对happytown的“一个适合初学者的crackme ”的简单分析
【文章标题】: 对happytown的“一个适合初学者的crackme ”的简单分析【文章作者】: 水中花
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
可以用字符串下断,断在此处
0040112C .50 push eax
0040112D .53 push ebx
0040112E .55 push ebp
0040112F .68 00020000 push 200 ; /Count = 200 (512.)
00401134 .68 49634000 push crackme.00406349 ; |Buffer = crackme.00406349
00401139 .68 EA030000 push 3EA ; |ControlID = 3EA (1002.)
0040113E .FF75 08 push dword ptr ; |hWnd
00401141 .E8 4A020000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA 获取用户名的长度
00401146 .83F8 03 cmp eax, 3 必须大于3位
00401149 .77 18 ja short crackme.00401163
0040114B .6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040114D .68 06634000 push crackme.00406306 ; |bad boy...
00401152 .68 0A624000 push crackme.0040620A ; |Text = "Username must have at least 4 chars..."
00401157 .FF75 08 push dword ptr ; |hOwner
0040115A .E8 3D020000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
0040115F .C9 leave
00401160 .C2 1000 retn 10
00401163 >8D15 49634000 lea edx, dword ptr
00401169 .52 push edx ; /String => "j与zi>"
0040116A .E8 8D020000 call <jmp.&kernel32.lstrlenA> ; \lstrlenA 去除用户名的第一位字符,该串设了A
0040116F .8BE8 mov ebp, eax
00401171 .B9 05000000 mov ecx, 5 ;循环计数器
00401176 .33F6 xor esi, esi
00401178 .33C0 xor eax, eax
0040117A >8A0C16 mov cl, byte ptr ; 以下是将A的各个字符按顺序与AA,89,C4,FE,46(超过5位的,分别A串的前面字符)相异或,所得串设为B
0040117D .8AD9 mov bl, cl
0040117F .3298 28634000 xor bl, byte ptr 相异或
00401185 .40 inc eax
00401186 .83F8 05 cmp eax, 5
00401189 .881C32 mov byte ptr , bl 存入中
0040118C .8888 27634000 mov byte ptr , cl
00401192 .75 02 jnz short crackme.00401196
00401194 .33C0 xor eax, eax
00401196 >46 inc esi
00401197 .3BF5 cmp esi, ebp
00401199 .^ 72 DF jb short crackme.0040117A
0040119B .33FF xor edi, edi
0040119D .33C9 xor ecx, ecx
0040119F .85ED test ebp, ebp
004011A1 .76 26 jbe short crackme.004011C9
004011A3 >8A9F 2D634000 mov bl, byte ptr ;以下是将B串反取按顺序与78 F0 D0 03 E7(超过5位的与B串的反取字符)相异或,所得串设以C
004011A9 .8BF5 mov esi, ebp
004011AB .2BF1 sub esi, ecx
004011AD .4E dec esi
004011AE .8A0432 mov al, byte ptr
004011B1 .32D8 xor bl, al 异或
004011B3 .47 inc edi
004011B4 .881C32 mov byte ptr , bl
004011B7 .8887 2C634000 mov byte ptr , al
004011BD .83FF 05 cmp edi, 5
004011C0 .75 02 jnz short crackme.004011C4
004011C2 .33FF xor edi, edi
004011C4 >41 inc ecx
004011C5 .3BCD cmp ecx, ebp
004011C7 .^ 72 DA jb short crackme.004011A3
004011C9 >33F6 xor esi, esi
004011CB .33FF xor edi, edi
004011CD .85ED test ebp, ebp
004011CF .76 21 jbe short crackme.004011F2
004011D1 >8A043A mov al, byte ptr 以下是将C串反取按顺序与F7 FD F4 E7 B9(超过5位的与C串的反取字符)相异或,所得串设以D
004011D4 .8A8E 32634000 mov cl, byte ptr
004011DA .32C8 xor cl, al 异或
004011DC .46 inc esi
004011DD .880C3A mov byte ptr , cl
004011E0 .8886 31634000 mov byte ptr , al
004011E6 .83FE 05 cmp esi, 5
004011E9 .75 02 jnz short crackme.004011ED
004011EB .33F6 xor esi, esi
004011ED >47 inc edi
004011EE .3BFD cmp edi, ebp
004011F0 .^ 72 DF jb short crackme.004011D1
004011F2 >33FF xor edi, edi
004011F4 .33C9 xor ecx, ecx
004011F6 .85ED test ebp, ebp
004011F8 .76 26 jbe short crackme.00401220
004011FA >8A9F 37634000 mov bl, byte ptr 以下是将D串反取按顺序与B5 1B C9 50 73(超过5位的与D串的反取字符)相异或,所得串设为E
00401200 .8BF5 mov esi, ebp
00401202 .2BF1 sub esi, ecx
00401204 .4E dec esi
00401205 .8A0432 mov al, byte ptr
00401208 .32D8 xor bl, al 异或
0040120A .47 inc edi
0040120B .881C32 mov byte ptr , bl
0040120E .8887 36634000 mov byte ptr , al
00401214 .83FF 05 cmp edi, 5
00401217 .75 02 jnz short crackme.0040121B
00401219 .33FF xor edi, edi
0040121B >41 inc ecx
0040121C .3BCD cmp ecx, ebp
0040121E .^ 72 DA jb short crackme.004011FA
00401220 >8D3D 45634000 lea edi, dword ptr
00401226 .33C0 xor eax, eax
00401228 .85ED test ebp, ebp
0040122A .C705 45634000>mov dword ptr , 0
00401234 .76 17 jbe short crackme.0040124D
00401236 >8BC8 mov ecx, eax 以下是将E串反取按顺序与00,00,00,00,(超过5位的与E串的反取字符)相add,超过4位有E串的反取相add
00401238 .83E1 03 and ecx, 3
0040123B .8A1C0F mov bl, byte ptr
0040123E .8D340F lea esi, dword ptr
00401241 .8A0C02 mov cl, byte ptr
00401244 .02D9 add bl, cl 相add
00401246 .40 inc eax
00401247 .3BC5 cmp eax, ebp
00401249 .881E mov byte ptr , bl 存入中
0040124B .^ 72 E9 jb short crackme.00401236
0040124D >5D pop ebp
0040124E .B9 0A000000 mov ecx, 0A ecx赋值为A,十进制10
00401253 .A1 45634000 mov eax, dword ptr 将(为)中的内容取出
00401258 .33DB xor ebx, ebx
0040125A >33D2 xor edx, edx
0040125C .F7F1 div ecx 除A
0040125E .80C2 30 add dl, 30 低位与30相add
00401261 .8893 49654000 mov byte ptr , dl 存入中
00401267 .43 inc ebx
00401268 .85C0 test eax, eax
0040126A .^ 75 EE jnz short crackme.0040125A
0040126C .68 49654000 push crackme.00406549 ; /String = "" 此为上面计算所得的值,设为F
00401271 .E8 86010000 call <jmp.&kernel32.lstrlenA> ; \lstrlenA
00401276 .33DB xor ebx, ebx
00401278 >8A88 48654000 mov cl, byte ptr 将F串反取,即为注册码
0040127E .888B 49674000 mov byte ptr , cl
00401284 .43 inc ebx
00401285 .48 dec eax
00401286 .^ 75 F0 jnz short crackme.00401278
00401288 .68 49674000 push crackme.00406749 ; /String2 = "" 此处出现真码
0040128D .68 49654000 push crackme.00406549 ; |String1 = crackme.00406549
00401292 .E8 5F010000 call <jmp.&kernel32.lstrcpyA> ; \lstrcpyA
00401297 .68 00020000 push 200 ; /Count = 200 (512.)
0040129C .68 49694000 push crackme.00406949 ; |Buffer = crackme.00406949
004012A1 .6A 64 push 64 ; |ControlID = 64 (100.)
004012A3 .FF75 08 push dword ptr ; |hWnd
004012A6 .E8 E5000000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004012AB .68 49654000 push crackme.00406549 ; /String2 = ""
004012B0 .68 49694000 push crackme.00406949 ; |String1 = "123456"
004012B5 .E8 36010000 call <jmp.&kernel32.lstrcmpA> ; \lstrcmpA 真假码比较
004012BA .0BC0 or eax, eax
004012BC .75 16 jnz short crackme.004012D4 跳向出错处
004012BE .6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004012C0 .68 DB624000 push crackme.004062DB ; |good boy...nope, thats not it!\n\ntry againbad boy...
004012C5 .68 AC624000 push crackme.004062AC ; |yep, thats the right code!\n\ngo write a keygen!good boy...nope, thats not it!\n\ntry againbad boy...
004012CA .FF75 08 push dword ptr ; |hOwner
004012CD .E8 CA000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
004012D2 .EB 14 jmp short crackme.004012E8
004012D4 >6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
004012D6 .68 06634000 push crackme.00406306 ; |bad boy...
004012DB .68 E7624000 push crackme.004062E7 ; |nope, thats not it!\n\ntry againbad boy...
004012E0 .FF75 08 push dword ptr ; |hOwner
004012E3 .E8 B4000000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
004012E8 >68 00020000 push 200 ; /Length = 200 (512.)
004012ED .68 49654000 push crackme.00406549 ; |Destination = crackme.00406549
004012F2 .E8 ED000000 call <jmp.&kernel32.RtlZeroMemory> ; \RtlZeroMemory
004012F7 .68 00020000 push 200 ; /Length = 200 (512.)
004012FC .68 49634000 push crackme.00406349 ; |Destination = crackme.00406349
00401301 .E8 DE000000 call <jmp.&kernel32.RtlZeroMemory> ; \RtlZeroMemory
00401306 .68 00020000 push 200 ; /Length = 200 (512.)
0040130B .68 49674000 push crackme.00406749 ; |Destination = crackme.00406749
00401310 .E8 CF000000 call <jmp.&kernel32.RtlZeroMemory> ; \RtlZeroMemory
00401315 .B9 16000000 mov ecx, 16
--------------------------------------------------------------------------------
【经验总结】
我是初手,也是第一次写这种破文,不好和不对之处,请大家多多指教!
算法总结:
1、去除用户名的第一位字符,设为A,将A按顺序分别与AA 89 C4FE 46(超过5位的,分别取A串的前面字符)相异或,设
所得结果为B
2、将B串反取按顺序与78 F0 D0 03 E7(超过5位的与B串的反取字符)相异或,所得串设以C
3、将C串反取按顺序与F7 FD F4 E7 B9(超过5位的与C串的反取字符)相异或,所得串设以D
4、将D串反取按顺序与B5 1B C9 50 73(超过5位的与D串的反取字符)相异或,所得串设为E
5、将E串反取按顺序与00,00,00,00,(超过5位的与E串的反取字符)相add,超过4位有E串的反取相add ,所得设为F
6、将F div A 余数+30,化为数字,所得值设为G
7、将G反取就为正确注册码
--------------------------------------------------------------------------------
2007年03月13日 22:12:48 这个是比较简单的 CM ,支持一下 /fad 我怎么没有看明白啊
凑个热闹
我也发一个成功截图,不过楼上的分析的挺详细 我也来耍耍 我的注册码就是1696244835我就是这点水平拉,哈哈!
页:
[1]