翻转黑白2.0
一个黑白棋的游戏,反正作者要10块注册费,不注册也能玩,但好象有限制。
工具:手术刀(DEDE)+镊子(OllyDBG)
1、先用DEDE开刀,在Form3的Button1Click里发现一个好玩的东西:
0045F7A8 E88BFDFFFF call 0045F538
0045F7AD 84C0 test al, al
0045F7AF 746F jz 0045F820
0045F7B1 6A00 push $00
0045F7B3 668B0D84F84500 mov cx, word ptr [$0045F884]
0045F7BA B202 mov dl, $02
* Possible String Reference to: '注册成功!谢谢您的支持!'
0045F7A8的call就是计算注册码。
2、用“草原猎豹”做用户名,"DebugYou"做试练码,用OllyDbg在0045F7A8下断,跟进,如下:
0045F538 /$ 55 PUSH EBP
0045F539 |. 8BEC MOV EBP,ESP
0045F53B |. 83C4 E0 ADD ESP,-20
0045F53E |. 53 PUSH EBX
0045F53F |. 56 PUSH ESI
0045F540 |. 57 PUSH EDI
0045F541 |. 33C9 XOR ECX,ECX
0045F543 |. 894D E4 MOV DWORD PTR SS:[EBP-1C],ECX
0045F546 |. 894D E0 MOV DWORD PTR SS:[EBP-20],ECX
0045F549 |. 8955 F8 MOV DWORD PTR SS:[EBP-8],EDX
0045F54C |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
0045F54F |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名
0045F552 |. E8 D146FAFF CALL Othello2.00403C28
0045F557 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; 试练码
0045F55A |. E8 C946FAFF CALL Othello2.00403C28
0045F55F |. 33C0 XOR EAX,EAX
0045F561 |. 55 PUSH EBP
0045F562 |. 68 D9F64500 PUSH Othello2.0045F6D9
0045F567 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
0045F56A |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
0045F56D |. 33DB XOR EBX,EBX
0045F56F |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名
0045F572 |. E8 FD44FAFF CALL Othello2.00403A74 ; 取用户名长度
0045F577 |. 8BF0 MOV ESI,EAX
0045F579 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] ; 试练码
0045F57C |. E8 F344FAFF CALL Othello2.00403A74 ; 取试练码长度
0045F581 |. 0FAFF0 IMUL ESI,EAX ; 试练码长度*用户名长度
0045F584 |. 85F6 TEST ESI,ESI ;结果是0就跳去死
0045F586 |. 0F84 25010000 JE Othello2.0045F6B1
0045F58C |. C745 F0 00000>MOV DWORD PTR SS:[EBP-10],0
0045F593 |. C745 F4 00000>MOV DWORD PTR SS:[EBP-C],0
0045F59A |. C745 E8 00000>MOV DWORD PTR SS:[EBP-18],0
0045F5A1 |. C745 EC 00000>MOV DWORD PTR SS:[EBP-14],0
0045F5A8 |. 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C]
0045F5AB |. BA F4F64500 MOV EDX,Othello2.0045F6F4 ; ASCII "HelloCracker"
0045F5B0 |. E8 DB42FAFF CALL Othello2.00403890
0045F5B5 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; 用户名
0045F5B8 |. E8 B744FAFF CALL Othello2.00403A74 ; 取用户名长度
0045F5BD |. 8BF0 MOV ESI,EAX
0045F5BF |. 85F6 TEST ESI,ESI
0045F5C1 |. 7E 23 JLE SHORT Othello2.0045F5E6 ;结果是0就跳去死
0045F5C3 |. BF 01000000 MOV EDI,1
0045F5C8 |> 8B45 FC /MOV EAX,DWORD PTR SS:[EBP-4] ; eax->用户名
0045F5CB |. 8A4438 FF |MOV AL,BYTE PTR DS:[EAX+EDI-1] ; 该循环取得用户名所有字符的ASCII码的和
0045F5CF |. 25 FF000000 |AND EAX,0FF
0045F5D4 |. 33D2 |XOR EDX,EDX
0045F5D6 |. 0345 F0 |ADD EAX,DWORD PTR SS:[EBP-10] ;
0045F5D9 |. 1355 F4 |ADC EDX,DWORD PTR SS:[EBP-C]
0045F5DC |. 8945 F0 |MOV DWORD PTR SS:[EBP-10],EAX ; ebp-10 -》用户名所有字符的ASCII码的和
0045F5DF |. 8955 F4 |MOV DWORD PTR SS:[EBP-C],EDX
0045F5E2 |. 47 |INC EDI
0045F5E3 |. 4E |DEC ESI
0045F5E4 |.^ 75 E2 \JNZ SHORT Othello2.0045F5C8
0045F5E6 |> 6A 00 PUSH 0
0045F5E8 |. 68 D3070300 PUSH 307D3
0045F5ED |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] ; 用户名所有字符的ASCII码的和
0045F5F0 |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
0045F5F3 |. E8 FC60FAFF CALL Othello2.004056F4 ; 用户名所有字符的ASCII码的和 * 198611
0045F5F8 |. 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
0045F5FB |. 8955 F4 MOV DWORD PTR SS:[EBP-C],EDX
0045F5FE |. 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C]
0045F601 |. E8 6E44FAFF CALL Othello2.00403A74 ; 取字串'HelloCracker'的长度
0045F606 |. 8BF0 MOV ESI,EAX
0045F608 |. 85F6 TEST ESI,ESI ;结果是0就跳去死,神经过敏
0045F60A |. 7E 23 JLE SHORT Othello2.0045F62F
0045F60C |. BF 01000000 MOV EDI,1
0045F611 |> 8B45 E4 /MOV EAX,DWORD PTR SS:[EBP-1C]
0045F614 |. 8A4438 FF |MOV AL,BYTE PTR DS:[EAX+EDI-1]
0045F618 |. 25 FF000000 |AND EAX,0FF
0045F61D |. 33D2 |XOR EDX,EDX
0045F61F |. 0345 E8 |ADD EAX,DWORD PTR SS:[EBP-18]
0045F622 |. 1355 EC |ADC EDX,DWORD PTR SS:[EBP-14]
0045F625 |. 8945 E8 |MOV DWORD PTR SS:[EBP-18],EAX
0045F628 |. 8955 EC |MOV DWORD PTR SS:[EBP-14],EDX
0045F62B |. 47 |INC EDI
0045F62C |. 4E |DEC ESI
0045F62D |.^ 75 E2 \JNZ SHORT Othello2.0045F611 ; 该循环取得字串'HelloCracker'所有字符的ASCII码的和
0045F62F |> 6A 00 PUSH 0
0045F631 |. 68 C6230D00 PUSH 0D23C6
0045F636 |. 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18]
0045F639 |. 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14]
0045F63C |. E8 B360FAFF CALL Othello2.004056F4 ; 'HelloCracker'所有字符的ASCII码的和 * 861126
0045F641 |. 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
0045F644 |. 8955 EC MOV DWORD PTR SS:[EBP-14],EDX
0045F647 |. 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10]
0045F64A |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C]
0045F64D |. 3345 E8 XOR EAX,DWORD PTR SS:[EBP-18] ; ('HelloCracker'所有字符的ASCII码的和 * 861126)xor (用户名所有字符的ASCII码的和 * 198611)
0045F650 |. 3355 EC XOR EDX,DWORD PTR SS:[EBP-14]
0045F653 |. 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
0045F656 |. 8955 F4 MOV DWORD PTR SS:[EBP-C],EDX
0045F659 |. FF75 F4 PUSH DWORD PTR SS:[EBP-C] ; /Arg2
0045F65C |. FF75 F0 PUSH DWORD PTR SS:[EBP-10] ; |Arg1
0045F65F |. 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20] ; |
0045F662 |. E8 6181FAFF CALL Othello2.004077C8 ; \根据判断和猜测,应该是inttostr函数,把上面运算结果转换成字符串
0045F667 |. 8B45 E0 MOV EAX,DWORD PTR SS:[EBP-20]
0045F66A |. E8 0544FAFF CALL Othello2.00403A74 ; 得到该字符串长度
0045F66F |. 8BF0 MOV ESI,EAX
0045F671 |. 85F6 TEST ESI,ESI ;结果是0就跳去死
0045F673 |. 7E 3A JLE SHORT Othello2.0045F6AF
0045F675 |. BF 01000000 MOV EDI,1
0045F67A |> 8D45 E0 /LEA EAX,DWORD PTR SS:[EBP-20]
0045F67D |. E8 C245FAFF |CALL Othello2.00403C44
0045F682 |. 8B55 E0 |MOV EDX,DWORD PTR SS:[EBP-20]
0045F685 |. 0FB6543A FF |MOVZX EDX,BYTE PTR DS:[EDX+EDI-1] ; 取上面xor计算出来的字符串的每个字符
0045F68A |. 8B4D E4 |MOV ECX,DWORD PTR SS:[EBP-1C]
0045F68D |. 0FB64C39 FF |MOVZX ECX,BYTE PTR DS:[ECX+EDI-1] ; 取'HelloCracker'的字符
0045F692 |. 03D1 |ADD EDX,ECX
0045F694 |. 83EA 30 |SUB EDX,30
0045F697 |. 885438 FF |MOV BYTE PTR DS:[EAX+EDI-1],DL
0045F69B |. 8B45 E0 |MOV EAX,DWORD PTR SS:[EBP-20]
0045F69E |. 8A4438 FF |MOV AL,BYTE PTR DS:[EAX+EDI-1]
0045F6A2 |. 8B55 F8 |MOV EDX,DWORD PTR SS:[EBP-8]
0045F6A5 |. 3A443A FF |CMP AL,BYTE PTR DS:[EDX+EDI-1] ;试练码每个字符和真注册码每个字符比较
0045F6A9 |. 75 06 |JNZ SHORT Othello2.0045F6B1 ;有哪个字符不等就跳去死
0045F6AB |. 47 |INC EDI
0045F6AC |. 4E |DEC ESI
0045F6AD |.^ 75 CB \JNZ SHORT Othello2.0045F67A ;该循环把上面xor计算出来的字符串的每个字符和'HelloCracker'的每个字符依次相加
0045F6AF |> B3 01 MOV BL,1 ;再减去30H,组成注册码的字符串
0045F6B1 |> 33C0 XOR EAX,EAX
0045F6B3 |. 5A POP EDX
0045F6B4 |. 59 POP ECX
0045F6B5 |. 59 POP ECX
0045F6B6 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
0045F6B9 |. 68 E0F64500 PUSH Othello2.0045F6E0
0045F6BE |> 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]
0045F6C1 |. BA 02000000 MOV EDX,2
0045F6C6 |. E8 5141FAFF CALL Othello2.0040381C
0045F6CB |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
0045F6CE |. BA 02000000 MOV EDX,2
0045F6D3 |. E8 4441FAFF CALL Othello2.0040381C
0045F6D8 \. C3 RETN
算法如下:
1、把用户名每个字符Ascii码相加,得到sum_username
2、把'HelloCracker'的每个字符Ascii码相加,得到sum_hellocracker
3、计算 IntToStr( (sum_username * 198611) xor (sum_hellocracker * 861126) ),得到字符串strTemp
4、依次从strTemp中和'HelloCracker'中取出字符,其Ascii码相加,再减去30H,组成注册码,strTemp取完为止。
5、注册机已写成,把界面修理的Cool一点的时候即可发布。
注册码是:OnuooLvae
这里面有不少参数和算法好象在绕圈,但好象实际上没有参加注册码的运算?
call 004056F4里的代码,push来push去,mul来mul去的,却只是一个简单的两数相乘的运算?
ps:作者的生日好象是1986年11月26日 ;-)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)