Nisy 发表于 2006-8-12 22:04:08

[适合新手练习算法]五子棋 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

绝恋风尘 发表于 2006-8-12 22:08:41

好久没玩五子棋了,下载来玩玩!/::P

[ 本帖最后由 绝恋风尘 于 2006-8-13 12:08 编辑 ]

野猫III 发表于 2006-8-12 22:56:18

原帖由 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 编辑 ]

wxh9833 发表于 2006-8-13 10:22:40

wxh9833 发表于 2006-8-13 12:46:46

页: [1]
查看完整版本: [适合新手练习算法]五子棋 v2.5b3 简单算法分析