周末无聊,在tuts4you下载了个UnPackMe来看看,还算简单,信心没有遭受打击。
反调试手段比较少,就两种:
1、IsDebuggerPresent判断
2、API断点检测
壳特征:
EP代码开始走:
0046D000 > E8 04000000 call 0046D009
0046D009 5D pop ebp
0046D00A EB 05 jmp short 0046D011
基本上都是这种Call、pop、jmp、ret的跳转指令,F8、F7交替使用。
中间有个代码自解密的地方:
0046B8C6 BB DAB84600 mov ebx, 0046B8DA
0046B8CB B9 C8030000 mov ecx, 3C8
0046B8D0 B0 43 mov al, 43
0046B8D2 300419 xor byte ptr [ecx+ebx], al
0046B8D5 8A0419 mov al, byte ptr [ecx+ebx]
0046B8D8 ^ E2 F8 loopd short 0046B8D2
简单的异或解密,前一次异或得到的结果作为下一次异或的Key
在0046B8D8 下一句直接F4继续走几下就到了调试器检测地方:
0046B903 31C9 xor ecx, ecx
0046B905 83C1 10 add ecx, 10
0046B908 BB FFFFFF77 mov ebx, 77FFFFFF
0046B90D 64:8B83 1900008>mov eax, dword ptr fs:[ebx+88000019] ;fs:[18]
0046B914 8B4448 10 mov eax, dword ptr [eax+ecx*2+10] ;[eax+30]
0046B918 0FB640 02 movzx eax, byte ptr [eax+2]
0046B91C F7D0 not eax
0046B91E 83E0 01 and eax, 1
0046B921 89C3 mov ebx, eax
0046B923 68 F6FBC300 push 0C3FBF6
0046B928 E8 00000000 call 0046B92D
从进程的PEB信息中得到是否被调试,0046B918 movzx eax, byte ptr [eax+2]这里将eax改为0就可躲过检测。
如果不修改的话0046B921处ebx为0
0046B92D 832C24 33 sub dword ptr [esp], 33
0046B931 89E6 mov esi, esp
0046B933 83C6 04 add esi, 4
0046B936 FFE6 jmp esi ;跳到压入的堆栈代码处,地址0012FFA0
压入的0C3FBF6:
0012FFA0 F6FB idiv bl ;有调试器则bl为0,产生除0异常
0012FFA2 C3 retn
随后的代码中对得到kernel32.GetProcAddress和VirtuallAlloc的地址,并检查第一字节是否为CC
0046B9F3 57 push edi
0046B9F4 6A 00 push 0
0046B9F6 FFD0 call eax ;分配空间
0046B9F8 85C0 test eax, eax
0046B9FA 74 52 je short 0046BA4E
0046B9FC 50 push eax
0046B9FD 8D95 00100000 lea edx, dword ptr [ebp+1000]
0046BA03 50 push eax
0046BA04 52 push edx
0046BA05 E8 EC010000 call 0046BBF6 ;APLib解码
跟踪壳代码的话,接下来所做的工作是释放分配的内存空间、创建互斥体、IAT填充、解密OEP,基本上用到的API都要检查是否被下断点
0046BB4F 83C7 04 add edi, 4
0046BB52 A9 00000080 test eax, 80000000
0046BB57 74 08 je short 0046BB61
0046BB59 25 FFFF0000 and eax, 0FFFF
0046BB5E 50 push eax
0046BB5F EB 06 jmp short 0046BB67
0046BB61 01E8 add eax, ebp
0046BB63 83C0 02 add eax, 2
0046BB66 50 push eax
0046BB67 53 push ebx
0046BB68 FFD6 call esi
0046BB6A 5A pop edx
0046BB6B 59 pop ecx
0046BB6C 85C0 test eax, eax
0046BB6E ^ 0F84 DAFEFFFF je 0046BA4E
0046BB74 8038 CC cmp byte ptr [eax], 0CC
0046BB77 ^ 0F84 D1FEFFFF je 0046BA4E
0046BB7D 8902 mov dword ptr [edx], eax ;填充地址
0046BB7F 83C2 04 add edx, 4
0046BB82 ^ EB A4 jmp short 0046BB28
0046BB84 5F pop edi
0046BB85 83C1 14 add ecx, 14
0046BB88 8379 0C 00 cmp dword ptr [ecx+C], 0
0046BB8C ^ 0F85 65FFFFFF jnz 0046BAF7
0046BB92 90 nop ;这里F4完成IAT解密过程
0046BB93 EB 04 jmp short 0046BB99
跳到OEP:
0046BB99 68 B0710200 push 271B0
0046BB9E 79 08 jns short 0046BBA8 ;这里会跳走
0046BBA0 53 push ebx
0046BBA1 81C9 00000000 or ecx, 0
0046BBA7 5B pop ebx
0046BBA8 3BD0 cmp edx, eax
0046BBAA C1C9 E0 ror ecx, 0E0
0046BBAD F8 clc
0046BBAE 012C24 add dword ptr [esp], ebp ;00400000+271B0=004271B0
0046BBB1 C3 retn
Dump后,Import Rec修复,OEP填271B0,IAT Auto Search即可。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)