[适合新手练习算法]五子棋 v2.5b3 简单算法分析
五子棋 v2.5b3 简单算法分析BY:李逍遥今天女儿要玩五子棋,从网上随便找了个,也不知道是哪年的了(后来看了下是1999年的,晕),挺老。以为是免费的,结果女儿玩了两局跳出提示框,呵呵,太不给我面子。网上搜索,却没发现注册码。很久不碰软件了,今天看来只有自己动手了。
软件简介:
五子棋2.5版,这是华东计算机研究所蒋祥刚先生的作品,支持人机对战、双人对战及网络对战等多种模式,网络对战中还可以三个人同时玩“三足鼎立”,当然它的棋力也甚为可观,介面自不必说了,它甚至还有多语种支撑功能,最大限度地满足了各个层面用户的需求。
注册名:LeExOyO
注册码:72:1:2
试验码:654321
主文件Five.exe,无壳,delphi编程。用DeDe很快找到断点:
0045EC0C /. 55 push ebp //下断
0045EC0D |. 8BEC mov ebp, esp
0045EC0F |. 6A 00 push 0
0045EC11 |. 53 push ebx
0045EC12 |. 33C0 xor eax, eax
。。。。。。。。。。。。。。。
0045EC76 |. E8 31FDFFFF call 0045E9AC //关键call
0045EC7B |. 803D 60FA4600>cmp byte ptr , 0
0045EC82 |. 75 0C jnz short 0045EC90
0045EC84 |. B8 04ED4500 mov eax, 0045ED04
0045EC89 |. E8 82CAFEFF call 0044B710
0045EC8E |. EB 14 jmp short 0045ECA4
0045EC90 |> B8 30ED4500 mov eax, 0045ED30
0045EC95 |. E8 76CAFEFF call 0044B710
0045EC9A |. A1 5CFA4600 mov eax,
0045EC9F |. E8 804EFEFF call 00443B24
0045ECA4 |> 33C0 xor eax, eax
0045ECA6 |. 5A pop edx
0045ECA7 |. 59 pop ecx
************************进入后****************
0045E9AC /$ 55 push ebp
0045E9AD |. 8BEC mov ebp, esp
0045E9AF |. 81C4 CCFDFFFF add esp, -234
0045E9B5 |. 53 push ebx
0045E9B6 |. 56 push esi
0045E9B7 |. 57 push edi
。。。。。。。。。。。。。。。。
0045EA5C |. 80BD 36FFFFFF>cmp byte ptr , 6 //注册码为6位
0045EA63 |. 74 0C je short 0045EA71
0045EA65 |> \C605 60FA4600>mov byte ptr , 0
0045EA6C |. E9 99000000 jmp 0045EB0A
0045EA71 |> 8BF0 mov esi, eax
0045EA73 |. 81E6 FF000000 and esi, 0FF
0045EA79 |. 85F6 test esi, esi
0045EA7B |. 7C 22 jl short 0045EA9F
0045EA7D |. 46 inc esi
0045EA7E |. 8D4D 9B lea ecx, ; //="LeExOyO"
0045EA81 |. 8D9D D1FEFFFF lea ebx,
0045EA87 |> 33C0 /xor eax, eax
0045EA89 |. 8A01 |mov al, //依次取注册名各字符转成16进制送到al
0045EA8B |. BF 0A000000 |mov edi, 0A
0045EA90 |. 33D2 |xor edx, edx
0045EA92 |. F7F7 |div edi //除以0xA取余
0045EA94 |. 80C2 30 |add dl, 30
0045EA97 |. 42 |inc edx //加1
0045EA98 |. 8813 |mov , dl
0045EA9A |. 43 |inc ebx
0045EA9B |. 41 |inc ecx
0045EA9C |. 4E |dec esi
0045EA9D |.^ 75 E8 \jnz short 0045EA87 ; //循环算出注册码,并依次放入内
0045EA9F |> 8A45 9B mov al,
0045EAA2 |. 3C 06 cmp al, 6
0045EAA4 |. 73 31 jnb short 0045EAD7
0045EAA6 |. 33C9 xor ecx, ecx
0045EAA8 |. 8AC8 mov cl, al
0045EAAA |. 41 inc ecx
0045EAAB |. 83F9 06 cmp ecx, 6
0045EAAE |. 7F 27 jg short 0045EAD7
0045EAB0 |. 8D9C0D D0FEFF>lea ebx,
0045EAB7 |> 33C0 /xor eax, eax
0045EAB9 |. 8A03 |mov al,
0045EABB |. 83C0 02 |add eax, 2
0045EABE |. 83E8 30 |sub eax, 30
0045EAC1 |. BE 0A000000 |mov esi, 0A
0045EAC6 |. 33D2 |xor edx, edx
0045EAC8 |. F7F6 |div esi
0045EACA |. 80C2 30 |add dl, 30
0045EACD |. 8853 01 |mov , dl
0045EAD0 |. 41 |inc ecx
0045EAD1 |. 43 |inc ebx
0045EAD2 |. 83F9 07 |cmp ecx, 7
0045EAD5 |.^ 75 E0 \jnz short 0045EAB7
0045EAD7 |> C685 D8FEFFFF>mov byte ptr , 0
0045EADE |. C605 60FA4600>mov byte ptr , 1
0045EAE5 |. B9 06000000 mov ecx, 6
0045EAEA |. 8D85 D2FEFFFF lea eax, ; //="72:1:2"
0045EAF0 |. 8D95 37FFFFFF lea edx, ; //=654321
0045EAF6 |> 8A18 /mov bl,
0045EAF8 |. 3A1A |cmp bl, ; //逐位比较
0045EAFA |. 74 09 |je short 0045EB05
0045EAFC |. C605 60FA4600>|mov byte ptr , 0
0045EB03 |. EB 05 |jmp short 0045EB0A
0045EB05 |> 42 |inc edx
0045EB06 |. 40 |inc eax
0045EB07 |. 49 |dec ecx
0045EB08 |.^ 75 EC \jnz short 0045EAF6
0045EB0A |> 33C0 xor eax, eax
0045EB0C |. 5A pop edx
0045EB0D |. 59 pop ecx
0045EB0E |. 59 pop ecx
0045EB0F |. 64:8910 mov fs:, edx
0045EB12 |. 68 2AEB4500 push 0045EB2A
0045EB17 |> 8D85 CCFDFFFF lea eax,
0045EB1D |. E8 B64DFAFF call 004038D8
0045EB22 \. C3 retn
算法比较简单:将注册名各字符的16进制除以0xA后的余数加上0x1,得到的值转为10进制取前面6位得到注册码。小于6位的注册名没有仔细看。
注册码明码保存在当前系统的windows目录下的Five99.ini中。
Name=LeExOyO
RegNo=72:1:2
李逍遥
2006.08.04 好久没玩五子棋了,下载来玩玩!/::P
[ 本帖最后由 绝恋风尘 于 2006-8-13 12:08 编辑 ] 原帖由 Nisy 于 2006-8-12 22:04 发表
五子棋 v2.5b3 简单算法分析BY:李逍遥
今天女儿要玩五子棋,从网上随便找了个,也不知道是哪年的了(后来看了下是1999年的,晕),挺老。以为是免费的,结果女儿玩了两局跳出提示框,呵呵,太不给我面子。网 ...
明码比较,前天咱都在分析这个软件的算法~呵呵~还没分析得出来。
但思路好像不是那样的,作者应该有预设字符。
先保持怀疑态度。咱预感作者在用户名不到6位的过程中,肯定用了预设符。
如02468...
0045E99F .55 PUSH EBP
0045E9A0 .0006 ADD BYTE PTR DS:,AL
0045E9A2 .72 65 JB SHORT FIVE.0045EA09
0045E9A4 .67:6973 74 00>IMUL ESI,DWORD PTR SS:,C08B0000
0045E9AC/$55 PUSH EBP
0045E9AD|.8BEC MOV EBP,ESP
0045E9AF|.81C4 CCFDFFFF ADD ESP,-234
0045E9B5|.53 PUSH EBX
0045E9B6|.56 PUSH ESI
0045E9B7|.57 PUSH EDI
0045E9B8|.33C0 XOR EAX,EAX ;EAX清零
0045E9BA|.8985 CCFDFFFF MOV DWORD PTR SS:,EAX
0045E9C0|.33C0 XOR EAX,EAX
0045E9C2|.55 PUSH EBP
0045E9C3|.68 23EB4500 PUSH FIVE.0045EB23
0045E9C8|.64:FF30 PUSH DWORD PTR FS:
0045E9CB|.64:8920 MOV DWORD PTR FS:,ESP
0045E9CE|.6A 00 PUSH 0
0045E9D0|.8D85 CCFDFFFF LEA EAX,DWORD PTR SS:
0045E9D6|.50 PUSH EAX
0045E9D7|.B9 3CEB4500 MOV ECX,FIVE.0045EB3C ;name
0045E9DC|.BA 4CEB4500 MOV EDX,FIVE.0045EB4C ;register
0045E9E1|.A1 64FA4600 MOV EAX,DWORD PTR DS:
0045E9E6|.8B18 MOV EBX,DWORD PTR DS:
0045E9E8|.FF13 CALL DWORD PTR DS:
0045E9EA|.8B95 CCFDFFFF MOV EDX,DWORD PTR SS: ;用户名
0045E9F0|.8D85 D0FDFFFF LEA EAX,DWORD PTR SS:
0045E9F6|.B9 FF000000 MOV ECX,0FF
0045E9FB|.E8 3051FAFF CALL FIVE.00403B30
0045EA00|.8D95 D0FDFFFF LEA EDX,DWORD PTR SS: ;用户名
0045EA06|.8D45 9B LEA EAX,DWORD PTR SS:
0045EA09|>B1 64 MOV CL,64
0045EA0B|.E8 883EFAFF CALL FIVE.00402898
0045EA10|.6A 00 PUSH 0
0045EA12|.8D85 CCFDFFFF LEA EAX,DWORD PTR SS:
0045EA18|.50 PUSH EAX
0045EA19|.B9 60EB4500 MOV ECX,FIVE.0045EB60 ;regno
0045EA1E|.BA 4CEB4500 MOV EDX,FIVE.0045EB4C ;register
0045EA23|.A1 64FA4600 MOV EAX,DWORD PTR DS:
0045EA28|.8B18 MOV EBX,DWORD PTR DS:
0045EA2A|.FF13 CALL DWORD PTR DS:
0045EA2C|.8B95 CCFDFFFF MOV EDX,DWORD PTR SS: ;试练码
0045EA32|.8D85 D0FDFFFF LEA EAX,DWORD PTR SS:
0045EA38|.B9 FF000000 MOV ECX,0FF
0045EA3D|.E8 EE50FAFF CALL FIVE.00403B30
0045EA42|.8D95 D0FDFFFF LEA EDX,DWORD PTR SS: ;试练码
0045EA48|.8D85 36FFFFFF LEA EAX,DWORD PTR SS:
0045EA4E|.B1 64 MOV CL,64
0045EA50|.E8 433EFAFF CALL FIVE.00402898
0045EA55|.8A45 9B MOV AL,BYTE PTR SS:
0045EA58|.84C0 TEST AL,AL ;用户名有没有填
0045EA5A|.74 09 JE SHORT FIVE.0045EA65 ;没填就跳出错。
0045EA5C|.80BD 36FFFFFF>CMP BYTE PTR SS:,6 ;试练码是否为6位
0045EA63|.74 0C JE SHORT FIVE.0045EA71 ;为6位才有希望
0045EA65|>C605 60FA4600>MOV BYTE PTR DS:,0 ;否则=0,标志位
0045EA6C|.E9 99000000 JMP FIVE.0045EB0A
0045EA71|>8BF0 MOV ESI,EAX ;试练码为6位跳来这,用户名位数送ESI
0045EA73|.81E6 FF000000 AND ESI,0FF
0045EA79|.85F6 TEST ESI,ESI ;对用户名进行检测
0045EA7B|.7C 22 JL SHORT FIVE.0045EA9F
0045EA7D|.46 INC ESI ;ESI+1
0045EA7E|.8D4D 9B LEA ECX,DWORD PTR SS: ;用户名,取位数,下面循环用。
0045EA81|.8D9D D1FEFFFF LEA EBX,DWORD PTR SS:
0045EA87|>33C0 /XOR EAX,EAX ;EAX清零,循环开始
0045EA89|.8A01 |MOV AL,BYTE PTR DS: ;第一次位数放AL,而后对逐位取用户名
0045EA8B|.BF 0A000000 |MOV EDI,0A ;EDI=0x0A
0045EA90|.33D2 |XOR EDX,EDX ;EDX清零
0045EA92|.F7F7 |DIV EDI ;EDX除以EDI
0045EA94|.80C2 30 |ADD DL,30 ;余数加0x30
0045EA97|.42 |INC EDX ;EDX再加1
0045EA98|.8813 |MOV BYTE PTR DS:,DL ;结果转成字符并排在
0045EA9A|.43 |INC EBX ;EBX+1
0045EA9B|.41 |INC ECX ;ECX+1
0045EA9C|.4E |DEC ESI ;ESI-1
0045EA9D|.^ 75 E8 \JNZ SHORT FIVE.0045EA87 ;向上循环,直到取完用户名
0045EA9F|>8A45 9B MOV AL,BYTE PTR SS: ;循环之后出来,用户名位数送AL
0045EAA2|.3C 06 CMP AL,6 ;比较用户名位数是否为6位
0045EAA4|.73 31 JNB SHORT FIVE.0045EAD7 ;高于/不低于6跳过下面的一个循环
0045EAA6|.33C9 XOR ECX,ECX ;否则接着来下面的一个循环,ECX清零
0045EAA8|.8AC8 MOV CL,AL ;CL=AL
0045EAAA|.41 INC ECX ;ECX+1
0045EAAB|.83F9 06 CMP ECX,6 ;ECX与6比较
0045EAAE|.7F 27 JG SHORT FIVE.0045EAD7 ;大于跳
0045EAB0|.8D9C0D D0FEFF>LEA EBX,DWORD PTR SS: ;预设置放EBX
0045EAB7|>33C0 /XOR EAX,EAX ;EAX清零
0045EAB9|.8A03 |MOV AL,BYTE PTR DS: ;上面的一循环取得的值,逐位放AL
0045EABB|.83C0 02 |ADD EAX,2 ;EAX+2
0045EABE|.83E8 30 |SUB EAX,30 ;EAX-30
0045EAC1|.BE 0A000000 |MOV ESI,0A ;ESI=0x0A
0045EAC6|.33D2 |XOR EDX,EDX ;EDX清零
0045EAC8|.F7F6 |DIV ESI ;EAX除以ESI,和上面的一个循环差不多。
0045EACA|.80C2 30 |ADD DL,30 ;余数加30
0045EACD|.8853 01 |MOV BYTE PTR DS:,DL ;结果并排在的位置
0045EAD0|.41 |INC ECX
0045EAD1|.43 |INC EBX
0045EAD2|.83F9 07 |CMP ECX,7 ;ECX位数与7比较
0045EAD5|.^ 75 E0 \JNZ SHORT FIVE.0045EAB7 ;不等的话往上循环
0045EAD7|>C685 D8FEFFFF>MOV BYTE PTR SS:,0
0045EADE|.C605 60FA4600>MOV BYTE PTR DS:,1 ;=1,标志位符
0045EAE5|.B9 06000000 MOV ECX,6 ;ECX=6
0045EAEA|.8D85 D2FEFFFF LEA EAX,DWORD PTR SS: ;真码进EAX
0045EAF0|.8D95 37FFFFFF LEA EDX,DWORD PTR SS: ;试练码
0045EAF6|>8A18 /MOV BL,BYTE PTR DS: ;进行循环逐位比较
0045EAF8|.3A1A |CMP BL,BYTE PTR DS: ;比较咯。。。
0045EAFA|.74 09 |JE SHORT FIVE.0045EB05 ;相等才跳
0045EAFC|.C605 60FA4600>|MOV BYTE PTR DS:,0 ;否则=0,这是标志位
0045EB03|.EB 05 |JMP SHORT FIVE.0045EB0A ;然后跳转循环
0045EB05|>42 |INC EDX
0045EB06|.40 |INC EAX
0045EB07|.49 |DEC ECX
0045EB08|.^ 75 EC \JNZ SHORT FIVE.0045EAF6
0045EB0A|>33C0 XOR EAX,EAX ;循环跳出来这
0045EB0C|.5A POP EDX
0045EB0D|.59 POP ECX
0045EB0E|.59 POP ECX
0045EB0F|.64:8910 MOV DWORD PTR FS:,EDX
0045EB12|.68 2AEB4500 PUSH FIVE.0045EB2A
0045EB17|>8D85 CCFDFFFF LEA EAX,DWORD PTR SS:
0045EB1D|.E8 B64DFAFF CALL FIVE.004038D8
0045EB22\.C3 RETN
0045EB23 .^ E9 EC47FAFF JMP FIVE.00403314
0045EB28 .^ EB ED JMP SHORT FIVE.0045EB17
0045EB2A .5F POP EDI
0045EB2B .5E POP ESI
0045EB2C .5B POP EBX
0045EB2D .8BE5 MOV ESP,EBP
0045EB2F .5D POP EBP
0045EB30 .C3 RETN ;返回。。。
[ 本帖最后由 野猫III 于 2006-8-12 23:11 编辑 ]
页:
[1]