【破文标题】Prolixe-KeygenMe#1破解分析
【破文作者】逍遥风
【破解工具】OD
【破解平台】WINXP
【软件简介】Difficulty: 1 - Very easy, for newbies
Platform: Windows
Language: Borland Delphi
----------------------------------------------------------------------
练习任务:
1)去掉运行时出现的NAG窗口
2)分析算法
难度:新手级(简单)
带着这两个任务,来解决这个CRACKME.
专为新手练习,高手飞过.
----------------------------------------------------------------------
任务1:去掉NAG
用OD载入这个 CRACKME,程序停在如下代码处。这里介绍两种方法要去除NAG窗口。
1)修改跳转法去NAG:
0040820C > $ 55 push ebp ; 修改这里(改为JMP 40822F)
0040820D . 8BEC mov ebp, esp
0040820F . 83C4 F0 add esp, -10
00408212 . B8 C4814000 mov eax, 004081C4
00408217 . E8 F0C2FFFF call 0040450C
0040821C . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040821E . 68 4C824000 push 0040824C ; |Title = "Rules"
00408223 . 68 54824000 push 00408254 ; |Text = "KeygenMe and delete this window good luck !!!"
00408228 . 6A 00 push 0 ; |hOwner = NULL
0040822A . E8 41C4FFFF call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0040822F . 68 047F4000 push 00407F04 ; /Arg1 = 00407F04
修改后变成
0040820C > /EB 21 jmp short 0040822F
0040820E |90 nop
保存修改后,重新运行这个CRACKME。NAG窗口已经被去掉了。
2)NOP法去NAG
还是上面的代码,这次不修改跳转。
00408217 . E8 F0C2FFFF call 0040450C
0040821C . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040821E . 68 4C824000 push 0040824C ; |Title = "Rules"
00408223 . 68 54824000 push 00408254 ; |Text = "KeygenMe and delete this window good luck !!!"
00408228 . 6A 00 push 0 ; |hOwner = NULL
0040822A . E8 41C4FFFF call <jmp.&user32.MessageBoxA> ; \MessageBoxA(修改这里,改为NOP)
修改后变为
00408228 . 6A 00 push 0 ; |hOwner = NULL
0040822A 90 nop
保存修改后,重新运行这个CRACKME。NAG窗口已经被去掉。
两种方法形式上不一样,但本质上是一样的。
----------------------------------------------------------------------
任务2:分析算法
用OD载入去掉NAG后的CRACKME。根据注册提示很容易来到关键代码处。
00407FA5 |> \6A 1E push 1E ; /在这里下断点; Case 3EA of switch 00407F91
00407FA7 |. 8D85 FCFEFFFF lea eax, [ebp-104] ; |
00407FAD |. 50 push eax ; |Buffer
00407FAE |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00407FB3 |. 53 push ebx ; |hWnd
00407FB4 |. E8 97C6FFFF call <jmp.&user32.GetDlgIte>; \GetDlgItemTextA
00407FB9 |. 6A 1E push 1E ; /Count = 1E (30.)
00407FBB |. 8D85 FCFDFFFF lea eax, [ebp-204] ; |
00407FC1 |. 50 push eax ; |Buffer
00407FC2 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
00407FC7 |. 53 push ebx ; |hWnd
00407FC8 |. E8 83C6FFFF call <jmp.&user32.GetDlgIte>; \GetDlgItemTextA
00407FCD |. 80BD FCFDFFFF >cmp byte ptr [ebp-204], 0 ; 分别取注册名与注册码的位数
00407FD4 |. 75 17 jnz short 00407FED ; 没有输入注册码会跳出错误提示
00407FD6 |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00407FD8 |. 68 0C814000 push 0040810C ; |error
00407FDD |. 68 14814000 push 00408114 ; |enter a serial
00407FE2 |. 53 push ebx ; |hOwner
00407FE3 |. E8 88C6FFFF call <jmp.&user32.MessageBo>; \MessageBoxA
00407FE8 |. E9 B9000000 jmp 004080A6
00407FED |> 80BD FCFEFFFF >cmp byte ptr [ebp-104], 0
00407FF4 |. 75 17 jnz short 0040800D ; 没有输入注册名也会跳出错误提示
00407FF6 |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00407FF8 |. 68 0C814000 push 0040810C ; |error
00407FFD |. 68 24814000 push 00408124 ; |enter a name
00408002 |. 53 push ebx ; |hOwner
00408003 |. E8 68C6FFFF call <jmp.&user32.MessageBo>; \MessageBoxA
00408008 |. E9 99000000 jmp 004080A6
0040800D |> 8D85 F8FDFFFF lea eax, [ebp-208]
00408013 |. 8D95 FCFEFFFF lea edx, [ebp-104] ; 使EDX等于注册名
00408019 |. B9 00010000 mov ecx, 100 ; 使ECX等于0x100
0040801E |. E8 19B8FFFF call 0040383C
00408023 |. 8B85 F8FDFFFF mov eax, [ebp-208] ; 使EAX等于注册名
00408029 |. 8D55 FC lea edx, [ebp-4]
0040802C |. E8 E3FDFFFF call 00407E14 ; 算法CALL,跟进
00408031 |. 8D85 F4FDFFFF lea eax, [ebp-20C]
00408037 |. 8D95 FCFDFFFF lea edx, [ebp-204]
0040803D |. B9 00010000 mov ecx, 100
00408042 |. E8 F5B7FFFF call 0040383C
00408047 |. 8B95 F4FDFFFF mov edx, [ebp-20C] ; 使EDX等于假码
0040804D |. 8B45 FC mov eax, [ebp-4] ; 使EAX等于正确的注册码
00408050 |. E8 EBB8FFFF call 00403940 ; 比较CALL
00408055 |. 75 2F jnz short 00408086 ; 不相等就注册失败
00408057 |. 68 34814000 push 00408134 ; /registred version
0040805C |. 68 F1030000 push 3F1 ; |ControlID = 3F1 (1009.)
00408061 |. 53 push ebx ; |hWnd
00408062 |. E8 11C6FFFF call <jmp.&user32.SetDlgIte>; \SetDlgItemTextA
00408067 |. 68 48814000 push 00408148 ; /prolixe keygenme #1 by fabsys -registred-
0040806C |. 53 push ebx ; |hWnd
0040806D |. E8 1EC6FFFF call <jmp.&user32.SetWindow>; \SetWindowTextA
00408072 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00408074 |. 68 74814000 push 00408174 ; |winner
00408079 |. 68 7C814000 push 0040817C ; |good boy
0040807E |. 53 push ebx ; |hOwner
0040807F |. E8 ECC5FFFF call <jmp.&user32.MessageBo>; \MessageBoxA
00408084 |. EB 20 jmp short 004080A6
00408086 |> 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00408088 |. 68 88814000 push 00408188 ; |wrong way
0040808D |. 68 94814000 push 00408194 ; |bad boy
00408092 |. 53 push ebx ; |hOwner
00408093 |. E8 D8C5FFFF call <jmp.&user32.MessageBo>; \MessageBoxA
跟进算法CALL
00407E14 /$ 55 push ebp ; 来到这里
00407E15 |. 8BEC mov ebp, esp
00407E17 |. 33C9 xor ecx, ecx
省略一些代码。。。。。。
00407E45 |. 8B45 FC mov eax, [ebp-4]
00407E48 |. E8 1BBAFFFF call 00403868 ; 取注册名位数
00407E4D |. 8BF0 mov esi, eax ; 使ESI=EAX=注册名位数
00407E4F |. 85F6 test esi, esi
00407E51 |. 7E 30 jle short 00407E83
00407E53 |. BB 01000000 mov ebx, 1 ; 使EBX等于1
00407E58 |> 8D45 F0 /lea eax, [ebp-10]
00407E5B |. 8B55 FC |mov edx, [ebp-4]
00407E5E |. 0FB67C1A FF |movzx edi, byte ptr [edx+eb>; 取注册名每一位的ASCII码
00407E63 |. 8BD7 |mov edx, edi ; 使EDX等于注册名每一位的ASCII码
00407E65 |. 8D4B 05 |lea ecx, [ebx+5] ; 使ECX等于Mn
00407E68 |. 33D1 |xor edx, ecx ; XOR(注册名每一位的ASCII码,对应的Mn)。得到的结果设为An
00407E6A |. 03D7 |add edx, edi ; 注册名的ASCII码与对应的An相加结果设为Bn
00407E6C |. 83C2 0A |add edx, 0A ; Bn与定值0x0A相加,结果设为Cn
00407E6F |. E8 4CB9FFFF |call 004037C0
00407E74 |. 8B55 F0 |mov edx, [ebp-10]
00407E77 |. 8D45 F4 |lea eax, [ebp-C]
00407E7A |. E8 F1B9FFFF |call 00403870
00407E7F |. 43 |inc ebx ; 每计算一次EBX+1
00407E80 |. 4E |dec esi ; 每计算一次ESI-1
00407E81 |.^ 75 D5 \jnz short 00407E58
00407E83 |> 8D55 EC lea edx, [ebp-14]
00407E86 |. 8B45 F4 mov eax, [ebp-C] ; 使EAX等于计算结果
00407E89 |. E8 62D5FFFF call 004053F0 ; 将计算结果转换成大写形式
00407E8E |. 8B55 EC mov edx, [ebp-14]
00407E91 |. 8D45 F4 lea eax, [ebp-C]
00407E94 |. E8 F3B7FFFF call 0040368C
00407E99 |. 68 EC7E4000 push 00407EEC ; hzf-
00407E9E |. FF75 F4 push dword ptr [ebp-C] ; 取固定字符串HZF-
00407EA1 |. 68 FC7E4000 push 00407EFC ; -gfd
00407EA6 |. 8B45 F8 mov eax, [ebp-8] ; 取固定字符串-GDF
00407EA9 |. BA 03000000 mov edx, 3 ; 使EDX等于3
00407EAE |. E8 01BAFFFF call 004038B4 ; 连接计算结果与两个固定字符串
算法的过程是:
XOR(注册名每一位的ASCII码,Mn),结果设为An
注册名每一位的ASCII码与对应的An相加,结果设为Bn
Bn与定值0x0A相加,结果设为Cn。取Cn对应的字符,并转换成大写作为最后的结果。
连接HZF-Cn-GDF三个部分作为注册码。
注意Mn的变化。(n=计算次数)
M1=注册名位数
M2=注册名位数+1
M3=注册名位数+2
。。。
依次类推:
----------------------------------------------------------------------
例如
注册名:1234567
1--31,XOR(31,6)=37。37+31=68。68+A=72。
72--r
所以Cn的第一位就是r。。。依次类推
所以:
注册名:1234567
注册码:HZF-RQX{~}|-GFD
--------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性。
阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开
发者可享99元/年,续费同价!