【文章标题】: crackme破解分析
【文章作者】: 逍遥风
【下载地址】: 自己搜索下载
【保护方式】: 无
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
----------------------------------------------------------------------
【详细过程】
总算放假了。又可以好好的来论坛了真高兴。放假先顺手分析了一个CRACKME,挺有趣的 ,与大家分享.
这个CRACKME比较有趣。有两关,第一关用到了一个让人没有想到的地方。
另外.:发现关于keyfile 重起验证类型的CRACKME分析还是有点少.希望大家
以后能够多多捧场.
用OD载入这个CRACKME,打开字符串查找看看有没有什么重要的信息。
超级字串参考+ , 条目 7
地址=004012C5
反汇编=PUSH KeyMe1.004030BB
文本字串=step 1 ok -> now register it! 注意到了吗“step 1 ok”看来这个CRACKME还是需要分步完成的。
好吧先看看他的第一步要怎样完成。
第一关
双击这个提示来到对应的代码处:
004012C1 |. 0BC0 OR EAX,EAX
004012C3 |. 75 2B JNZ SHORT KeyMe1.004012F0 注意这个跳转:
004012C5 |. 68 BB304000 PUSH KeyMe1.004030BB ; /step 1 ok -> now register it!
004012CA |. 6A 66 PUSH 66 ; |ControlID = 66 (102.)
004012CC |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012CF |. E8 AE000000 CALL <JMP.&USER32.SetDlgItemTextA> ; \SetDlgItemTextA
004012D4 |. 6A 00 PUSH 0 ; /Enable = FALSE
004012D6 |. FF35 56334000 PUSH DWORD PTR DS:[403356] ; |hWnd = NULL
004012DC |. E8 71000000 CALL <JMP.&USER32.EnableWindow> ; \EnableWindow
004012E1 |. 6A 01 PUSH 1 ; /Enable = TRUE
004012E3 |. FF35 5A334000 PUSH DWORD PTR DS:[40335A] ; |hWnd = NULL
004012E9 |. E8 64000000 CALL <JMP.&USER32.EnableWindow> ; \EnableWindow
004012EE |. EB 0F JMP SHORT KeyMe1.004012FF
004012F0 |> 68 F6304000 PUSH KeyMe1.004030F6 ; /registration failed!!!
代码最上方的跳转 很是可疑。到跳转前面看看。
0040126C |. 6A 00 PUSH 0 ; /在这里下断点
0040126E |. E8 03010000 CALL <JMP.&USER32.OpenClipboard> ; \OpenClipboard
00401273 |. 6A 01 PUSH 1 ; /Format = CF_TEXT
00401275 |. E8 E4000000 CALL <JMP.&USER32.GetClipboardData> ; \GetClipboardData
说明:
\OpenClipboard
\GetClipboardData
分别是用来打开剪切板和读取剪切板中内容的,剪切板中的内容就是我们平时用到“粘贴复制”时,复制的内容
0040127A |. 0BC0 OR EAX,EAX ; 读取剪切板中的信息
0040127C |. 74 72 JE SHORT KeyMe1.004012F0 ; 剪切板中没有信息就直接跳向失败
0040127E |. A3 33324000 MOV DWORD PTR DS:[403233],EAX
00401283 |. 60 PUSHAD
00401284 |. 9C PUSHFD
00401285 |. BE 33324000 MOV ESI,KeyMe1.00403233 ; 使ESI中的值等于剪切板中的内容
0040128A |. 8B36 MOV ESI,DWORD PTR DS:[ESI]
0040128C |. FF35 3E334000 PUSH DWORD PTR DS:[40333E]
00401292 |. 8F05 42334000 POP DWORD PTR DS:[403342]
00401298 |. 8B0D 46334000 MOV ECX,DWORD PTR DS:[403346]
0040129E |> 8A5431 FF /MOV DL,BYTE PTR DS:[ECX+ESI-1]
004012A2 |. 0FB6D2 |MOVZX EDX,DL
004012A5 |. 2915 42334000 |SUB DWORD PTR DS:[403342],EDX
004012AB |. 49 |DEC ECX
004012AC |.^ 75 F0 \JNZ SHORT KeyMe1.0040129E
004012AE |. 9D POPFD
004012AF |. 61 POPAD
004012B0 |. A1 42334000 MOV EAX,DWORD PTR DS:[403342]
004012B5 |. 6BC0 FF IMUL EAX,EAX,-1
004012B8 |. 83C0 01 ADD EAX,1
004012BB |. 6BC0 FF IMUL EAX,EAX,-1
004012BE |. 83C0 01 ADD EAX,1
004012C1 |. 0BC0 OR EAX,EAX ; 检验剪切板中的内容是否与一个字符串相等。
004012C3 |. 75 2B JNZ SHORT KeyMe1.004012F0 ; 不相等就条向失败
我们现在只能判断出剪切板中的内容要等于一个字符串,那这个字符串是什么呢。
注意这一句,当跟踪到下面这段代码时。
用到“D”命令了。
00401285 |. BE 33324000 MOV ESI,KeyMe1.00403233 ; 使ESI中的值等于剪切板中的内容
0040128A |. 8B36 MOV ESI,DWORD PTR DS:[ESI]
命令窗口输入:D 00403233
00403233 B0 9C 14 00 00 00 40 00 54 43 2D 46 31 44 44 39 ?...@.TC-F1DD9
00403243 44 31 41 39 33 31 43 00 00 00 00 00 00 00 00 00 D1A931C.........
看到了吗,那个字符串就是TC-F1DD9D1A931C(每个机子不一样的)。明白了吗,只要将这个字符串复制一下,再点击CRACKME
的“check”,就显示第一关通过了。
第二关:
现在来关心一下这个字符串是怎么来的。重新载入这个CRACKME
GetComputerNameA很可疑:
00401085 |. C701 FF000000 MOV DWORD PTR DS:[ECX],0FF ; 在这里下断点
0040108B |. 51 PUSH ECX ; /pBufferSize => KeyMe1.0040333A
0040108C |. 68 3B324000 PUSH KeyMe1.0040323B ; |Buffer = KeyMe1.0040323B
00401091 |. E8 86020000 CALL <JMP.&KERNEL32.GetComputerNameA> ; \GetComputerNameA
00401096 |. 68 3B324000 PUSH KeyMe1.0040323B ; /String = ""
0040109B |. E8 A0020000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA
004010A0 |. A3 46334000 MOV DWORD PTR DS:[403346],EAX ; 这时字符串出现了。
004010A5 |. 59 POP ECX
004010A6 |. 58 POP EAX
004010A7 |. 60 PUSHAD ; 原来那个字符串就是我们的计算机名
004010A8 |. 9C PUSHFD
004010A9 |. BE 3B324000 MOV ESI,KeyMe1.0040323B
004010AE |. C705 3E334000>MOV DWORD PTR DS:[40333E],0 ; 取计算机名准备计算
004010B8 |> AC /LODS BYTE PTR DS:[ESI] ; 循环计算
004010B9 |. 0FB6C0 |MOVZX EAX,AL ; 取每一位的ASCII值
004010BC |. 0105 3E334000 |ADD DWORD PTR DS:[40333E],EAX ; 累加计算
004010C2 |. 3C 00 |CMP AL,0 ; 计算完了么
004010C4 |.^ 75 F2 \JNZ SHORT KeyMe1.004010B8 ; 继续计算
004010C6 |. 9D POPFD
004010C7 |. 61 POPAD ; 累加的结果设为A
得到了结果A,继续往下又跟不成了,只好重来.一定要记住A的值.我这里
TC-F1DD9D1A931C的累加结果即A等于0x392
这次又发现了CreateFileA这个函数,继续看看
00401121 |. 6A 00 PUSH 0 ; /hTemplateFile = NULL
00401123 |. 68 80000000 PUSH 80 ; |Attributes = NORMAL
00401128 |. 6A 03 PUSH 3 ; |Mode = OPEN_EXISTING
0040112A |. 6A 00 PUSH 0 ; |pSecurity = NULL
0040112C |. 6A 01 PUSH 1 ; |ShareMode = FILE_SHARE_READ
0040112E |. 68 00000080 PUSH 80000000 ; |Access = GENERIC_READ
00401133 |. 68 26314000 PUSH KeyMe1.00403126 ; |reg.key
00401138 |. E8 D3010000 CALL <JMP.&KERNEL32.CreateFileA> ; \CreateFileA
0040113D |. 83F8 FF CMP EAX,-1 ; reg.key文件
00401140 |. 75 05 JNZ SHORT KeyMe1.00401147
00401142 |. E9 E7000000 JMP KeyMe1.0040122E ; 没有这个文件就OVER
00401147 |> A3 4A334000 MOV DWORD PTR DS:[40334A],EAX ; 检验完了文件,继续检验大小
0040114C |. 6A 00 PUSH 0 ; /pFileSizeHigh = NULL
0040114E |. FF35 4A334000 PUSH DWORD PTR DS:[40334A] ; |hFile = 00000090 (window)
00401154 |. E8 C9010000 CALL <JMP.&KERNEL32.GetFileSize> ; \GetFileSize
00401159 |. 83F8 08 CMP EAX,8 ; 文件最小为8个字节
0040115C |. 73 10 JNB SHORT KeyMe1.0040116E
0040115E |. FF35 4A334000 PUSH DWORD PTR DS:[40334A] ; /hObject = 00000090 (window)
00401164 |. E8 A1010000 CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle
00401169 |. E9 C0000000 JMP KeyMe1.0040122E
0040116E |> A3 52334000 MOV DWORD PTR DS:[403352],EAX
00401173 |. FF35 52334000 PUSH DWORD PTR DS:[403352] ; /MemSize = 8
00401179 |. 6A 40 PUSH 40 ; |Flags = GPTR
0040117B |. E8 AE010000 CALL <JMP.&KERNEL32.GlobalAlloc> ; \GlobalAlloc
00401180 |. 0BC0 OR EAX,EAX
00401182 |. 75 1F JNZ SHORT KeyMe1.004011A3
赶紧用HEX创建一个新文件,文件名rag.key 文件大小8字节
004011A3 |> \A3 4E334000 MOV DWORD PTR DS:[40334E],EAX ; 准备读取文件内容了
004011A8 |. 6A 00 PUSH 0 ; /pOverlapped = NULL
004011AA |. 68 2E314000 PUSH KeyMe1.0040312E ; |pBytesRead = KeyMe1.0040312E
004011AF |. FF35 52334000 PUSH DWORD PTR DS:[403352] ; |BytesToRead = 8
004011B5 |. FF35 4E334000 PUSH DWORD PTR DS:[40334E] ; |Buffer = 0014E408
004011BB |. FF35 4A334000 PUSH DWORD PTR DS:[40334A] ; |hFile = 00000090 (window)
004011C1 |. E8 74010000 CALL <JMP.&KERNEL32.ReadFile> ; \ReadFile
004011C6 |. 0BC0 OR EAX,EAX
004011C8 |. 75 18 JNZ SHORT KeyMe1.004011E2
004011CA |. FF35 4A334000 PUSH DWORD PTR DS:[40334A] ; /hObject = 00000090 (window)
004011D0 |. E8 35010000 CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle
004011D5 |. FF35 4E334000 PUSH DWORD PTR DS:[40334E] ; /hMem = 0014E408
004011DB |. E8 54010000 CALL <JMP.&KERNEL32.GlobalFree> ; \GlobalFree
004011E0 |. EB 4C JMP SHORT KeyMe1.0040122E
004011E2 |> FF35 4A334000 PUSH DWORD PTR DS:[40334A] ; /hObject = 00000090 (window)
004011E8 |. E8 1D010000 CALL <JMP.&KERNEL32.CloseHandle> ; \CloseHandle
004011ED |. 56 PUSH ESI
004011EE |. 52 PUSH EDX
004011EF |. 8B35 4E334000 MOV ESI,DWORD PTR DS:[40334E] ; 读取文件中的内容
004011F5 |. 8B06 MOV EAX,DWORD PTR DS:[ESI] ; 使EAX等于前四个字节的内容
004011F7 |. 83C6 04 ADD ESI,4
004011FA |. 8B16 MOV EDX,DWORD PTR DS:[ESI] ; 使EDX等于5到8字节的内容
004011FC |. 33C2 XOR EAX,EDX ; 将前四个字节内容与后四个字节内容做XOR计算.
注意哦。这里读取文件的内容是倒序的比如文件的内容是:11223344 55667788
读取的时候顺序就变成44332211 88776655
004011FE |. 8B15 42334000 MOV EDX,DWORD PTR DS:[403342] ; 结果设为B
00401204 |. 03C2 ADD EAX,EDX
00401206 |. 5A POP EDX
00401207 |. 5E POP ESI
00401208 |. 3B05 3E334000 CMP EAX,DWORD PTR DS:[40333E] ; 结果B的值与A的值相比较
0040120E |. 75 1E JNZ SHORT KeyMe1.0040122E ; 值相等就成功了.
00401210 |. 68 D9304000 PUSH KeyMe1.004030D9 ; /good work. you have done it!
00401215 |. 6A 66 PUSH 66 ; |ControlID = 66 (102.)
00401217 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040121A |. E8 63010000 CALL <JMP.&USER32.SetDlgItemTextA> ; \SetDlgItemTextA
0040121F |. 6A 00 PUSH 0 ; /Enable = FALSE
00401221 |. FF35 5A334000 PUSH DWORD PTR DS:[40335A] ; |hWnd = 015E0836 ('-> Register <-',class='Button',parent=002202A8)
00401227 |. E8 26010000 CALL <JMP.&USER32.EnableWindow> ; \EnableWindow
这下就完全明白了:文件的内容必须符合这个要求.(假设:文件刚好为8字节)
XOR(前四个字节,后四个字节) = 计算机名的累加值A
在这里我的计算机名为:TC-F1DD9D1A931C累加值为0x392
创建的reg.key文件的前四个字节内容为:11223344
根据这个就可以算出整个key文件的内容了
XOR(44332211,X) = 0x392
X = XOR(44332211,0x392) = 44332183
所以文件个字节的内容就应该是:11223344 83213344
* 注意顺序上的变化。
暂时好象不能传附件
----------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年01月21日 15:52:57
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!