可能有某某已经发表过了,但是不同的分析能看出不同的效果。
这里我只做了分析,没写相关的注册代码。不过分析得应该够详细吧,因为我还是个菜鸟。
希望能得个邀请码
这也是我第一次在看雪发帖。
如有不对之处,请大神纠正:
在这段代码上看到了cm.dll关键字,它是来检测cm.dll是否存在,所以我们创建个cm.dll来通过检测。
00401304 |. 57 push edi
00401305 |. 6A 00 push 0x0
00401307 |. 6A 03 push 0x3
00401309 |. 57 push edi
0040130A |. 6A 01 push 0x1
0040130C |. 68 00000080 push 0x80000000
00401311 |. 68 4C314000 push CrackMe.0040314C ; ASCII "cm.dll"
00401316 |. FFD0 call eax
00401318 |. 40 inc eax
00401319 |. 0F84 7A010000 je CrackMe.00401499 ; 判断cm.dll是否存在
cm.dll大小必须为27字节
0040131F |. 48 dec eax
00401320 |. A3 44314000 mov dword ptr ds:[0x403144],eax
00401325 |. E8 6E020000 call CrackMe.00401598 ; 获取文件大小
0040132A |. 93 xchg eax,ebx
0040132B |. 83FB 1B cmp ebx,0x1B ; 文件大小是否为1B=27
0040132E |. 0F85 65010000 jnz CrackMe.00401499 ; 等于1B就继续,不等就跳
00401334 |. 6A 00 push 0x0 ; /pOverlapped = NULL
00401336 |. 68 48314000 push CrackMe.00403148 ; |pBytesRead = CrackMe.00403148
0040133B |. 53 push ebx ; |BytesToRead
0040133C |. 68 53314000 push CrackMe.00403153 ; |Buffer = CrackMe.00403153
00401341 |. FF35 44314000 push dword ptr ds:[0x403144] ; |hFile = 00000064
00401347 |. E8 24030000 call <jmp.&kernel32.ReadFile> ; \ReadFile
0040134C |. FF35 44314000 push dword ptr ds:[0x403144] ; /hObject = 00000064
00401352 |. E8 EF020000 call <jmp.&kernel32.CloseHandle> ; \CloseHandle
第一个跳转的算法分析
00401357 |. 8D35 53314000 lea esi,dword ptr ds:[0x403153] ; 存放cm.dll数据到esi中
0040135D |. 56 push esi
0040135E |. 2BD2 sub edx,edx ; edx置0
00401360 |. 8B56 08 mov edx,dword ptr ds:[esi+0x8] ; 取第8位后4位数
00401363 |. 81EA 9AF7110E sub edx,0xE11F79A ; edx-0xE11F79A
00401369 |. 92 xchg eax,edx ; eax与edx数据交换
0040136A |. B9 24000000 mov ecx,0x24 ; 循环24次
0040136F 40 inc eax ; eax+1
00401370 C1C8 02 ror eax,0x2 ; 右循环移位
00401373 2D B6240000 sub eax,0x24B6 ; eax-0x24B6
00401378 |.^ E2 F5 \loopd XCrackMe.0040136F
0040137A |. 8B15 09304000 mov edx,dword ptr ds:[0x403009] ; EDX=088C67C4
00401380 |. 0FCA bswap edx ; EDX=C4678C08
00401382 |. 3BC2 cmp eax,edx ; eax与edx是否相等
00401384 |. 0F85 0F010000 jnz CrackMe.00401499
从这里可知eax的值必须为C4678C08
0040137A |. 8B15 09304000 mov edx,dword ptr ds:[0x403009] ; EDX=088C67C4
00401380 |. 0FCA bswap edx ; EDX=C4678C08
在这里进行反运算
0040136F 40 inc eax ; eax+1
00401370 C1C8 02 ror eax,0x2 ; 右循环移位
00401373 2D B6240000 sub eax,0x24B6 ; eax-0x24B6
00401378 |.^ E2 F5 \loopd XCrackMe.0040136F
改成
0040136F 05 B6240000 add eax,0x24B6 ; eax+24B6
00401374 C1C0 02 rol eax,0x2 ; 左循环移位
00401377 48 dec eax ; eax-1
00401378 |.^ E2 F5 \loopd XCrackMe.0040136F
然后注意这里
00401363 |. 81EA 9AF7110E sub edx,0xE11F79A ; edx-0xE11F79A
反运算得出的结果必须+0xE11F79A
126774D2+E11F79A=20796C6C
好了,我们就得出了第一个跳转的4个字节代码。
反过来从右到至左
6C6C7920
第8、9、10、11字节分别为6C 6C 79 20
00401384 /0F85 0F010000 jnz CrackMe.00401499
0040138A |. 8D3D BE304000 lea edi,dword ptr ds:[0x4030BE]
00401390 |. 66:8B06 mov ax,word ptr ds:[esi] ; 取文件第1、2位字节
00401393 |. 86E0 xchg al,ah ; 文件第1、2位字节交换位置
00401395 |. 66:8B5F 11 mov bx,word ptr ds:[edi+0x11] ; bx=5C27,知道了BX的值EAX值就为C4675C27
00401399 |. 35 4A1D0000 xor eax,0x1D4A ; 0xC4675C27 xor
0x1D4A = C467416D
所以文件的第0、1位字节为41 6D
0040139E |. 66:3BD8 cmp bx,ax
004013A1 |. 0F85 F2000000 jnz CrackMe.00401499
以下2个跳转必须合起来算
004013A1 |. 0F85 F2000000 jnz CrackMe.00401499
004013A7 |. 8B1D CC304000 mov ebx,dword ptr ds:[0x4030CC] ; ebx=27418BE4
004013AD |. 8B56 0E mov edx,dword ptr ds:[esi+0xE]
004013B0 0FCA bswap edx
004013B2 81F2 80E4D312 xor edx,0x12D3E480
004013B8 |. 66:3BD3 cmp dx,bx
004013BB |. 0F85 D8000000 jnz CrackMe.00401499
004013C1 |C1EA 10 shr edx,0x10
004013C4 |86F2 xchg dl,dh
004013C6 |. |66:81FA 75BC cmp dx,0xBC75
通过这调试段代码得知bx的值为8BE4
004013A7 |. 8B1D CC304000 mov ebx,dword ptr ds:[0x4030CC] ; ebx=27418BE4
这段代码是取edx值的前2位,BC75
004013C6 |. |66:81FA 75BC cmp dx,0xBC75
我们把以上2个值合起来
BC758BE4
注意这两段
004013C1 |C1EA 10 shr edx,0x10
004013C4 |86F2 xchg dl,dh
前2位需要调换
75BC8BE4
然后注意这两段
004013B0 0FCA bswap edx
004013B2 81F2 80E4D312 xor edx,0x12D3E480
把edx的值改成75BC8BE4的值,然后这两段代码交换,调试。
调试得出edx的值为646F6F67
14、15、16、17位的字节分别为67 6F 6F 64
004013CB /0F85 C8000000 jnz CrackMe.00401499
004013D1 |46 inc esi
004013D2 |46 inc esi
004013D3 |AC lods byte ptr ds:[esi] ; 获取第2位的字节
004013D4 |D0C0 rol al,1
004013D6 |2C 05 sub al,0x5
004013D8 |34 18 xor al,0x18
004013DA |8A1D 04304000 mov bl,byte ptr ds:[0x403004] ; bl=23
004013E0 |38C3 cmp bl,al
运算以下
xor al,0x18
add al,0x5
ror al,1
得
al=20
所以文件第2位的字节为20
004013E2 /0F85 B1000000 jnz CrackMe.00401499
004013E8 |8B1E mov ebx,dword ptr ds:[esi] ; 获取第3、4、5、6位字节
004013EA |8B15 83304000 mov edx,dword ptr ds:[0x403083] ; edx=0000BC75
004013F0 |2BDA sub ebx,edx
004013F2 |81FB 4CE5A701 cmp ebx,0x1A7E54C
改ebx为0x1A7E54C,然后进行调试运算
add ebx,edx
得出
65722049
第3、4、5、6位字节分别为49 20 72 65
004013F8 /0F85 9B000000 jnz CrackMe.00401499
004013FE |83C6 08 add esi,0x8
00401401 |8B16 mov edx,dword ptr ds:[esi] ; 获取第11、12、13、14位字节
00401403 |8A5E 07 mov bl,byte ptr ds:[esi+0x7] ; 获取第18位字节
00401406 |66:81FA 2061 cmp dx,0x6120
第11、12、18位字节分别为20 61 20
0040140B /0F85 88000000 jnz CrackMe.00401499
00401411 |0FCA bswap edx ; 高低位交换
00401413 |86D3 xchg bl,dl ; bl=20
00401415 |66:81FA 2020 cmp dx,0x2020
第13位字节为20
0040141A /75 7D jnz XCrackMe.00401499
0040141C |5E pop esi
0040141D |83C6 13 add esi,0x13
00401420 |8B3E mov edi,dword ptr ds:[esi] ; 获取第19、20、21、22位字节
00401422 |0FCF bswap edi
00401424 |57 push edi
00401425 |83C6 04 add esi,0x4
00401428 |8B1E mov ebx,dword ptr ds:[esi] ; 获取第23、24、25、26位字节
0040142A |0FCB bswap ebx
0040142C |03FB add edi,ebx
0040142E |81EF A2D3D7CE sub edi,0xCED7D3A2
00401434 |85FF test edi,edi
00401436 /75 61 jnz XCrackMe.00401499
00401438 |5F pop edi ; 获得第19、20、21、22位字节
00401439 |C1C7 04 rol edi,0x4
0040143C |81EF 36162637 sub edi,0x37261636
00401442 |85FF test edi,edi
先从最后面的jnz跳转开始算
改edi为0x37261636
改rol edi,0x4为ror edi,0x4
得
63726163
注意这2段代码
00401422 |0FCF bswap edi
0040142A |0FCB bswap ebx
第19、20、21、22位字节分别为63 61 72 63
然后0xCED7D3A2 - 0x63726163 = 0x6B65723F
第23、24、25、26位字节分别为6B 65 72 3F
整体结果为
00000000h: 41 6D 20 49 20 72 65 00 6C 6C 79 20 61 20 67 6F ; Am I re.lly a go
00000010h: 6F 64 20 63 72 61 63 6B 65 72 3F ; od cracker?
只有第7位可以随便乱填。。。。
合起来是一句英语:Am I really a good cracker?
CrackMe.zip
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)