|
欢迎您注册加入!这里有您将更精采!
您需要 登录 才可以下载或查看,没有账号?注册
x
下面的过程是按脱服务端的过程写的.
已知:
1.这个是2次加密的,不会用SDK.
2.VC编译的
step0.抹掉TLS表
用lord-PE把数据目录(Directories)中TLS一项全部置0,然后save.
注意:不能把TLS CALLBACK ADDRESS 和TLS CALLBACK INDEX置0 !!!!(why?I Don't Know)
BTW:这个"秘密"是forgot广播的.
step1.
经过step0后,就不用设置让OD停在系统断点了(设置停在EP).而且TLS中的"飞刀"也不用管了.但是还需要一个"核武器"----advencedolly插件.加上这个插件,EXEC的anti可以全过.
但是,本次脱壳用hideOD就可以了,因为我们没有KEY,无法跑到后面,也不需要跑到后面.所以很多anti是没有用的.
step2.
步骤其实很简单,经过上面的准备后.用OD载入,忽略所有异常:- 0BB8CE4E > E8 F7FEFFFF call 0BB8CD4A
- 0BB8CE53 05 07480000 add eax, 4807
- 0BB8CE58 FFE0 jmp eax
- 0BB8CE5A E8 EBFEFFFF call 0BB8CD4A
- 0BB8CE5F 05 9F6A0000 add eax, 6A9F
- 0BB8CE64 FFE0 jmp eax
- 0BB8CE66 E8 04000000 call 0BB8CE6F
- 0BB8CE6B FFFF ??? ; 未知命令
- 0BB8CE6D FFFF ??? ; 未知命令
- 0BB8CE6F 5E pop esi
- 0BB8CE70 C3 retn
复制代码 然后
1.HE GetProcAddress
2.F9
3.HD GetProcAddress
4.alt+f9
现在我们到了填充IAT的地方了:- 0BB8CBE7 55 push ebp
- 0BB8CBE8 8BEC mov ebp, esp
- 0BB8CBEA 83C4 F4 add esp, -0C
- 0BB8CBED 56 push esi
- 0BB8CBEE 57 push edi
- 0BB8CBEF 53 push ebx
- 0BB8CBF0 BE 00F0AD0A mov esi, 0AADF000
- 0BB8CBF5 B8 00004000 mov eax, 00400000
- 0BB8CBFA 8945 FC mov dword ptr ss:[ebp-4], eax
- 0BB8CBFD 89C2 mov edx, eax
- 0BB8CBFF 8B46 0C mov eax, dword ptr ds:[esi+C]
- 0BB8CC02 09C0 or eax, eax
- 0BB8CC04 0F84 8E000000 je 0BB8CC98
- 0BB8CC0A 01D0 add eax, edx
- 0BB8CC0C 89C3 mov ebx, eax
- 0BB8CC0E 50 push eax
- 0BB8CC0F FF15 B480AA0B call dword ptr ds:[<&kernel32.GetModu>; kernel32.GetModuleHandleA
- 0BB8CC15 09C0 or eax, eax
- 0BB8CC17 0F85 0F000000 jnz 0BB8CC2C
- 0BB8CC1D 53 push ebx
- 0BB8CC1E FF15 B880AA0B call dword ptr ds:[<&kernel32.LoadLib>; kernel32.LoadLibraryA
- 0BB8CC24 09C0 or eax, eax
- 0BB8CC26 0F84 64000000 je 0BB8CC90
- 0BB8CC2C 8945 F8 mov dword ptr ss:[ebp-8], eax
- 0BB8CC2F 6A 00 push 0
- 0BB8CC31 8F45 F4 pop dword ptr ss:[ebp-C]
- 0BB8CC34 8B06 mov eax, dword ptr ds:[esi]
- 0BB8CC36 09C0 or eax, eax
- 0BB8CC38 8B55 FC mov edx, dword ptr ss:[ebp-4]
- 0BB8CC3B 0F85 03000000 jnz 0BB8CC44
- 0BB8CC41 8B46 10 mov eax, dword ptr ds:[esi+10]
- 0BB8CC44 01D0 add eax, edx
- 0BB8CC46 0345 F4 add eax, dword ptr ss:[ebp-C]
- 0BB8CC49 8B18 mov ebx, dword ptr ds:[eax]
- 0BB8CC4B 8B7E 10 mov edi, dword ptr ds:[esi+10]
- 0BB8CC4E 01D7 add edi, edx
- 0BB8CC50 037D F4 add edi, dword ptr ss:[ebp-C]
- 0BB8CC53 09DB or ebx, ebx
- 0BB8CC55 0F84 E2000000 je 0BB8CD3D
- 0BB8CC5B F7C3 00000080 test ebx, 80000000
- 0BB8CC61 0F85 04000000 jnz 0BB8CC6B
- 0BB8CC67 8D5C13 02 lea ebx, dword ptr ds:[ebx+edx+2]
- 0BB8CC6B 81E3 FFFFFF7F and ebx, 7FFFFFFF
- 0BB8CC71 53 push ebx
- 0BB8CC72 FF75 F8 push dword ptr ss:[ebp-8]
- 0BB8CC75 FF15 BC80AA0B call dword ptr ds:[<&kernel32.GetProc>; kernel32.GetProcAddress
- 0BB8CC7B 09C0 or eax, eax ; WS2_32.send //我们现在停在这里
- 0BB8CC7D 0F84 0D000000 je 0BB8CC90
- 0BB8CC83 8907 mov dword ptr ds:[edi], eax
- 0BB8CC85 8345 F4 04 add dword ptr ss:[ebp-C], 4
- 0BB8CC89 ^ E9 A6FFFFFF jmp 0BB8CC34
- 0BB8CC8E 0000 add byte ptr ds:[eax], al
- 0BB8CC90 53 push ebx
- 0BB8CC91 89D8 mov eax, ebx
- 0BB8CC93 E8 07000000 call 0BB8CC9F
- 0BB8CC98 5B pop ebx //走到这里后IAT就填充完毕了,在这里F4
- 0BB8CC99 5F pop edi
- 0BB8CC9A 5E pop esi
- 0BB8CC9B 8BE5 mov esp, ebp
- 0BB8CC9D 5D pop ebp
- 0BB8CC9E C3 retn
复制代码 观察上面代码发现,者个函数就是填充IAT的函数,退出这个函数后IAT就处理完了.所以在0BB8CC98 上F4走完这个函数.
BTW:论坛上看到过几位牛人讨论无KEY脱exec,再出来注册框之前,所有东西都解码完毕了.
我想一般的壳填充IAT都是最后一步,于是我就去看看代码段是否解码完了.果然全部代码都解出来了.
step3.修复stolen code
再次感谢shoooo,forgot的指点.
因为IAT已经填充完,而且没有加密.根据VC的启动代码都会call GetVersion,所以根据IAT反查出Call GetVersion的地址:- 00529265 - E9 E4ED5E0A jmp 0AB1804E
- 0052926A 8BC2 mov eax, edx
- 0052926C 5A pop edx
- 0052926D - E9 8EDD5B0A jmp 0AAE7000
- 00529272 C1FC 56 sar esp, 56
- 00529275 BE 948B56E8 mov esi, E8568B94
- 0052927A 50 push eax
- 0052927B 64:8925 0000000>mov dword ptr fs:[0], esp
- 00529282 83EC 58 sub esp, 58
- 00529285 53 push ebx
- 00529286 56 push esi
- 00529287 57 push edi
- 00529288 8965 E8 mov dword ptr ss:[ebp-18], esp
- 0052928B FF15 34FDAD0A call dword ptr ds:[AADFD34] ; kernel32.GetVersion //See?See!
- 00529291 33D2 xor edx, edx
- 00529293 8AD4 mov dl, ah
复制代码 根据VC的OEP的特称,可以断定00529265是OEP.
但是被stolen了5行
应该是
push ebp
mov ebp,esp
push -1
push imm32
push imm32
...........
关键就是这两个imm32是多少.如果有KEY可以让程序跑起来断在后在,通过堆栈的值来修复这两个数.但问题是,我们没有KEY,程序无法运行.
我请教了forgot,问这两个imm32有没有办法找出来.他说这是VC的机制,是个xxx表.由于我愚钝,似懂非懂.后来遇上了shoooo.shoooo说这就是VC封装的SEH.想弄清楚就自己写个
__try,__except来看看.
于是豁然开朗~
我大体说一下怎么找这两imm32(为什么这样找?自己写个__try,__except看看就明白了,还有就是看看Crt.c或者crt0.c的源码.)
先纪录两个地址:- 00529265 - E9 E4ED5E0A jmp 0AB1804E
- 0052926A 8BC2 mov eax, edx
- 0052926C 5A pop edx
- 0052926D - E9 8EDD5B0A jmp 0AAE7000
- 00529272 C1FC 56 sar esp, 56
- 00529275 BE 948B56E8 mov esi, E8568B94
- 0052927A 50 push eax
- 0052927B 64:8925 0000000>mov dword ptr fs:[0], esp
- 00529282 83EC 58 sub esp, 58
- 00529285 53 push ebx
- 00529286 56 push esi
- 00529287 57 push edi
- 00529288 8965 E8 mov dword ptr ss:[ebp-18], esp
- 0052928B FF15 34FDAD0A call dword ptr ds:[AADFD34] ; kernel32.GetVersion
- 00529291 33D2 xor edx, edx
- 00529293 8AD4 mov dl, ah
- 00529295 8915 D0C7AD0A mov dword ptr ds:[AADC7D0], edx
- 0052929B 8BC8 mov ecx, eax
- 0052929D 81E1 FF000000 and ecx, 0FF
- 005292A3 890D CCC7AD0A mov dword ptr ds:[AADC7CC], ecx
- 005292A9 C1E1 08 shl ecx, 8
- 005292AC 03CA add ecx, edx
- 005292AE 890D C8C7AD0A mov dword ptr ds:[AADC7C8], ecx
- 005292B4 C1E8 10 shr eax, 10
- 005292B7 A3 C4C7AD0A mov dword ptr ds:[AADC7C4], eax
- 005292BC 6A 01 push 1
- 005292BE E8 7E560000 call 0052E941
- 005292C3 59 pop ecx
- 005292C4 85C0 test eax, eax
- 005292C6 75 08 jnz short 005292D0
- 005292C8 6A 1C push 1C
- 005292CA E8 C3000000 call 00529392
- 005292CF 59 pop ecx
- 005292D0 E8 DD1A0000 call 0052ADB2
- 005292D5 85C0 test eax, eax
- 005292D7 75 08 jnz short 005292E1
- 005292D9 6A 10 push 10
- 005292DB E8 B2000000 call 00529392
- 005292E0 59 pop ecx
- 005292E1 33F6 xor esi, esi
- 005292E3 8975 FC mov dword ptr ss:[ebp-4], esi
- 005292E6 E8 52850000 call 0053183D
- 005292EB FF15 0CFEAD0A call dword ptr ds:[AADFE0C] ; kernel32.GetCommandLineA
- 005292F1 A3 84E7AD0A mov dword ptr ds:[AADE784], eax
- 005292F6 E8 10840000 call 0053170B
- 005292FB A3 B4C7AD0A mov dword ptr ds:[AADC7B4], eax
- 00529300 E8 B9810000 call 005314BE
- 00529305 E8 FB800000 call 00531405
- 0052930A E8 41050000 call 00529850
- 0052930F 8975 D0 mov dword ptr ss:[ebp-30], esi
- 00529312 8D45 A4 lea eax, dword ptr ss:[ebp-5C]
- 00529315 50 push eax
- 00529316 FF15 08FEAD0A call dword ptr ds:[AADFE08] ; kernel32.GetStartupInfoA
- 0052931C E8 8C800000 call 005313AD
- 00529321 8945 9C mov dword ptr ss:[ebp-64], eax
- 00529324 F645 D0 01 test byte ptr ss:[ebp-30], 1
- 00529328 74 06 je short 00529330
- 0052932A 0FB745 D4 movzx eax, word ptr ss:[ebp-2C]
- 0052932E EB 03 jmp short 00529333
- 00529330 6A 0A push 0A
- 00529332 58 pop eax
- 00529333 50 push eax
- 00529334 FF75 9C push dword ptr ss:[ebp-64]
- 00529337 56 push esi
- 00529338 56 push esi
- 00529339 FF15 50FDAD0A call dword ptr ds:[AADFD50] ; kernel32.GetModuleHandleA
- 0052933F 50 push eax
- 00529340 E8 4E8AEDFF call 00401D93 ////这个就是Call WinMain
- 00529345 8945 A0 mov dword ptr ss:[ebp-60], eax
- 00529348 50 push eax
- 00529349 E8 2F050000 call 0052987D
- 0052934E 8B45 EC mov eax, dword ptr ss:[ebp-14] //这一行
- 00529351 8B08 mov ecx, dword ptr ds:[eax]
- 00529353 8B09 mov ecx, dword ptr ds:[ecx]
- 00529355 894D 98 mov dword ptr ss:[ebp-68], ecx
- 00529358 50 push eax
- 00529359 51 push ecx
- 0052935A E8 89400000 call 0052D3E8
- 0052935F 59 pop ecx
- 00529360 59 pop ecx
- 00529361 C3 retn
- 00529362 8B65 E8 mov esp, dword ptr ss:[ebp-18] //还有这一行
- 00529365 FF75 98 push dword ptr ss:[ebp-68]
- 00529368 E8 21050000 call 0052988E
- 0052936D 833D BCC7AD0A 0>cmp dword ptr ds:[AADC7BC], 1
- 00529374 75 05 jnz short 0052937B
- 00529376 E8 D2860000 call 00531A4D
- 0052937B FF7424 04 push dword ptr ss:[esp+4]
- 0052937F E8 02870000 call 00531A86
- 00529384 68 FF000000 push 0FF
- 00529389 FF15 CC566200 call dword ptr ds:[6256CC] ; GameServ.0052988E
- 0052938F 59 pop ecx
- 00529390 59 pop ecx
- 00529391 C3 retn
- 00529392 833D BCC7AD0A 0>cmp dword ptr ds:[AADC7BC], 1
- 00529399 75 05 jnz short 005293A0
- 0052939B E8 AD860000 call 00531A4D
- 005293A0 FF7424 04 push dword ptr ss:[esp+4]
- 005293A4 E8 DD860000 call 00531A86
- 005293A9 59 pop ecx
- 005293AA 68 FF000000 push 0FF
- 005293AF FF15 10FEAD0A call dword ptr ds:[AADFE10] ; kernel32.ExitProcess
- 005293B5 C3 retn
复制代码 得到两个地址:
0052934E
00529362
然后到数据窗口转到data段,搜索2进制字串:
FF FF FF FF 4e 93 52 00 62 93 52 00
找一个:
00615E68 FF FF FF FF 4E 93 52 00 62 93 52 00 80 90 61 00
这个存放这个2进制字串的地址就是第一个imm32
于是我们知道了第一个imm32是00615E68
第二个就简单了,是 SEH_HANDLE函数的地址,这个有个明显的标记
在代码段搜索2进制字串:"VC20XC00"
找到一个:- 00526CCC . 56 43 32 30 5>ascii "VC20XC00"
- 00526CD4 /$ 55 push ebp ; 结构异常处理程序
- 00526CD5 |. 8BEC mov ebp, esp
- 00526CD7 |. 83EC 08 sub esp, 8
- 00526CDA |. 53 push ebx
- 00526CDB |. 56 push esi
- 00526CDC |. 57 push edi
- 00526CDD |. 55 push ebp
- 00526CDE |. FC cld
复制代码 于是第二个imm32就是00526CD4
现在我们就能修复stolen code了
修复后- 004010C0 >/$ 55 push ebp
- 004010C1 |. 8BEC mov ebp, esp
- 004010C3 |. 6A FF push -1
- 004010C5 |. 68 40014200 push 00615E68
- 004010CA |. 68 A42C4000 push 00526CD4 ; SE 处理程序安装
- 004010CF |. 64:A1 0000000>mov eax, dword ptr fs:[0]
- 004010D5 |. 50 push eax
- 004010D6 |. 64:8925 00000>mov dword ptr fs:[0], esp
- 00529282 . 83EC 58 sub esp, 58
- 004010E0 |. 53 push ebx
- 004010E1 |. 56 push esi
- 004010E2 |. 57 push edi
- 004010E3 |. 8965 E8 mov dword ptr ss:[ebp-18], esp
- 004010E6 |. FF15 94514200 call dword ptr ds:[<&KERNEL32.GetVers>; kernel32.GetVersion
复制代码 现在用lordPE,先correct ImageSize,然后dump full.(这个文件巨大有100多MB).
把dump.exe用PE-TOOL把最后3个区段砍掉(壳加上去的),然后用LordPE rebuildPE(注意不要rebuild ImportTable).
之后文件小多了,但是还是有10+MB
step4. 修复导入表
这步就不说了,因为IAT完好无损.
step5.
over. |
|