【破文标题】crackme解分析
【破文作者】逍遥风
【破解工具】OD
【破解平台】WINXP
【保护方式】
【软件简介】Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows 2000/XP only
Language: Assembler
---------------------------------------------------------------------
在crackmes.de评分是,
Votes: 4
Crackme is quite nice.挺有意思,拿出来玩玩
第一步:
脱壳
OD载入这个CRACKME,没有加壳提示。
0040D4CA 5D pop ebp ; 停在这里
0040D4CB 81ED 60164000 sub ebp, 00401660
0040D4D1 FFB5 FC164000 push dword ptr [ebp+4016FC]
0040D4D7 FFB5 F8164000 push dword ptr [ebp+4016F8]
0040D4DD E8 8C000000 call 0040D56E
0040D4E2 8BB5 EC164000 mov esi, [ebp+4016EC]
0040D4E8 837E 10 00 cmp dword ptr [esi+10], 0
0040D4EC 74 62 je short 0040D550 ; F8到这里,回车让跳转实现
。。。
0040D550 FFA5 F4164000 jmp [ebp+4016F4] ; F4运行到这里。F8跳向OEP
跳向这里:用OD脱壳。
00401000 BE db BE
00401001 6A db
很简单的壳
---------------------------------------------------------------------
第二步:
修复文件头
这个CRACKME的文件头被加密了,载入脱壳后的文件
00401000 > $ BE 6A124000 mov esi, 0040126A ; 停在这里
00401005 . 6A 04 push 4 ; /Protect = PAGE_READWRITE
00401007 . 68 00100000 push 1000 ; |AllocationType = MEM_COMMIT
0040100C . 68 00400000 push 4000 ; |Size = 4000 (16384.)
00401011 . 6A 00 push 0 ; |Address = NULL
00401013 . E8 64420000 call <jmp.&kernel32.VirtualAlloc> ; \VirtualAlloc
省略一些代码。。。。。。
00401039 . C1C3 07 rol ebx, 7
0040103C .^ E2 EE loopd short 0040102C
0040103E . 8B1D 08604000 mov ebx, [406008] ; 运行到这里,文件头解密完毕
注意OD信息窗口的提示:
ds:[00406008]=00370000, (ASCII "MZP")。就是这个00370000
在命令行输入 D 00370000,后看到了一些信息,不用理他们。右键---》备分---》保存数据到文件
将新文件命名后,保存。
---------------------------------------------------------------------
第三步:
分析算法:
用OD载入脱壳并修复后的CRACKME,在命令行下短点
BP GetDlgItemTextA 任意输入注册信息后程序中断了
来到这里。。。
00401143 |. 6A 64 push 64 ; /Count = 64 (100.)
00401145 |. 68 26404000 push 00404026 ; |Buffer = _0037000.00404026
0040114A |. 6A 00 push 0 ; |ControlID = 0
0040114C |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040114F |. E8 2B200000 call <jmp.&USER32.GetDlg>; \GetDlgItemTextA
00401154 |. 83F8 04 cmp eax, 4 ; 注册名位数与4比较
00401157 |. 0F86 1101000>jbe 0040126E ; 小于4位就跳向失败
0040115D |. A3 EE404000 mov [4040EE], eax
00401162 |. 6A 64 push 64 ; /Count = 64 (100.)
00401164 |. 68 8A404000 push 0040408A ; |Buffer = _0037000.0040408A
00401169 |. 6A 01 push 1 ; |ControlID = 1
0040116B |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040116E |. E8 0C200000 call <jmp.&USER32.GetDlg>; \GetDlgItemTextA
00401173 |. 85C0 test eax, eax ; 输入注册码了吗?
00401175 |. 0F84 F300000>je 0040126E ; 没有输入注册码就跳向失败
0040117B |. FF35 EE40400>push dword ptr [4040EE]
00401181 |. 68 26404000 push 00404026 ; 取注册名准备进行计算
00401186 |. E8 EE000000 call 00401279 ; 将注册名进行MD5计算
对注册名进行了MD5计算后,就把MD5(注册名)作为第一张密码表,设为密码表1
在此以注册名lovetc为例,MD5(lovetc)= 3A76C4E1F2907B1C35319657E278EA05
所以:
密码表1=3A76C4E1F2907B1C35319657E278EA05
0040118B |. 8BF0 mov esi, eax
0040118D |. BF 06404000 mov edi, 00404006
00401192 |. B9 10000000 mov ecx, 10
00401197 |. F3:A4 rep movs byte ptr es:[e>; 将MD5(注册名)存放在地址00404006处
00401199 |. 83C4 08 add esp, 8
0040119C |. 33C0 xor eax, eax ; EAX清零
0040119E |. B9 8A404000 mov ecx, 0040408A ; 使ECX等于输入的注册码
004011A3 |. 8841 08 mov [ecx+8], al ; 使AL等于注册码的第9位
004011A6 |. 8861 11 mov [ecx+11], ah ; 使AH等于注册码的第18位
004011A9 |. 8841 1A mov [ecx+1A], al
004011AC |. 51 push ecx ; ECX等于注册码的前8位“12345678”
004011AD |. E8 720F0000 call 00402124
004011B2 |. A3 F2404000 mov [4040F2], eax ; 将注册码前8位放在004040F2中
004011B7 |. BE 93404000 mov esi, 00404093 ; ASCII "2C15C06D"
004011BC |. 56 push esi ; 使ESI等于注册码的第10到第17位
004011BD |. E8 620F0000 call 00402124
004011C2 |. C1C0 07 rol eax, 7 ; ROL(01234567,7)=91A2B380,设为A
004011C5 |. A3 F6404000 mov [4040F6], eax ; 将91A2B380这个值,储存在地址4040F6处
004011CA |. BE 9C404000 mov esi, 0040409C ; ASCII "0386EBE2"
004011CF |. 56 push esi ; 使ESI等于注册码的19到26位
004011D0 |. E8 4F0F0000 call 00402124
004011D5 |. C1C8 09 ror eax, 9 ; ROR(90123456,9)=2B48091A,设为B
004011D8 |. A3 FA404000 mov [4040FA], eax ; 将2B48091A这个值储存在地址4040FA处
对注册名进行MD5处理后,再进行对注册码的处理。
在这里以注册码12345678901234567890123456为例。
1)注册码前8位就设为“注册码前8为”
2)ROL(注册码10~17位,7),设为A
3)ROR(注册码19~26位,9),设为B
注册码的第9,18位可以是任意字符。
作者逍遥风
在处理完注册码后开始查表进行计算
这里要用到两张密码表:
密码表1=3A76C4E1F2907B1C35319657E278EA05
密码表2为:从地址0040216D处提取:
A6, 0B, 31, D1, AC, B5, DF, 98, DB, 72, FD, 2F, B7, DF, 1A, D0,
ED, AF, E1, B8, 96, 7E, 26, 6A, 45, 90, 7C, BA, 99, 7F, 2C, F1,
47, 99, A1, 24, F7, 6C, 91, B3, E2, F2, 01, 08, 16, FC, 8E, 85,
D8, 20, 69, 63, 69, 4E, 57, 71, A3, FE, 58, A4, 7E, 3D, 93, F4,
8F, 74, 95, 0D, 58, B6, 8E, 72, 58, CD, 8B, 71, EE, 4A, 15, 82,
1D, A4, 54, 7B, B5, 59, 5A, C2, 39, D5, 30, 9C, 13, 60, F2, 2A,
23, B0, D1, C5, F0, 85, 60, 28, 18, 79, 41, CA, EF, 38, DB, B8,
B0, DC, 79, 8E, 0E, 18, 3A, 60, 8B, 0E, 9E, 6C, 3E, 8A, 1E, B0,
C1, 77, 15, D7, 27, 4B, 31, BD, DA, 2F, AF, 78, 60, 5C, 60, 55,
F3, 25, 55, E6, 94, AB, 55, AA, 62, 98, 48, 57, 40, 14, E8, 63,
6A, 39, CA, 55, B6, 10, AB, 2A, 34, 5C, CC, B4, CE, E8, 41, 11,
AF, 86, 54, A1, 93, E9, 72, 7C, 11, 14, EE, B3, 2A, BC, 6F, 63,
5D, C5, A9, 2B, F6, 31, 18, 74, 16, 3E, 5C, CE, 1E, 93, 87, 9B,
33, BA, D6, AF, 5C, CF, 24, 6C, 81, 53, 32, 7A, 77, 86, 95, 28,
98, 48, 8F, 3B, AF, B9, 4B, 6B, 1B, E8, BF, C4, 93, 21, 28, 66,
CC, 09, D8, 61, 91, A9, 21, FB, 60, AC, 7C, 48, 32, 80, EC, 5D,
5D, 5D, 84, EF
004011DD |. F8 clc
004011DE |. 1BC9 sbb ecx, ecx
004011E0 |. BE 06404000 mov esi, 00404006 ; 使ESI指向地址404006,即:指向密码表1{MD5(注册名)}
004011E5 |. BF 6D214000 mov edi, 0040216D ; 使EDI指向地址40216D(即:指向密码表2)
004011EA |. 0FB606 movzx eax, byte ptr [esi] ; 取密码表1的第1位
004011ED |. 8B1C38 mov ebx, [eax+edi] ; 使EBX指向密码表2中EAX+EDI所指向地址的数据
004011F0 |. 0FB646 03 movzx eax, byte ptr [esi+>; 使EAX指向密码表1的第4位
004011F4 |. 8B1438 mov edx, [eax+edi] ; 使EDX指向密码表2中EAX+EDI所指向地址的数据
004011F7 |. 33DA xor ebx, edx ; XOR(EBX,EDX)所得的结果设为C
004011F9 |. A1 F2404000 mov eax, [4040F2] ; 使EAX等于注册名的1~8位
004011FE |. 33C3 xor eax, ebx ; 比较注册名前8为与C是否相等
00401200 |. 03C8 add ecx, eax
00401202 |. 0FB646 04 movzx eax, byte ptr [esi+>; 使EAX指向密码表1的第5位
00401206 |. 8B1C38 mov ebx, [eax+edi] ; 使EBX指向密码表2中EAX+EDI所指向地址的数据
00401209 |. 0FB646 08 movzx eax, byte ptr [esi+>; 使EAX指向密码表1的第9位
0040120D |. 8B1438 mov edx, [eax+edi] ; 使EDX指向密码表2中EAX+EDI所指向地址的数据
00401210 |. 33DA xor ebx, edx ; XOR(EBX,EDX)所得结果设为E
00401212 |. A1 F6404000 mov eax, [4040F6] ; 使EAX等于A
00401217 |. 33C3 xor eax, ebx ; 检验A与E是否相等
00401219 |. 03C8 add ecx, eax ; 累加
0040121B |. 0FB646 09 movzx eax, byte ptr [esi+>; 使EAX指向密码表1的第10位
0040121F |. 8B1C38 mov ebx, [eax+edi] ; 使EBX指向密码表2中EAX+EDI所指向地址的数据
00401222 |. 0FB646 0A movzx eax, byte ptr [esi+>; 使EAX指向密码表1的第11位
00401226 |. 8B1438 mov edx, [eax+edi] ; 使EDX指向密码表2中EAX+EDI所指向地址的数据
00401229 |. 33DA xor ebx, edx ; XOR(EBX,EDX),结果设为G
0040122B |. A1 FA404000 mov eax, [4040FA] ; 使EAX等于B
00401230 |. 33C3 xor eax, ebx ; 检验B和G是否相等
00401232 |. 03C8 add ecx, eax ; ECX=3次检验的结果累加
00401234 |. 8BC1 mov eax, ecx ; 使EAX等于ECX。
00401236 |. B9 20000000 mov ecx, 20 ; 使ECX=32
0040123B |. F8 clc
0040123C |> 72 30 /jb short 0040126E
0040123E |. D1E8 |shr eax, 1 ; 检验比较结果
00401240 |.^ E2 FA \loopd short 0040123C
00401242 |. 6A 40 push 40
00401244 |. E8 07000000 call 00401250 ; PUSH ASCII "solved"
这部分算法以查表计算和XOR运算为主。下面以注册名lovetc为例进行说明:
注册名lovetc
一:注册码第一部分
1)MD5(lovetc)=3A76C4E1F2907B1C35319657E278EA05
2)指向密码表1的第1位:
取3A
3)使EBX指向密码表2中EAX+EDI所指向地址的数据
edi=0040216D。地址:0040216D+3A=004021A7
查看内容:D 4021A7=3D7EA458
所以:EBX就等于3D7EA458
4)使EAX指向密码表1的第4位
取E1
5)使EBX指向密码表2中EAX+EDI所指向地址的数据
地址:0040216D+E1=0040224E
查看内容:D 40224E=AF3BF48
所以:EDX就等于AF3B8F48
6)XOR(EBX,EDX)
XOR(3D7EA458,AF3B8F48)=92452B10
即C==92452B10
所以注册码第一部分必须为92452B10
二:注册码第二部分(文字省略)
F2
0040216D+F2=0040225F
D 40225F=A99161D8
EBX=A99161D8
XOR(A99161D8,A371574E)=0AE03696=E
35
0040216D+35=004021A2
D 4021A2=A371574E
EDX=A371574E
所以:A必须等于0AE03696,即ROL(注册码10~17位,7)必须等于0AE03696
三:注册名第三部分
31
0040216D+31=0040219E
D 40219E=69636920
EBX=69636920
XOR(69636920,9862AA55)=F101C375=G
96
0040216D+96=00402203
D 402203=9862AA55
EDX=9862AA55
所以B必须等于F101C375,即ROR(注册码19~26位,9)必须等于F101C375
最后根据所要求的条件,找出一组注册码
注册名:lovetc
注册码:92452B10_2C15C06D_0386EBE2
----------------------------------------------------------------------
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!