|
【文章标题】: zp1.4脱壳
【文章作者】: faint88
【软件名称】: zp_1.4.exe
【下载地址】: http://www.unpack.cn/viewthread.php?tid=29485&extra=page%3D4 9楼
【加壳方式】: zp1.4
【编写语言】: delphi
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
004987C9 > 8D84C0 00000401 lea eax, dword ptr [eax+eax*8+104000>
004987D0 ^ E9 46FCFFFF jmp 0049841B
004987D5 06 push es
004987D6 ^ 0F83 E7FCFFFF jnb 004984C3
004987DC ^ E9 25FFFFFF jmp 00498706
004987E1 8BD5 mov edx, ebp
004987E3 E9 0A010000 jmp 004988F2
004987E8 07 pop es
004987E9 3C FF cmp al, 0FF
004987EB D0E9 shr cl, 1
004987ED 1C FE sbb al, 0FE
004987EF FFFF ??? ; 未知命令
004987F1 FD std
004987F2 1801 sbb byte ptr [ecx], al
004987F4 05 41E954FC add eax, FC54E941
004987F9 FFFF ??? ; 未知命令
004987FB F1 int1
004987FC BC C3E9FDFC mov esp, FCFDE9C3
00498801 FFFF ??? ; 未知命令
00498803 51 push ecx
00498804 ^ E9 01FCFFFF jmp 0049840A
1.到达OEP
一直F7 到达
004986F4 60 pushad
004986F5 E9 BE020000 jmp 004989B8
004986FA 837E B2 80 cmp dword ptr [esi-4E], -80
004986FE E9 E3040000 jmp 00498BE6
00498703 8B10 mov edx, dword ptr [eax]
00498705 EA 33C0E976 030>jmp far 0003:76E9C033
0049870C 002B add byte ptr [ebx], ch
F8 ESP定律 hr esp
F9 删除断点 单步 发现段间跳转
00453D0C 55 push ebp ; <---OEP
00453D0D 8BEC mov ebp, esp
00453D0F 83C4 F0 add esp, -10
00453D12 B8 2C3B4500 mov eax, 00453B2C
00453D17 E8 441FFBFF call 00405C60
00453D1C A1 58504500 mov eax, dword ptr [455058]
00453D21 8B00 mov eax, dword ptr [eax]
00453D23 E8 74E3FFFF call 0045209C
00453D28 8B0D 38514500 mov ecx, dword ptr [455138] ; zp_1_4.00456BFC
00453D2E A1 58504500 mov eax, dword ptr [455058]
00453D33 8B00 mov eax, dword ptr [eax]
00453D35 8B15 3C364500 mov edx, dword ptr [45363C] ; zp_1_4.00453688
00453D3B E8 74E3FFFF call 004520B4
00453D40 A1 58504500 mov eax, dword ptr [455058]
2 IAT修复
这个程序有DLL模拟
重开程序 下CreateFileA和VirtualAlloc 2个硬件执行断点
F9 开始停在VirtualAlloc的断点都不要管 继续F9
看堆栈
0013F8A0 00E615C4 /CALL 到 CreateFileA 来自 00E615BE
0013F8A4 0013FA50 |FileName = "C:\WINDOWS\system32\kernel32.dll"
0013F8A8 80000000 |Access = GENERIC_READ
0013F8AC 00000001 |ShareMode = FILE_SHARE_READ
0013F8B0 00000000 |pSecurity = NULL
0013F8B4 00000003 |Mode = OPEN_EXISTING
0013F8B8 00000080 |Attributes = NORMAL
0013F8BC 00000000 \hTemplateFile = NULL
F9
0013F8AC 00E63E24 /CALL 到 VirtualAlloc 来自 00E63E1E
0013F8B0 00000000 |Address = NULL
0013F8B4 0011D000 |Size = 11D000 (1167360.)
0013F8B8 00001000 |AllocationType = MEM_COMMIT
0013F8BC 00000040 \Protect = PAGE_EXECUTE_READWRITE
这个VirtualAlloc的出来的空间就是模拟的kernel32.dll
这里需要记录3个值
0013F8AC 00E63E24 /CALL 到 VirtualAlloc 来自 00E63E1E
0013F8B0 00000000 |Address = NULL
0013F8B4 0011D000 |Size = 11D000 (1167360.) 《==数据1,DLL的大小
0013F8B8 00001000 |AllocationType = MEM_COMMIT
0013F8BC 00000040 \Protect = PAGE_EXECUTE_READWRITE
0013F8C0 00000000
0013F8C4 00E84CB0
0013F8C8 004D0C16 zp_1_4.004D0C16
0013F8CC 0013F940
0013F8D0 00000000
0013F8D4 000000F8
0013F8D8 FFFFFFFF
0013F8DC 7C933288 返回到 ntdll.7C933288 来自 ntdll.7C92EE02
0013F8E0 7C9366F1 返回到 ntdll.7C9366F1 来自 ntdll.LdrUnlockLoaderLock
0013F8E4 00000001
0013F8E8 0AAC003F
0013F8EC 7C93657E 返回到 ntdll.7C93657E 来自 ntdll.7C92EE02
0013F8F0 00000000
0013F8F4 00000000
0013F8F8 00000002
0013F8FC 004C0045 zp_1_4.004C0045
0013F900 7C933281 返回到 ntdll.7C933281 来自 ntdll.RtlLeaveCriticalSection
0013F904 00000000
0013F908 00000000
0013F90C 02080000
0013F910 7C99CC20 ntdll.7C99CC20
0013F914 0000163F
0013F918 00905A4D
0013F91C 00000003
0013F920 00000004
0013F924 0000FFFF
0013F928 000000B8
0013F92C 00000000
0013F930 00000040
0013F934 00000000
0013F938 00000000
0013F93C 00000000
0013F940 00000000
0013F944 00000000
0013F948 00000000
0013F94C 00000000
0013F950 00000000
0013F954 000000E8
0013F958 00004550
0013F95C 0004014C
0013F960 46239C32
0013F964 00000000
0013F968 00000000
0013F96C 210E00E0
0013F970 0A07010B
0013F974 00082200
0013F978 00095400
0013F97C 00000000
0013F980 0000B5AE
0013F984 00001000
0013F988 0007F000
0013F98C 7C800000 kernel32.7C800000 〈==数据2,模拟的DLL地址
0013F990 00001000
0013F994 00000200
0013F998 00010005
0013F99C 00010005
0013F9A0 00000004
返回到用户代码
EAX 00EB0000 〈〈====数据3,模拟后的DLL地址
ECX 7C809AB9 kernel32.7C809AB9
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7C810B8E kernel32.SetFilePointer
ESP 0013F8C0
EBP 0013FE64
ESI 00000048
EDI 7C80180E kernel32.ReadFile
EIP 00E63E24
C 0 ES 0023 32位 0(FFFFFFFF)
P 1 CS 001B 32位 0(FFFFFFFF)
A 0 SS 0023 32位 0(FFFFFFFF)
Z 1 DS 0023 32位 0(FFFFFFFF)
S 0 FS 003B 32位 7FFDF000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000246 (NO,NB,E,BE,NS,PE,GE,LE)
ST0 empty -UNORM D0A8 01050104 00640079
ST1 empty 0.0
ST2 empty 0.0
ST3 empty 0.0
ST4 empty 0.0
ST5 empty 0.0
ST6 empty 1.0000000000000000000
ST7 empty 1.0000000000000000000
3 2 1 0 E S P U O Z D I
FST 4000 Cond 1 0 0 0 Err 0 0 0 0 0 0 0 0 (EQ)
FCW 027F Prec NEAR,53 掩码 1 1 1 1 1 1
F9 记录所有DLL的这3个数据 然后让程序停在OEP
修复IAT参考了Solid的方法。一共分3步。
第一步。找到 call xxxxxxxx nop和jmp xxxxxxxx nop这样的代码
通过查找加密后的IAT,把call xxxxxxxx nop改成call [xxxxxxxx的地址] 把jmp xxxxxxxx nop改成jmp [xxxxxxxx的地址]
关于查找IAT,在
00453D17 E8 441FFBFF call 00405C60回车
00405C6C E8 2BFFFFFF call 00405B9C 回车
00405B9C - FF25 E4714500 jmp dword ptr [4571E4] //4571e4就是IAT,这样可以得到IAT的start和end
而且,这个非常另类的函数就是GetModuleHandleA
004571E4 00E425D0 //把EIP设置到00E425D0单步走就可以看到他就是猥琐的GetModuleHandleA |
|