首页
社区
课程
招聘
WinUnpack 0.39 Final的分析和手动脱壳
发表于: 2008-1-23 18:22 6772

WinUnpack 0.39 Final的分析和手动脱壳

2008-1-23 18:22
6772
WinUnpack 0.39 Final的分析和手动脱壳

[分析]

压缩软件WinUnpack 0.39 Final的特点是:压缩率高,无保护功能。由于其压缩率比较高,被一些病毒程序编写者青睐;但正因为其无保护功能,所以相对来讲,比较好脱壳。程序的下载地址可至http://www.PEArmor.com
下面,我们以WinRAR.exe V3.71为对象进行分析。未压缩前的原文件表示为A,大小为915KB,压缩后的文件表示为B,大小为370KB。在下文中PA表示物理地址,RVA表示相对虚拟地址,AVA表示绝对虚拟地址,地址值均用十六进制表示。
WinUnpack对于文件头部的处理,显示出程序作者对于PE格式和windows装载机制深刻的理解。在此对程序作者表示敬意。

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
00000000   4D 5A 4B 45 52 4E 45 4C  33 32 2E 44 4C 4C 00 00   MZKERNEL32.DLL..
00000010   50 45 00 00 4C 01 03 00  BE B0 11 40 00 AD 50 FF   PE..L...景.@.璓
00000020   76 34 EB 7C 48 01 0F 01  0B 01 4C 6F 61 64 4C 69   v4雦H.....LoadLi
00000030   62 72 61 72 79 41 00 00  18 10 00 00 10 00 00 00   braryA..........
00000040   00 40 0A 00 00 00 40 00  00 10 00 00 00 02 00 00   .@....@.........
00000050   04 00 00 00 00 00 39 00  04 00 00 00 00 00 00 00   ......9.........
00000060   00 F0 18 00 00 02 00 00  00 00 00 00 02 00 00 00   .?.............
00000070   00 00 10 00 00 20 00 00  00 00 10 00 00 10 00 00   ..... ..........
00000080   00 00 00 00 0A 00 00 00  F1 61 18 00 5F 00 00 00   ........馻.._...
00000090   EE E1 18 00 14 00 00 00  00 A0 12 00 0A 5F 00 00   钺.......?.._..
000000A0   FF 76 38 AD 50 8B 3E BE  F0 E0 58 00 6A 27 59 F3   v8璓?攫郮.j'Y?
000000B0   A5 FF 76 04 83 C8 FF 8B  DF AB EB 1C 00 00 00 00   ?v.內嬤.....
000000C0   47 65 74 50 72 6F 63 41  64 64 72 65 73 73 00 00   GetProcAddress..
000000D0   D9 61 18 00 18 00 00 00  40 AB 40 B1 04 F3 AB C1   賏......@獲?螳?
000000E0   E0 0A B5 1C F3 AB 8B 7E  0C 57 51 E9 DB 51 18 00   ??螳媬.WQ檑Q..
000000F0   56 10 E2 E3 B1 04 D3 E0  03 E8 8D 53 18 33 C0 55   V.忏?余.鑽S.3繳
00000100   40 51 D3 E0 8B EA 91 FF  56 4C 99 59 D1 E8 13 D2   @Q余嬯?VL橸谚.?
00000110   E2 FA 5D 03 EA 45 59 89  6B 08 56 8B F7 2B F5 F3   恸].闑Y塳.V嬿+躞
00000120   A4 AC 5E B1 80 AA 3B 7E  34 0F 82 AC FE FF FF 58   が^眬?~4.偓?X
00000130   5F 59 E3 1B 8A 07 47 04  18 3C 02 73 F7 8B 07 3C   _Y??G..<.s鲖.<
00000140   11 75 F3 B0 00 0F C8 03  46 38 2B C7 AB E2 E5 5E   .u蟀..?F8+谦忮^
00000150   5D 59 46 AD 85 C0 74 1F  51 56 97 FF D1 93 AC 84   ]YF瓍纓.QV?褤瑒
00000160   C0 75 FB 38 06 74 EA 8B  C6 79 05 46 33 C0 66 AD   纔?.t陭苰.F3纅?
00000170   50 53 FF D5 AB EB E7 C3  00 90 12 00 00 10 00 00   PS斋腌??.....
00000180   F0 01 00 00 10 00 00 00  0A FF 52 00 83 62 58 00   ?.......R.僢X.
00000190   C6 51 00 00 60 00 00 E0  00 10 40 00 B8 62 58 00   芉..`..?.@.竍X.
000001A0   00 40 06 00 00 A0 12 00  E0 C3 05 00 00 02 00 00   .@...?.嗝......
000001B0   00 10 40 00 FF 7F 52 00  E0 63 58 00 60 00 00 E0   ..@.R.郼X.`..?
000001C0   9F 97 52 00 FC 0F 40 00  00 10 00 00 00 E0 18 00   煑R.?@......?.
000001D0   F0 01 00 00 10 00 00 00  50 62 58 00 53 62 58 00   ?......PbX.SbX.
000001E0   62 62 58 00 60 00 00 E0  28 00 00 00 BE 00 00 00   bbX.`..?...?..
000001F0   00 00 00 00 00 00 00 00  00 00 02 00 00 00 E8 11   ..............?
               图(1)B文件的前200个字节

在Windows下,DOS EXE Stub对于PE文件的执行并无用处,有意义的只限于两处:PA00-01处的标记e_magic和PA3c-3f处、指向NT头的指针e_lfanew。B中的e_lfanew指向位于PA0010处的IMAGE_NT_HEADER。这就是说,经winunpack压缩的程序,IMAGE_NT_HEADER覆盖在DOS EXE Stub上,已经不再可能在DOS下运行、打印出一个出错信息。
同理,IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER中有一些域对于程序的运行没有多大用处,可以另作它用。比如B中SizeOfCode, SizeOfInitializedData, SizeOfUninitializedData被用来存放函数字符串“LoadLibraryA”。
继续前行,0170-01E7处是三个节头,每一个节头占0x28个字节。

VA          Size                PA            Size
0x00001000  0x00129000          0x00000010    0x000001F0
0x0012A000  0x00064000          0x00000200    0x0005C3E0
0x0018E000  0x00001000          0x00000010    0x000001F0
图(2)
Windows在按照节头加载节时,会按照FileAlignment(B为200)和SectionAlignment(B为1000)将这些值进行调整。
RVA          Size                PA            Size
0x00001000  0x00129000          0x00000000    0x00000200
0x0012A000  0x00064000          0x00000200    0x0005C400
0x0018E000  0x00001000          0x00000000    0x00000200
图(3)
如果你在压缩时没有选择“清除输出表”,输出数据目录会和原程序A相同,没有更改。输入数据目录位于PA 0x01EE-0x01FF处,在文件中实际只有0x12个字节,还有两个字节在哪里?因为Windows加载时会用零初始化没有文件数据映射的内存,所以后两个字节值为0x0000,位于用零初始化的内存AVA 0x0018E200-0x0018E201。
00 00 00 00 00 00 00 00 00 00  00 00 02 00 00 00 E8 11
->
00 00 00 00 00 00 00 00 00 00  00 00 02 00 00 00 E8 11 00 00

总结一下,前200个字节的文件头。

0000 - 0001 e_magic
0002 - 000E 字符串"kernel32.dll"
0010 - 0013 IMAGE_NT_SIGANATURE
0014 - 0027 IMAGE_FILE_HEADER,有意义、可信的域有Machine(0x014C), NumberOfSections(03), SizeOfOptionalHeader(0x0148), Characteristics(0x010F)
    0018 - 0023 B的入口点

0028 - 016F IMAGE_OPTIONAL_HEADER,有意义、可信的域有Magic(0x010B), AddressOfEntryPoint(0x00001018), ImageBase(0x00400000), SectionAlignment(0x00001000), FileAlignment(0x00000200), MajorOperatingSystemVersion(0x0004), MinorOperatingSystemVersion(0x0000), MajorSubsystemVersion(0x0004), MinorSubsystemVersion(0x0000), Win32VersionValue(0x0000), SizeOfImage(随着程序大小的不同而变化), SizeOfHeaders(0x00000200), Subsystem
    002A - 0037 字符串"LoadLibraryA"

0170 - 01E7 三个节头
VA          Size          PA            Size
?           ?             0x00000010    0x000001F0
?           ?             0x00000200    SizeB-0x0200
?           ?             0x00000010    0x000001F0
注I.?表示可变量,其它量为固定值;II.SizeB表示B文件的大小

01E8 - 01F3 FirstThunk
01EE - 01FF 输入数据目录,有意义、可信的域有Name(0x0020), FirstThunk(0x11E8)
输入两个函数两个:kernel32!GetProcAddress, kernel32!LoadLibraryA

现在开始分析程序体,从入口点开始。解压缩部分大致分为:入栈,初始化,解压缩,修补Call调用,加载输入函数。
入口点处,先后入栈的三个数依次是:OEP, LoadLibraryA()指针, GetAddress()指针。
注意哦!OEP是最先入栈的。

PS______:00401018 mov     esi, offset OEP
PS______:0040101D lodsd
PS______:0040101E push    eax           ; OEP
PS______:0040101F push    dword ptr [esi+34h]     ; LoadLibraryA()指针
PS______:00401022 jmp     short loc_4010A0
PS______:004010A0 push    dword ptr [esi+38h]         ; GetAddress()指针

用0xFFFFFFFF, 0x00000000, 0x00000001初始化某些内存段,然后进入解压缩循环。下面是解压缩循环完成后的代码段。

00586415 loc_586415:         ; CODE XREF: start:loc_58631E j
00586415 stosb
00586416 cmp     edi, [esi+34h] ; [esi+34h]是解压缩循环结束时应该到达的地址
00586419 jb      loc_5862CB
; 解压缩循环结束处,修补call调用开始处
0058641F pop     eax          
00586420 pop     edi     ; 起址
00586421 pop     ecx     ; 修补的次数
00586422 jecxz   short loc_58643F
00586424
00586424 FixCall:            
00586424 mov     al, [edi]
00586426 inc     edi
00586427 add     al, 18h
00586429 cmp     al, 2
0058642B jnb     short FixCall
0058642D mov     eax, [edi]
0058642F cmp     al, 11h
00586431 jnz     short loc_586426
00586433 mov     al, 0
00586435 bswap   eax
00586437 add     eax, [esi+38h]
0058643A sub     eax, edi
0058643C stosd
0058643D loop    FixCall
; 修补Call调用结束,加载输入函数开始
0058643F pop     esi   ; esi 
00586440 pop     ebp     ; ebp  - GetProcAddress()函数指针出栈
00586441 pop     ecx   ; ecx  - LoadLibraryA()函数指针出栈
00586442 inc     esi
00586443 lodsd          ; eax - FirstThunk
00586444 test    eax, eax
00586446 jz      short locret_586467
00586448 push    ecx
00586449 push    esi     ; DLL Name
0058644A xchg    eax, edi ; edi - FirstThunk
0058644B call    ecx
0058644D xchg    eax, ebx ; ebx – DLL Handle
0058644E
0058644E loc_58644E:         ; CODE XREF: seg018:00586451 j seg018:00586465 j
0058644E lodsb
0058644F test    al, al
00586451 jnz     short loc_58644E
00586453 cmp     [esi], al
00586455 jz      short loc_586441
00586457 mov     eax, esi
00586459 jns     short loc_586460  
0058645B inc     esi       ; 以顺序号,不是以函数名引用DLL函数时
0058645C xor     eax, eax
0058645E lodsw
00586460
00586460 loc_586460:         ; CODE XREF: seg018:00586459 j
00586460 push    eax
00586461 push    ebx
00586462 call    ebp
00586464 stosd
00586465 jmp     short loc_58644E
00586467 retn           ; 返回OEP

[手工脱壳]

因为B是动态解压缩,所以不能直接在返回点处下断点,你可以在开头0x00401018下断点,然后在FixCall代码段之前下断点,返回处下断点。最后程序中断到此处0x00586467。转储:打开WinHex,起址为0x00400000,大小为0x0018F000,终址为0x0058EFFF,保存。
修复文件头。重建DOS EXE Stub,可以以下面的这个为模板。

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
00000000   4D 5A 90 00 03 00 00 00  04 00 00 00 FF FF 00 00   MZ?..........
00000010   B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00   ?......@.......
00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000030   00 00 00 00 00 00 00 00  00 00 00 00 88 00 00 00   ............?..
00000040   0E 1F BA 0E 00 B4 09 CD  21 B8 01 4C CD 21 54 68   ..?.???L?Th
00000050   69 73 20 70 72 6F 67 72  61 6D 20 63 61 6E 6E 6F   is program canno
00000060   74 20 62 65 20 72 75 6E  20 69 6E 20 44 4F 53 20   t be run in DOS 
00000070   6D 6F 64 65 2E 0D 0D 0A  24 00 00 00 00 00 00 00   mode....$.......
00000080   00 00 00 00 00 00 00 00  50 45 00 00 00 00 00 00   ........PE......

  依上图所示从PA 000088开始重建IMAGE_NT_HEADER,以B的文件头为模板,可信的域不变,不可信的域清零。IMAGE_OPTIONAL_HEADER中可信的域中需要修改的有:AddressOfEntryPoint设为0x401000(从B中获得的OEP),FileAlignment改成和SectionAlignment一样,SizeOfHeaders改为0x001000,其它多处不一一赘述。改完的文件头,如下图所示。

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
00000000   4D 5A 90 00 03 00 00 00  04 00 00 00 FF FF 00 00   MZ?..........
00000010   B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00   ?......@.......
00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000030   00 00 00 00 00 00 00 00  00 00 00 00 88 00 00 00   ............?..
00000040   0E 1F BA 0E 00 B4 09 CD  21 B8 01 4C CD 21 54 68   ..?.???L?Th
00000050   69 73 20 70 72 6F 67 72  61 6D 20 63 61 6E 6E 6F   is program canno
00000060   74 20 62 65 20 72 75 6E  20 69 6E 20 44 4F 53 20   t be run in DOS 
00000070   6D 6F 64 65 2E 0D 0D 0A  24 00 00 00 00 00 00 00   mode....$.......
00000080   00 00 00 00 00 00 00 00  50 45 00 00 4C 01 03 00   ........PE..L...
00000090   00 00 00 00 00 00 00 00  00 00 00 00 48 01 0F 01   ............H...
000000A0   0B 01 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000B0   00 10 00 00 00 00 00 00  00 00 00 00 00 00 40 00   ..............@.
000000C0   00 10 00 00 00 10 00 00  04 00 00 00 00 00 00 00   ................
000000D0   04 00 00 00 00 00 00 00  00 30 19 00 00 10 00 00   .........0......
000000E0   00 00 00 00 02 00 00 00  00 00 10 00 00 20 00 00   ............. ..
000000F0   00 00 10 00 00 10 00 00  00 00 00 00 0A 00 00 00   ................
00000100   F1 61 18 00 5F 00 00 00  00 E0 18 00 00 50 00 00   馻.._....?..P..
00000110   00 A0 12 00 0A 5F 00 00  00 00 00 00 00 00 00 00   .?.._..........
00000120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000130   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000140   00 00 00 00 00 00 00 00  D9 61 18 00 18 00 00 00   ........賏......
00000150   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000160   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000170   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000180   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000190   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001E0   00 00 00 00 00 00 00 00  31 00 00 00 00 00 00 00   ........1.......
000001F0   00 90 12 00 00 10 00 00  00 90 12 00 00 10 00 00   .?......?.....
00000200   00 00 00 00 00 00 00 00  00 00 00 00 60 00 00 E0   ............`..?
00000210   32 00 00 00 00 00 00 00  00 40 06 00 00 A0 12 00   2........@...?.
00000220   00 40 06 00 00 A0 12 00  00 00 00 00 00 00 00 00   .@...?.........
00000230   00 00 00 00 60 00 00 E0  33 00 00 00 00 00 00 00   ....`..?.......
00000240   00 50 00 00 00 E0 18 00  00 50 00 00 00 E0 18 00   .P...?..P...?.
00000250   00 00 00 00 00 00 00 00  00 00 00 00 60 00 00 E0   ............`..?
00000260   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

输出目录和资源目录,winunpack在压缩时都没有改动。为了方便修改输入目录,我将最后一个节由1000扩大为5000,空间足够了。下图是完整的输入目录

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
0018E000   00 00 00 00 00 00 00 00  00 00 00 00 00 E6 18 00   .............?.
0018E010   04 21 0F 00 00 00 00 00  00 00 00 00 00 00 00 00   .!..............
0018E020   80 E8 18 00 D8 23 0F 00  00 00 00 00 00 00 00 00   €?.?..........
0018E030   00 00 00 00 A0 FC 18 00  88 26 0F 00 00 00 00 00   ....狘..?......
0018E040   00 00 00 00 00 00 00 00  00 FE 18 00 CC 26 0F 00   .........?.?..
0018E050   00 00 00 00 00 00 00 00  00 00 00 00 C0 FE 18 00   ............俐..
0018E060   64 27 0F 00 00 00 00 00  00 00 00 00 00 00 00 00   d'..............
0018E070   C0 02 19 00 2C 28 0F 00  00 00 00 00 00 00 00 00   ?..,(..........
0018E080   00 00 00 00 00 05 19 00  D4 2A 0F 00 00 00 00 00   ........?......
0018E090   00 00 00 00 00 00 00 00  00 18 19 00 4C 2D 0F 00   ............L-..
0018E0A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................


    下图是部分advapi32.dll的函数名字表。
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

0018E600   41 44 56 41 50 49 33 32  2E 44 4C 4C 00 00 00 00   ADVAPI32.DLL....
0018E610   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
0018E620   00 00 41 64 6A 75 73 74  54 6F 6B 65 6E 50 72 69   ..AdjustTokenPri
0018E630   76 69 6C 65 67 65 73 00  00 00 00 00 00 00 00 00   vileges.........
0018E640   00 00 47 65 74 46 69 6C  65 53 65 63 75 72 69 74   ..GetFileSecurit
0018E650   79 41 00 00 00 00 00 00  00 00 00 00 00 00 00 00   yA..............
0018E660   00 00 47 65 74 46 69 6C  65 53 65 63 75 72 69 74   ..GetFileSecurit
0018E670   79 57 00 00 00 00 00 00  00 00 00 00 00 00 00 00   yW..............
0018E680   00 00 47 65 74 53 65 63  75 72 69 74 79 44 65 73   ..GetSecurityDes
0018E690   63 72 69 70 74 6F 72 4C  65 6E 67 74 68 00 00 00   criptorLength...
0018E6A0   00 00 4C 6F 6F 6B 75 70  50 72 69 76 69 6C 65 67   ..LookupPrivileg
0018E6B0   65 56 61 6C 75 65 41 00  00 00 00 00 00 00 00 00   eValueA.........

在修复完数据目录后,程序便可以正常运行了。不想弄些什么按多少多少次到哪里,知道了程序里代码段都是干什么的,自然知道断点在哪里下。

Enjoy it. By TNTTOOLS

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
2
纯粹鼓励,,,,,,,

我觉得LZ应该往更高的层次发展了,,,,,

例如指出壳用了什么压缩/加密算法,,,,

BUT,,,,人到了一定水平就会变懒,,,,至少我是这样,,,,
2008-1-23 18:47
0
雪    币: 297
活跃值: (27)
能力值: ( LV13,RANK:380 )
在线值:
发帖
回帖
粉丝
3
WinUpack v3.9 Final的主程序也是用的这样的压缩方法。今天花了一点时间又将其主程序搞定。贴图留个纪念。向作者Dwing表示敬意。注意图中的主窗口的标题被我改了。
“tnttools到此一游”,纯粹搞笑。
上传的附件:
2008-1-23 23:56
0
游客
登录 | 注册 方可回帖
返回
//