当前位置: 首页 > article >正文

《Windows PE》17.3 FSG壳

回顾第十六章PE病毒的16.2.2病毒分析案例一中,我们分析的病毒样本Lab01-03.exe使用了FSG壳。本节我们就来详细分析FSG壳。

本节必须掌握的知识点:

    静态分析

        手工脱壳

17.3.1 静态分析

       ■FSG壳的特点

FSG壳是一种经典的加壳工具,主要用于对可执行文件进行压缩和加密处理。下面是FSG壳的一些特点和工作原理:

●压缩功能:FSG壳使用定制的高效压缩算法对可执行文件进行压缩,从而减小文件大小。压缩后的文件会包含解压缩代码和数据,以便在运行时还原原始的可执行文件。

●加密保护:除了压缩,FSG壳还会对可执行文件进行加密处理,以增强文件的安全性。加密可以防止未经授权的访问和修改,保护程序的知识产权和机密性。

●运行时解压缩:在程序运行时,FSG壳会先解密和解压缩原始的可执行文件,然后将其加载到内存中执行。这种运行时解压缩的方式有助于保护程序的代码和数据不被恶意篡改或窥探。

●反调试和反分析:FSG壳通常包含反调试和反分析技术,用于防止调试器和逆向工程工具的使用。这些技术可以增加对程序的保护,使其更难以被破解和篡改。

●资源优化:通过压缩和加密处理,FSG壳可以帮助优化程序的资源占用和加载速度,提高程序的运行效率和用户体验。

实验一百一十五:FSG壳静态分析

让我们使用WinHex工具对FSG壳做静态分析,对比加壳前后的变化。

       ■静态分析

       分析环境:VMWare16.2.1,Windows XP系统。

       分析样本:

原程序HelloWorld.exe;

加壳程序HelloWorld_fsg.exe;

脱壳程序HelloWorld_unfsg.exe;

【注】样本程序不支持Windows 64位系统。

       ●加壳前

       将原程序HelloWorld.exe拖入WinHex,PE头信息如下:

000000B0   50 45 00 00 4C 01 03 00  8C 10 A7 60 00 00 00 00   PE..L...?....

000000C0   00 00 00 00 E0 00 0F 01  0B 01 05 0C 00 02 00 00   ....?..........

000000D0   00 04 00 00 00 00 00 00  00 10 00 00 00 10 00 00   ................

000000E0   00 20 00 00 00 00 40 00  00 10 00 00 00 02 00 00   . ....@.........

000000F0   04 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00   ................

00000100   00 40 00 00 00 04 00 00  00 00 00 00 02 00 00 00   .@..............

00000110   00 00 10 00 00 10 00 00  00 00 10 00 00 10 00 00   ................

00000120   00 00 00 00 10 00 00 00  00 00 00 00 00 00 00 00   ................

00000130   10 20 00 00 3C 00 00 00  00 00 00 00 00 00 00 00   . ..<...........

00000140   00 00 00 00 00 00 00 00  00 00 00 00 00 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 20 00 00 10 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  2E 74 65 78 74 00 00 00   .........text...

000001B0   24 00 00 00 00 10 00 00  00 02 00 00 00 04 00 00   $...............

000001C0   00 00 00 00 00 00 00 00  00 00 00 00 20 00 00 60   ............ ..`

000001D0   2E 72 64 61 74 61 00 00  92 00 00 00 00 20 00 00   .rdata..?... ..

000001E0   00 02 00 00 00 06 00 00  00 00 00 00 00 00 00 00   ................

000001F0   00 00 00 00 40 00 00 40  2E 64 61 74 61 00 00 00   ....@..@.data...

00000200   0D 00 00 00 00 30 00 00  00 02 00 00 00 08 00 00   .....0..........

00000210   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 C0   ............@..

       1.NumberOfSections:节区数3;

       2.AddressOfEntryPoint:程序入口地址0x1000;

       3.BaseOfCode:代码节起始地址0x1000;

       4.BaseOfData:数据节起始地址0x2000;

       5.ImageBase:程序建议装载基址0x4000;

       6.SectionAlignment:内存对齐颗粒度0x1000;

       7.FileAlignment:文件对齐颗粒度0x200;

       8.SizeOflmage:映像文件大小0x4000;

       9.导入表RAV地址:0x2010;

       10.函数地址表RVA地址:0x2000;

       11.3个节区:

.text

00000400   6A 00 6A 00 68 00 30 40  00 6A 00 E8 08 00 00 00   j.j.h.0@.j.?...

00000410   6A 00 E8 07 00 00 00 CC  FF 25 08 20 40 00 FF 25   j.?...?%. @.%

00000420   00 20 40 00 00 00 00 00  00 00 00 00 00 00 00 00   . @.............

.rdata

00000600   76 20 00 00 00 00 00 00  5C 20 00 00 00 00 00 00   v ......\ ......

00000610   54 20 00 00 00 00 00 00  00 00 00 00 6A 20 00 00   T ..........j ..

00000620   08 20 00 00 4C 20 00 00  00 00 00 00 00 00 00 00   . ..L ..........

00000630   84 20 00 00 00 20 00 00  00 00 00 00 00 00 00 00   ?... ..........

00000640   00 00 00 00 00 00 00 00  00 00 00 00 76 20 00 00   ............v ..

00000650   00 00 00 00 5C 20 00 00  00 00 00 00 B1 01 4D 65   ....\ ......?Me

00000660   73 73 61 67 65 42 6F 78  41 00 75 73 65 72 33 32   ssageBoxA.user32

00000670   2E 64 6C 6C 00 00 9B 00  45 78 69 74 50 72 6F 63   .dll..?ExitProc

00000680   65 73 73 00 6B 65 72 6E  65 6C 33 32 2E 64 6C 6C   ess.kernel32.dll

.data;

       00000800   48 65 6C 6C 6F 57 6F 72  6C 64 50 45 00 00 00 00   HelloWorldPE....

       ●加壳后

       将加壳程序HelloWorld_fsg.exe拖入WinHex,PE头信息如下:

       00000000   4D 5A 00 00 00 00 00 00  00 00 00 00 50 45 00 00   MZ..........PE..

00000010   4C 01 02 00 46 53 47 21  00 00 00 00 00 00 00 00   L...FSG!........

00000020   E0 00 0F 01 0B 01 00 00  00 02 00 00 00 04 00 00   ?..............

00000030   00 00 00 00 54 01 00 00  00 10 00 00 0C 00 00 00   ....T...........

00000040   00 00 40 00 00 10 00 00  00 02 00 00 04 00 00 00   ..@.............

00000050   00 00 00 00 04 00 00 00  00 00 00 00 00 60 00 00   .............`..

00000060   00 02 00 00 00 00 00 00  02 00 00 00 00 00 10 00   ................

00000070   00 10 00 00 00 00 10 00  00 10 00 00 00 00 00 00   ................

00000080   10 00 00 00 00 00 00 00  00 00 00 00 7C 50 00 00   ............|P..

00000090   84 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ?..............

000000A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00000100   00 00 00 00 00 00 00 00  00 00 00 00 00 40 00 00   .............@..

00000110   00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00000120   00 00 00 00 00 00 00 00  E0 00 00 C0 00 00 00 00   ........?.?...

00000130   00 00 00 00 00 10 00 00  00 50 00 00 FD 00 00 00   .........P..?..

00000140   00 02 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

       00000150   E0 00 00 C0                                        ?.

       1.NumberOfSections:节区数2;

       2.AddressOfEntryPoint:程序入口地址0x154;

       3.BaseOfCode:代码节起始地址0x1000;

       4.BaseOfData:数据节起始地址0x0C;

       5.ImageBase:程序建议装载基址0x40000;

       6.SectionAlignment:内存对齐颗粒度0x1000;

       7.FileAlignment:文件对齐颗粒度0x200;

       8.SizeOflmage:映像文件大小0x6000;

       9.导入表RAV地址:0x507C;

       10.函数地址表RVA地址:无;

       11.2个节区

       第一个节区:节区名(无),节区大小0x4000,内存RVA地址0x1000,文件对齐后大小0,文件起始地址0,节区属性0xC00000E0;

       程序的入口地址0x154位于第一个节区,因此可以判断此节区为代码段。如下所示:

00000150                      87 25 C0 50  40 00 61 94 55 A4 B6 80       ?繮@.a擴ざ€

00000160   FF 13 73 F9 33 C9 FF 13  73 16 33 C0 FF 13 73 1F   .s??.s.3?.s.

00000170   B6 80 41 B0 10 FF 13 12  C0 73 FA 75 3A AA EB E0   秬A?..纒鷘:?

00000180   FF 53 08 02 F6 83 D9 01  75 0E FF 53 04 EB 24 AC   S..鰞?u.S.??

00000190   D1 E8 74 2D 13 C9 EB 18  91 48 C1 E0 08 AC FF 53   谚t-.呻.慔拎.?S

000001A0   04 3B 43 F8 73 0A 80 FC  05 73 06 83 F8 7F 77 02   .;C鴖.€?s.凐w.

000001B0   41 41 95 8B C5 B6 00 56  8B F7 2B F0 F3 A4 5E EB   AA晪哦.V嬿+痼?

000001C0   9F 5E AD 97 AD 50 FF 53  10 95 8B 07 40 78 F3 75   焇瓧璓S.晪.@x髐

000001D0   03 FF 63 0C 50 55 FF 53  14 AB EB EE 33 C9 41 FF   .c.PUS.?葾

000001E0   13 13 C9 FF 13 72 F8 C3  02 D2 75 05 8A 16 46 12   ..?.r.襲.?F.

000001F0   D2 C3 4B 45 52 4E 45 4C  33 32 2E 64 6C 6C 00 00   颐KERNEL32.dll..

第二个节区:节区名(无),节区大小0x1000,内存RVA地址0x5000,文件对齐后大小0xFD,文件起始地址0x200,节区属性0xC00000E0;

导入表RVA地址0x507C,位于第二个节区,偏移0x7C,因此导入表在文件内的地址0x27C:

00000270                                           D4 50 00 00               訮..

00000280   00 00 00 00 00 00 00 00  F2 01 00 00 D4 50 00 00   ........?..訮..

00000290   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000002A0   00 00 00 00 00 10 40 00  00 50 40 00 10 20 40 00   ......@..P@.. @.

000002B0   00 00 00 00 C4 50 40 00  80 00 00 00 00 7D 00 00   ....腜@.€....}..

000002C0   A4 50 40 00 E8 01 40 00  DC 01 40 00 DE 01 40 00   @.?@.?@.?@.

000002D0   00 10 40 00 DE 50 00 00  EC 50 00 00 00 00 00 00   ..@.轕..霵......

000002E0   4C 6F 61 64 4C 69 62 72  61 72 79 41 00 00 47 65   LoadLibraryA..Ge

000002F0   74 50 72 6F 63 41 64 64  72 65 73 73 00            tProcAddress.

第二个节区0x200~0x27B之间的数据,暂时不太清楚是什么?

00000200   6A E1 9C 04 68 0C 30 40  0F E8 70 08 E1 08 07 88   j釡.h.0@.鑠.?.?

00000210   CC FF 7E 25 6D 20 2A 0C  C2 28 01 FF DF 71 77 2E   ?~%m *.?.遯w.

00000220   59 E6 03 5D 48 08 7F 44  08 6A DC 09 22 4B 84 98   Y?]H.D.j?"K剺

00000230   FC 4C F9 5B 5E E0 4D 65  73 E2 61 75 67 0E 42 6F   麹鵞^郙es鈇ug.Bo

00000240   78 41 0F 75 7F 40 72 33  32 2E 64 6C E3 40 1A 45   xA.u@r32.dl鉆.E

00000250   78 69 06 74 50 72 6F 63  43 E0 6B CF 32 6E 0A 6C   xi.tProcC鄈?n.l

00000260   1C 52 3F 01 7D DC 1C 48  65 6C 4E 6F 57 4E 72 C3   .R?.}?HelNoWNr?

00000270   64 50 45 84 7F FE BD 80  00 00 00 00               dPE?€....

【注意】在加壳程序的0x14地址处有FSG壳标志字符串“FSG!”。

       ●脱壳后

使用FSG脱壳工具Unpacker对加壳程序HelloWorld_fsg.exe进行脱壳处理。

图17-2 FSG脱壳

然后将脱壳后的程序HelloWorld_unfsg.exe拖入WinHex,PE头信息如下:    

00000000   4D 5A 00 00 00 00 00 00  00 00 00 00 50 45 00 00   MZ..........PE..

00000010   4C 01 03 00 46 53 47 21  00 00 00 00 00 00 00 00   L...FSG!........

00000020   E0 00 0F 01 0B 01 00 00  00 02 00 00 00 04 00 00   ?..............

00000030   00 00 00 00 00 10 00 00  00 10 00 00 0C 00 00 00   ................

00000040   00 00 40 00 00 10 00 00  00 10 00 00 04 00 00 00   ..@.............

00000050   00 00 00 00 04 00 00 00  00 00 00 00 00 70 00 00   .............p..

00000060   00 02 00 00 00 00 00 00  02 00 00 00 00 00 10 00   ................

00000070   00 10 00 00 00 00 10 00  00 10 00 00 00 00 00 00   ................

00000080   10 00 00 00 00 00 00 00  00 00 00 00 00 60 00 00   .............`..

00000090   84 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ?..............

000000A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00000100   00 00 00 00 2E 52 49 46  31 00 00 00 00 40 00 00   .....RIF1....@..

00000110   00 10 00 00 00 40 00 00  00 10 00 00 00 00 00 00   .....@..........

00000120   00 00 00 00 00 00 00 00  E0 00 00 C0 2E 52 49 46   ........?.?RIF

00000130   32 00 00 00 00 10 00 00  00 50 00 00 00 10 00 00   2........P......

00000140   00 50 00 00 00 00 00 00  00 00 00 00 00 00 00 00   .P..............

00000150   E0 00 00 C0 2E 52 49 46  00 00 61 94 00 10 00 00   ?.?RIF..a?...

00000160   00 60 00 00 00 10 00 00  00 60 00 00 FF 13 73 1F   .`.......`...s.

00000170   B6 80 41 B0 10 FF 13 12  20 00 00 E0               秬A?.. ..?    

       对比脱壳前的变化:

  1. 节区数量变为3个;
  2. 程序入口地址变为0x1000;
  3. 映像文件大小变为:0x7000;
  4. 导入表RVA地址变为:0x6000;

5.3个节区分别为:

RIF1:节区大小0x4000,内存RVA地址0x1000,文件对齐大小0x4000,文件起始地址0x1000,节区属性0xC00000E0。

00001000   6A 00 6A 00 68 00 30 40  00 6A 00 E8 08 00 00 00   j.j.h.0@.j.?...

00001010   6A 00 E8 07 00 00 00 CC  FF 25 08 20 40 00 FF 25   j.?...?%. @.%

00001020   00 20 40 00 00 00 00 00  00 00 00 00 00 00 00 00   . @.............

【注】对应原程序HelloWorld.exe的.text节区。

00002000   76 20 00 00 00 00 00 00  5C 20 00 00 00 00 00 00   v ......\ ......

00002010   08 20 40 00 6A 20 40 00  00 20 40 00 84 20 40 00   . @.j @.. @.?@.

00002020   00 00 00 00 4C 20 00 00  00 00 00 00 00 00 00 00   ....L ..........

00002030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 4D 65   ..............Me

00002060   73 73 61 67 65 42 6F 78  41 00 75 73 65 72 33 32   ssageBoxA.user32

00002070   2E 64 6C 6C 00 00 00 00  45 78 69 74 50 72 6F 63   .dll....ExitProc

00002080   65 73 73 00 6B 65 72 6E  65 6C 33 32 2E 64 6C 6C   ess.kernel32.dll

【注】对应原程序HelloWorld.exe的.rdata节区。

00003000   48 65 6C 6C 6F 57 6F 72  6C 64 50 45 00 00 00 00   HelloWorldPE....

【注】对应原程序HelloWorld.exe的.data节区。

RIF2:节区大小0x1000,内存RVA地址0x5000,文件对齐大小0x1000,文件起始地址0x5000,节区属性0xC00000E0。

00005000   6A E1 9C 04 68 0C 30 40  0F E8 70 08 E1 08 07 88   j釡.h.0@.鑠.?.?

00005010   CC FF 7E 25 6D 20 2A 0C  C2 28 01 FF DF 71 77 2E   ?~%m *.?.遯w.

00005020   59 E6 03 5D 48 08 7F 44  08 6A DC 09 22 4B 84 98   Y?]H..D.j?"K剺

00005030   FC 4C F9 5B 5E E0 4D 65  73 E2 61 75 67 0E 42 6F   麹鵞^郙es鈇ug.Bo

00005040   78 41 0F 75 7F 40 72 33  32 2E 64 6C E3 40 1A 45   xA.u.@r32.dl鉆.E

00005050   78 69 06 74 50 72 6F 63  43 E0 6B CF 32 6E 0A 6C   xi.tProcC鄈?n.l

00005060   1C 52 3F 01 7D DC 1C 48  65 6C 4E 6F 57 4E 72 C3   .R?.}?HelNoWNr?

00005070   64 50 45 84 7F FE BD 80  00 00 00 00 D4 50 00 00   dPE?€....訮..

00005080   00 00 00 00 00 00 00 00  F2 01 00 00 D4 50 00 00   ........?..訮..

00005090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000050A0   00 00 00 00 00 10 40 00  00 50 40 00 10 20 40 00   ......@..P@.. @.

000050B0   00 00 00 00 C4 50 40 00  80 00 00 00 00 7D 00 00   ....腜@.€....}..

000050C0   C4 FF 13 00 E8 01 40 00  DC 01 40 00 DE 01 40 00   ?..?@.?@.?@.

000050D0   00 10 40 00 7B 1D 80 7C  40 AE 80 7C 00 00 00 00   ..@.{.€|@畝|....

000050E0   4C 6F 61 64 4C 69 62 72  61 72 79 41 00 00 47 65   LoadLibraryA..Ge

000050F0   74 50 72 6F 63 41 64 64  72 65 73 73 00 00 00 00   tProcAddress....

【注】对应加壳程序HelloWorld_fsg.exe的第二个节区,包含导入表。

RIF:节区大小0x1000,内存RVA地址0x6000,文件对齐大小0x1000,文件起始地址0x6000,节区属性0xC0000020。

00006000   08 20 00 00 00 00 00 00  00 00 00 00 6A 20 00 00   . ..........j ..

00006010   08 20 00 00 00 20 00 00  00 00 00 00 00 00 00 00   . ... ..........

00006020   84 20 00 00 00 20 00 00  00 00 00 00 00 00 00 00   ?... ..........

【注】对应原程序HelloWorld.exe的函数地址表。

  总结

       通过对原程序、加壳程序和脱壳程序的静态分析,我们可以得出以下结论:

       ●加壳过程:

       1.NumberOfSections:节区数2;——修改了节区数量。

       2.AddressOfEntryPoint:程序入口地址0x154;——修改了程序入口地址,从壳代码开始执行。

       3.BaseOfCode:代码节起始地址0x1000;——未改变。

       4.BaseOfData:数据节起始地址0x0C;——修改了数据节起始地址,对PE头进行了压缩,这也造成了Windows 64位系统下无法执行。

       5.ImageBase:程序建议装载基址0x40000;——未改变。

       6.SectionAlignment:内存对齐颗粒度0x1000;——未改变。

       7.FileAlignment:文件对齐颗粒度0x200;——未改变。

       8.SizeOflmage:映像文件大小0x6000;——由0x4000改为0x6000

       9.导入表RAV地址:0x507C;——导入表RVA地址由0x2010改为0x507C

       10.函数地址表RVA地址:无;——函数地址表RAV地址有0x2000改为0

       11.2个节区

       第一个节区:节区名(无),节区大小0x4000,内存RVA地址0x1000,文件对齐后大小0,文件起始地址0,节区属性0xC00000E0;

       程序的入口地址0x154位于第一个节区,因此可以判断此节区为代码段。

第二个节区:节区名(无),节区大小0x1000,内存RVA地址0x5000,文件对齐后大小0xFD,文件起始地址0x200,节区属性0xC00000E0;

导入表RVA地址0x507C,位于第二个节区,偏移0x7C,因此导入表在文件内的地址0x27C

第二个节区0x200~0x27B之间的数据,暂时不太清楚是什么?

详见下面的手工脱壳讲解。

       ●脱壳过程:

       对比脱壳前的变化:

  1. 节区数量变为3个;——用户还原原程序的3个节区。
  2. 程序入口地址变为0x1000;——修改为原程序的入口地址。
  3. 映像文件大小变为:0x7000;——增加两个节区,分别保存导入表和函数地址表。
  4. 导入表RVA地址变为:0x6000;——导入表单独解析,存入RIF2节区。

5.3个节区分别为:

RIF1:节区大小0x4000,内存RVA地址0x1000,文件对齐大小0x4000,文件起始地址0x1000,节区属性0xC00000E0。

【注】存储原程序HelloWorld.exe的.text节区。

【注】存储原程序HelloWorld.exe的.rdata节区。

【注】存储原程序HelloWorld.exe的.data节区。

RIF2:节区大小0x1000,内存RVA地址0x5000,文件对齐大小0x1000,文件起始地址0x5000,节区属性0xC00000E0。

【注】存储加壳程序HelloWorld_fsg.exe的第二个节区,包含导入表。

RIF:节区大小0x1000,内存RVA地址0x6000,文件对齐大小0x1000,文件起始地址0x6000,节区属性0xC0000020。

【注】存储原程序HelloWorld.exe的函数地址表。      

17.3.2 手工脱壳

不同的壳程序通常都会有一个对应的脱壳工具。但是多数情况下,必须进行手动脱壳。手动脱壳有时候很快,且不费精力。有时候却是一件费事且艰巨的过程。

手动脱壳方法

手动脱壳程序的方法有两种:

●找到加壳的算法,然后编写一个程序逆向运行它。通过逆向运行这个算法,这个程序可以解开加壳程序的每一步操作。虽然有一些自动化的工具可以完成这些工作,但是这种方法效率很低,因为编写的脱壳程序仅针对单个的加壳程序。所以,即使辅以自动化,这个过程依然需要大量的时间来完成。

●运行脱壳程序,让脱壳存根帮你工作,让它从内存中转储出进程,然后你再手动修正PE头部,保持程序的完整。这是一种非常有效的方法。

接下来我们使用第二种方法解析下面的两个加壳程序。

实验一百一十六:FSG壳动态分析

让我们借助OllyDbg调试器调试跟踪加壳程序HelloWorld_fsg.exe,找到程序的OEP原程序入口地址。

       ■调试跟踪加壳程序HelloWorld_fsg.exe

       将加壳程序HelloWorld_fsg.exe拖入OllyDbg调试器。从入口地址0x00400154开始按F8单步执行(期间可以使用F4跟随断点跳过循环,加快调试进程),直到跟踪到0x004001D1地址处,如下图所示:

图17-3 单步跟踪加壳程序到关键跳转语句

       在0x004001D1地址处,按F8单步执行,跳转到原程序入口地址0x00401000。如图17-4所示。点击鼠标右键“分析”->“分析代码”就可以正确显示反汇编代码了。

       此时,打开内存映像窗口,可以看到,加壳程序除了PE头之外,包含两个节区。第一个节区为代码段,第二个节区为输入表。双击代码段节区,数据窗口显示原程序的代码段。

此时,再双击第二个节区,打开数据窗口,如图17-5所示。和之前我们静态分析PE文件中第二个节区数据没有任何变化。说明这里的数据是只读数据,应该是在加壳时需要用到的额外数据。

图17-4 跳转到原程序入口地址

图17-5 查看加壳程序第二个节区数据

  总结

       如果需要动态调试加壳程序,关键是找到跳转原程序入口地址的JMP指令,剩下的事情和调试未加壳程序是一样的。动态调试的过程和静态分析是相互印证的过程。

       此外,FSG加壳程序的PE头都会带有FSG壳的标识字符串“FSG!”,可以作为判断依据。

       ■手工脱壳

实验一百一十七:HelloWorld_fsg.exe手工脱壳

让我们借助OllyDbg调试器、LordPE、ImpotREC工具实现加壳程序HelloWorld_fsg.exe手工脱壳。

       ●HelloWorld_fsg.exe

       第一步:使用OllyDbg调试器单步跟踪,跳转到原程序的入口地址(OEP)。

      

                                          图17-6 跳转程序入口地址

       第二步:使用OllyDbg插件OllyDump进行程序的脱壳操作。点击鼠标右键“用OllyDump脱壳调试进程”,弹出如下对话框窗口。

图17-7 dump脱壳程序

       注意检查“起始地址”、“入口点地址”是否正确,不要勾选“重建输入表”选项,等待稍后修复输入表。点击“脱壳”选项,保存为OllyDump_HelloWorld.exe。

       还可以使用LordPE工具dump脱壳文件。打开LordPE,选择当前正在调试的进程HelloWorld_fsg.exe,如下图所示:

图17-8 使用LordPE dump脱壳文件

       点击鼠标右键“完全脱壳”,保存脱壳文件为dumped_HelloWorld.exe。使用LordPE工具dump下来的脱壳文件和使用OllyDump插件几乎完全一样。

       第三步:修复输入表。如果使用纯手工修复是可以的。但是如果导入函数很多,可以借助于ImportREC工具修复导入表和IAT表。

       打开ImportREC工具,附加当前调试的加壳程序HelloWorld_fsg.exe,如图17-9所示。

       输入程序的OEP入口RVA地址00001000,然后点击自动查找,发现提示“在此OEP没有找到任何有用的信息!”。如果没有找到IAT信息,则要手动填入IAT的RVA和大小。

      

                                                 图17-9 自动查找IAT

使用WinHex打开dump文件OllyDump_HelloWorld.exe,我们会发现在文件偏移00002000H地址处有导入表和IAT表信息,如下所示:

      

00002000   A2 BF 81 7C FF FF FF FF  EA 07 D5 77 FF FF FF 7F   ⒖亅?誻

00002010   08 20 40 00 6A 20 40 00  00 20 40 00 84 20 40 00   . @.j @.. @.?@.

00002020   00 00 00 00 4C 20 00 00  00 00 00 00 00 00 00 00   ....L ..........

00002030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 4D 65   ..............Me

00002060   73 73 61 67 65 42 6F 78  41 00 75 73 65 72 33 32   ssageBoxA.user32

00002070   2E 64 6C 6C 00 00 00 00  45 78 69 74 50 72 6F 63   .dll....ExitProc

00002080   65 73 73 00 6B 65 72 6E  65 6C 33 32 2E 64 6C 6C   ess.kernel32.dll

00002090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

         此时,查看调试器中的内存窗口地址0x00402000,如下图所示:

                                                        图17-10 查看OllyDbg调试器IAT表

       内存地址0x00402000处存储的就是内存中的IAT表。我们据此修复PE文件内的IAT表就可以了。

       因此,我们将OEP下方的“RVA”栏填写为:00002000,“大小”栏填写00001000。然后点击获取输入表。

图17-11 获取输入表

查看左侧窗口显示的导入函数,其中有些是无效的,点击“显示无效的”按钮,筛选出无效的导入函数,如图所示:

图17-12 筛选无效导入函数

然后在输入表函数栏点击鼠标右键“剪切指针”,删除无效导入函数。如下图所示:

图17-13 删除无效函数

      

       最后点击左侧按钮“修复转储文件”,选择需要转存的dump文件,保存修复后的文件unpack_HelloWorld.exe。

第四步:运行修复后的文件,成功!对比修复后的变化。

将修复之后保存的文件unpack_HelloWorld.exe拖入WinHex:

       节区二:

00002000   4A 60 00 00 00 00 00 00  64 60 00 00 00 00 00 00   J`......d`......

00002010   08 20 40 00 6A 20 40 00  00 20 40 00 84 20 40 00   . @.j @.. @.?@.

00002020   00 00 00 00 4C 20 00 00  00 00 00 00 00 00 00 00   ....L ..........

00002030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00002050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 4D 65   ..............Me

00002060   73 73 61 67 65 42 6F 78  41 00 75 73 65 72 33 32   ssageBoxA.user32

00002070   2E 64 6C 6C 00 00 00 00  45 78 69 74 50 72 6F 63   .dll....ExitProc

00002080   65 73 73 00 6B 65 72 6E  65 6C 33 32 2E 64 6C 6C   ess.kernel32.dll

4A 60 00 00 00 00 00 00  64 60 00 00 00 00 00 00为修复后的IAT表,对应节区三种中的函数导入表。

节区三:

00006000   00 00 00 00 00 00 00 00  00 00 00 00 3C 60 00 00   ............<`..

00006010   00 20 00 00 00 00 00 00  00 00 00 00 00 00 00 00   . ..............

00006020   58 60 00 00 08 20 00 00  00 00 00 00 00 00 00 00   X`... ..........

00006030   00 00 00 00 00 00 00 00  00 00 00 00 6B 65 72 6E   ............kern

00006040   65 6C 33 32 2E 64 6C 6C  00 00 B7 00 45 78 69 74   el32.dll..?Exit

00006050   50 72 6F 63 65 73 73 00  75 73 65 72 33 32 2E 64   Process.user32.d

00006060   6C 6C 00 00 DD 01 4D 65  73 73 61 67 65 42 6F 78   ll..?MessageBox

00006070   41 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   A...............

将unpack_HelloWorld.exe拖入OllyDbg,查看内存窗口:

00402000 >E0 3B 60 77 00 00 00 00 B0 FD 7B 77 00 00 00 00  ?`w....褒{w....

00402010  08 20 40 00 6A 20 40 00 00 20 40 00 84 20 40 00  @.j @.. @.?@.

00402020  00 00 00 00 4C 20 00 00 00 00 00 00 00 00 00 00  ....L ..........

00402030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

00402040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

00402050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 4D 65  ..............Me

00402060  73 73 61 67 65 42 6F 78 41 00 75 73 65 72 33 32  ssageBoxA.user32

00402070  2E 64 6C 6C 00 00 00 00 45 78 69 74 50 72 6F 63  .dll....ExitProc

00402080  65 73 73 00 6B 65 72 6E 65 6C 33 32 2E 64 6C 6C  ess.kernel32.dll

       IAT表已修复完成,可以正常运行。

实验一百一十八:Lab1-03.exe手工脱壳

让我们借助OllyDbg调试器、ImpotREC工具实现加壳程序Lab1-03.exe手工脱壳。

●Lab1-03.exe

       我们再以第十六章的病毒分析案例一Lab1-03.exe为例,完成手工脱壳。

       第一步:将加壳程序Lab1-03.exe拖入OllyDbg调试器,快速定位OEP原程序入口地址。如下图所示:

      

图17-14 快速定位OEP

       如上图所示,为何在0x004050E1地址处下F2断点?打开内存映射窗口,第一个节区的地址区间从0x00401000开始,大小为3000H。将Lab1-03.exe拖入WinHex,观察3个节区的属性都是可读可写可执行。加壳程序的入口地址为0x00405000,0x004050E1地址处的反汇编指令是一个JE指令,跳转地址为0x00401090。因此,这个地址很可疑。接着按F8单步执行,然后按F9执行,多次重复这一动作,直到完成跳转为止。再不济,一步步单步跟踪,最终也是可以找到OEP的。如下图所示:

      

                                                 图17-15 跳转OEP地址

       第二步:使用OllyDbg插件OllyDump进行程序的脱壳操作。点击鼠标右键“用OllyDump脱壳调试进程”,弹出如下对话框窗口。

图17-16 dump脱壳程序

       注意检查“起始地址”、“入口点地址”是否正确,不要勾选“重建输入表”选项,等待稍后修复输入表。点击“脱壳”选项,保存为dumped_Lab01-03.exe。

       还可以使用LordPE工具dump脱壳文件。打开LordPE,选择当前正在调试的进程Lab01-03.exe,如下图所示:

图17-17 使用LordPE dump脱壳文件

       点击鼠标右键“完全脱壳”,保存脱壳文件为dumped_Lab01-03.exe。使用LordPE工具dump下来的脱壳文件和使用OllyDump插件几乎完全一样。

       第三步:修复输入表。如果使用纯手工修复是可以的。但是如果导入函数很多,可以借助于ImportREC工具修复导入表和IAT表。

       打开ImportREC工具,附加当前调试的加壳程序Lab01-03.exe,如图17-18所示。

       输入程序的OEP入口RVA地址00001090,然后点击自动查找,发现提示“在此OEP没有找到任何有用的信息!”。如果没有找到IAT信息,则要手动填入IAT的RVA和大小。

                                                 图17-18 自动查找IAT

         点击“确定”之后,点击右侧“获取输入表”按钮,如图17-19所示。

图17-19 获取输入表

                                          图17-20 修复IAT后转存储文件

       由左侧的窗口可知,输入函数的DLL RVA地址为0x00002000。因此,我们将OEP下方的“RVA”栏填改写为:00002000,“大小”栏不变(20个输入函数*4)。然后重新点击获取输入表。再点击“显示无效的”按钮,然后在输入表函数栏点击鼠标右键“剪切指针”,删除无效导入函数。如图17-20所示。     

       最后点击左侧按钮“修复转储文件”,选择需要转存的dump文件,保存修复后的文件unpack_Lab01-03_.exe。

第四步:运行修复后的文件,成功!对比修复后的变化。

将修复之后保存的文件unpack_HelloWorld.exe拖入WinHex:

.rdata节区:

00002000   5C 60 00 00 6C 60 00 00  7A 60 00 00 8E 60 00 00   \`..l`..z`..巂..

00002010   A0 60 00 00 AE 60 00 00  BE 60 00 00 C6 60 00 00   燻..甡..綻..芵..

00002020   D4 60 00 00 DC 60 00 00  EC 60 00 00 F8 60 00 00   訿..躟..靈..鴃..

00002030   0C 61 00 00 00 00 00 00  2A 61 00 00 38 61 00 00   .a......*a..8a..

00002040   4A 61 00 00 00 00 00 00  64 61 00 00 74 61 00 00   Ja......da..ta..

00002050   88 61 00 00 00 00 00 00  01 DF 02 00 00 00 00 00   坅.......?.....

00002060   C0 00 00 00 00 00 00 46  61 16 0C D3 AF CD D0 11   ?.....Fa..盈托.

00002070   8A 3E 00 C0 4F C9 E2 6E  FF FF FF FF 80 11 40 00   ?.繭赦n€.@.

00002080   94 11 40 00 00 00 00 00  00 00 00 00 00 00 00 00   ?@.............

       .mackt节区:

00006050   6D 73 76 63 72 74 2E 64  6C 6C 00 00 6F 00 5F 5F   msvcrt.dll..o.__

00006060   67 65 74 6D 61 69 6E 61  72 67 73 00 D7 00 5F 63   getmainargs.?_c

00006070   6F 6E 74 72 6F 6C 66 70  00 00 EE 00 5F 65 78 63   ontrolfp..?_exc

00006080   65 70 74 5F 68 61 6E 64  6C 65 72 33 00 00 9A 00   ept_handler3..?

00006090   5F 5F 73 65 74 5F 61 70  70 5F 74 79 70 65 00 00   __set_app_type..

000060A0   87 00 5F 5F 70 5F 5F 66  6D 6F 64 65 00 00 82 00   ?__p__fmode..?

000060B0   5F 5F 70 5F 5F 63 6F 6D  6D 6F 64 65 00 00 F7 00   __p__commode..?

000060C0   5F 65 78 69 74 00 50 00  5F 58 63 70 74 46 69 6C   _exit.P._XcptFil

000060D0   74 65 72 00 91 02 65 78  69 74 00 00 7C 00 5F 5F   ter.?exit..|.__

000060E0   70 5F 5F 5F 69 6E 69 74  65 6E 76 00 3C 01 5F 69   p___initenv.<._i

000060F0   6E 69 74 74 65 72 6D 00  9C 00 5F 5F 73 65 74 75   nitterm.?__setu

00006100   73 65 72 6D 61 74 68 65  72 72 00 00 B7 00 5F 61   sermatherr..?_a

00006110   64 6A 75 73 74 5F 66 64  69 76 00 00 6F 6C 65 61   djust_fdiv..olea

00006120   75 74 33 32 2E 64 6C 6C  00 00 08 00 56 61 72 69   ut32.dll....Vari

00006130   61 6E 74 49 6E 69 74 00  02 00 53 79 73 41 6C 6C   antInit...SysAll

00006140   6F 63 53 74 72 69 6E 67  00 00 06 00 53 79 73 46   ocString....SysF

00006150   72 65 65 53 74 72 69 6E  67 00 6F 6C 65 33 32 2E   reeString.ole32.

00006160   64 6C 6C 00 FE 00 4F 6C  65 49 6E 69 74 69 61 6C   dll.?OleInitial

00006170   69 7A 65 00 12 00 43 6F  43 72 65 61 74 65 49 6E   ize...CoCreateIn

00006180   73 74 61 6E 63 65 00 00  15 01 4F 6C 65 55 6E 69   stance....OleUni

00006190   6E 69 74 69 61 6C 69 7A  65 00 00 00 00 00 00 00   nitialize.......

将unpack_HelloWorld.exe拖入OllyDbg,查看内存窗口:

00402000 >EB EE BE 77 4F EE C1 77 94 5C C0 77 7C 53 C0 77  腩緒O盍w擻纖|S纖

00402010 >DB F1 BE 77 A4 F1 BE 77 9A 9E C0 77 AE 2D C0 77  垴緒ゑ緒殲纖?纖

00402020 >7E 9E C0 77 F1 F1 BE 77 67 9D C0 77 95 D6 C1 77  ~灷w耨緒g澙w曋羨

00402030 >D8 23 C3 77 00 00 00 00 80 49 0F 77 05 4C 0F 77  ?脀....€IwLw

00402040 >80 48 0F 77 00 00 00 00 0A 1C 9B 76 D4 F1 9A 76  €Hw.....泇择歷

00402050 >7F 32 9E 76 00 00 00 00 01 DF 02 00 00 00 00 00  2瀡....?.....

00402060  C0 00 00 00 00 00 00 46 61 16 0C D3 AF CD D0 11  ?.....Fa.盈托

00402070  8A 3E 00 C0 4F C9 E2 6E FF FF FF FF 80 11 40 00  ?.繭赦n€@.

00402080  94 11 40 00 00 00 00 00 00 00 00 00 00 00 00 00  ?@.............

IAT表已修复完成,可以正常运行。


http://www.kler.cn/a/371751.html

相关文章:

  • ELK + Filebeat + Spring Boot:日志分析入门与实践(二)
  • 如何用猿大师办公助手实现OA系统中Word公文/合同在线编辑及流转?
  • 晓羽扫码点餐快销版系统源码
  • Android实现扫描二维码条形码,实现扫描快递单,相册图片识别快递单 最慢3秒出回调结果
  • 【YOLOv11[基础]】实例分割 + 跟踪
  • CSS3新增长度单位
  • 怎么把word文档拆分成2个word文档,拆分后原格式保持不变
  • 机器学习结课项目报告
  • Es概念理解 ▎Es索引库操作 ▎Es文档操作
  • MySQL 9从入门到性能优化-创建触发器
  • 显示器时不时黑一下是什么原因?
  • DDoS攻击趋势令人担忧,安全防御体系构建指南
  • 自研小程序-心情追忆
  • 【云原生】云原生与DevOps的结合:提升软件开发与交付的效率
  • 2-134 基于matlab的图像边缘检测
  • 腾讯共享wifi项目全解析!头部服务商系统质量大测评!
  • 2024年10月实测安装支持 winxp的最后一个python版本 2.7.18 和python 3.4.4版本,你觉得还能正常安装吗?
  • 【Linux】MySQL部署
  • 【Java网络编程】从套接字(Socket)概念到UDP与TCP套接字编程
  • chat_gpt回答:qt中,常见格式及格式转换
  • 【数据集】MODIS地表温度数据(MOD11)
  • 程序员必看!AI如何助你工作开挂!
  • verilog实现一个5bit序列检测器
  • word拷贝学号到excel
  • 无人机救援系统基本组成
  • 指令集架构(ISA)