环境
windows xp sp3
工具
1.exeinfo pe
2.ollydbg
3.WinHex
查壳
和上一个一样,OD载入判断出
测试
运行后发现是没有任何提示,而且没有输入serial的窗口,通过任务管理器可以看出程序的名称写有“Uncracked”,可以猜测是keyfile了。
也可以通过OD载入后观察出来:
00401016 |. 6A 00 push 0x0 ; /hTemplateFile = NULL
00401018 |. 68 80000000 push 0x80 ; |Attributes = NORMAL
0040101D |. 6A 03 push 0x3 ; |Mode = OPEN_EXISTING
0040101F |. 6A 00 push 0x0 ; |pSecurity = NULL
00401021 |. 6A 03 push 0x3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
00401023 |. 68 000000C0 push 0xC0000000 ; |Access = GENERIC_READ|GENERIC_WRITE
00401028 |. 68 D7204000 push Cruehead.004020D7 ; |FileName = "CRACKME3.KEY"
0040102D |. E8 76040000 call <jmp.&KERNEL32.CreateFileA> ; \CreateFileA
00401032 |. 83F8 FF cmp eax,-0x1 ; 判断文件是否存在
00401035 |. 75 0C jnz XCruehead.00401043
00401037 |> 68 0E214000 push Cruehead.0040210E ; ASCII "CrackMe v3.0 "
0040103C |. E8 B4020000 call Cruehead.004012F5
00401041 |. EB 6B jmp XCruehead.004010AE
00401043 |> A3 F5204000 mov dword ptr ds:[0x4020F5],eax
00401048 |. B8 12000000 mov eax,0x12
0040104D |. BB 08204000 mov ebx,Cruehead.00402008
00401052 |. 6A 00 push 0x0 ; /pOverlapped = NULL
00401054 |. 68 A0214000 push Cruehead.004021A0 ; |pBytesRead = Cruehead.004021A0
00401059 |. 50 push eax ; |BytesToRead => 12 (18.)
0040105A |. 53 push ebx ; |Buffer => Cruehead.00402008
0040105B |. FF35 F5204000 push dword ptr ds:[0x4020F5] ; |hFile = NULL
00401061 |. E8 30040000 call <jmp.&KERNEL32.ReadFile> ; \ReadFile
00401066 |. 833D A0214000>cmp dword ptr ds:[0x4021A0],0x12 ; 这里是确认keyfile是否存在0x12个字符
0040106D |.^ 75 C8 jnz XCruehead.00401037
0040106F |. 68 08204000 push Cruehead.00402008
00401074 |. E8 98020000 call Cruehead.00401311 ; 将前14个字符进行计算,结果保存在[0x4020F9]中
00401079 |. 8135 F9204000>xor dword ptr ds:[0x4020F9],0x12345678 ; 这里是计算异或
00401083 |. 83C4 04 add esp,0x4
00401086 |. 68 08204000 push Cruehead.00402008
0040108B |. E8 AC020000 call Cruehead.0040133C ; 这里是取keyfile中后4个字符
00401090 |. 83C4 04 add esp,0x4
00401093 |. 3B05 F9204000 cmp eax,dword ptr ds:[0x4020F9] ; 比较是否相同
00401099 |. 0F94C0 sete al
0040109C |. 50 push eax
0040109D |. 84C0 test al,al
0040109F |.^ 74 96 je XCruehead.00401037
可以在[00401028]处得知要的keyfile名称。接下来就是读取keyfile文件内是否存在18个字符(0x12)。不存在就跳转。
00401311 /$ 33C9 xor ecx,ecx
00401313 |. 33C0 xor eax,eax
00401315 |. 8B7424 04 mov esi,dword ptr ss:[esp+0x4]
00401319 |. B3 41 mov bl,0x41
0040131B |> 8A06 /mov al,byte ptr ds:[esi]
0040131D |. 32C3 |xor al,bl
0040131F |. 8806 |mov byte ptr ds:[esi],al ; 这里将会改变从keyfile中读取到的值,并将这个值显示为Cracker名
00401321 |. 46 |inc esi
00401322 |. FEC3 |inc bl
00401324 |. 0105 F9204000 |add dword ptr ds:[0x4020F9],eax
0040132A |. 3C 00 |cmp al,0x0
0040132C |. 74 07 |je XCruehead.00401335
0040132E |. FEC1 |inc cl
00401330 |. 80FB 4F |cmp bl,0x4F
00401333 |.^ 75 E6 \jnz XCruehead.0040131B
00401335 |> 890D 49214000 mov dword ptr ds:[0x402149],ecx
0040133B \. C3 retn
读取前14个字符的内容,并且对bl的值进行异或,异或后的结果保存回对应的位置,用来作为Cracker的name
前14个字符加起来的值之和会与0x12345678异或,异或后的结果将于剩下的4个字符比较是否相等,相等就显示正确的对话框。
要用16进制编辑器编辑!
keyfile:CRACKME3.KEY的内容:
20 20 20 20 20 20 20 20 20 20 20 20 20 20 D1 53 34 12