首页
社区
课程
招聘
[原创]UPack壳的PE头部分析
发表于: 2025-9-15 21:52 776

[原创]UPack壳的PE头部分析

2025-9-15 21:52
776

    根据PE文件结构标准,DOS头在执行过程中需要检查MZ签名和根据e_lfanew字段定位NT头,因此无论中间的值如何奇怪,可以定位到NT头在地址00 00 00 10处。在upack打包程序中,upack通过修改中间字段使DOS头和NT头混合,e_lfanew字段同时也作为IMAGE_OPTIONAL_HEADER中的BaseofCode使用。

    接下来说一下常见的关注点,但在本例中可能不涉及。

NT文件头的SizeOfOptionalHeader(可选头大小)定义了标准头结束和节区表开始的位置。当SizeOfOptionalHeader被修改时,程序能够正常执行(其实是有时候可以,可以参考我写的另外一篇Windows加载文件全流程文档),但对于很多分析器像调试器、文件解析工具、反汇编器等将造成影响。修改目的大部分是为了反调试,但也有一些版本的upack壳中在此处扩展字段来插入解码代码。

    可选头的NumberOfRvaAndSizes(数据目录项数),通常值为16(0x10),修改后可能干扰工具解析文件,运行时不受影响,但对于工具来说就是分析数据目录项数的解析标杆,可能出现无意义值或者显示不全。我在未打包程序上测试的可修改后正常运行的最小值为0x06。当修改值小于16时,后面的条目将无法被读取,变成程序加载时读取不到的地方。

    严格根据e_lfanew + 4(签名) + 20(COFF头) + SizeofOptionalHeader计算节区头的起始位置,本例中计算得到10H + 4H + 14H + 148H = 170H,跳转至170地址处就是节区头。

 

    upack打包程序有三个节区头,根据信息可以知道一些关键信息:

节区

SizeOfRawData

PointerToRawData

VirtualAdress

VirtualSize

1

0x000001F0

0x00000010

0x00001000

0x0000F000

2

0x00005358

0x00000200

0x00010000

0x0000A000

3

0x000001F0

0x00000010

0x0001A000

0x00001000

    在磁盘中upack打包程序的第1、3个节区是重合的,但是在内存中的VirtualAress和VirtualSize却是不同的,说明磁盘中的某个区域被映射了两次,在映射之初肯定是完全相同的,但是在内存中随着程序运行这两个节区一定会发生变化。

    接下来查看程序的入口,几乎所有壳都会将原始代码跳转处作为壳代码,将真正的OEP藏在壳代码内部。AddressOfEntryPoint(RVA) = 0x00001018,计算出RAW = 0x18(要考虑FileAlinment影响,PointerToRawData = 10时,取整得0)

    0x18地址处的代码片段为:

BE B0 11 40 00    mov esi, 0x004011B0   ; 将地址 0x4011B0 加载到 ESI 寄存器

AD                lodsd                  ; 从 [ESI] 加载双字到 EAX,然后 ESI+4

50                push eax               ; 将 EAX 的值压入栈

FF 76 34          push dword ptr [esi+34h] ; 将 [ESI+0x34] 处的双字压入栈

...

    这里就是解壳代码。



[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-9-15 21:57 被Calparrot编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回