鱼C论坛

 找回密码
 立即注册
查看: 2402|回复: 1

解密 PE 文件 —— 区块表

[复制链接]
发表于 2018-12-24 15:29:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 零度非安全 于 2018-12-25 10:58 编辑

1. 前述
在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体。
2. 区块表
区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含区块的信息,比如位置、长度、属性等,区块的数目是由 NT 头中的文件头里的 NumberOfSections 给出。以下为 IMAGE_SECTION_HEADER 结构:
20181224145043284_26431.png
在上述图中,有两个字段比较重要,分别为 VirtualAddress、PointerToRawData,这两个字段用于将相对虚拟地址或虚拟地址转换为文件偏移地址,以下为 RVA 转 FOA 函数:
  1. // RVA 转 FOA
  2. DWORD RVAtoFOA(DWORD dwRva)
  3. {
  4.     // 获取区段表的数量
  5.     DWORD dwCounts = g_NtHeader->FileHeader.NumberOfSections;

  6.     // 获取区段表数组的首元素
  7.     auto Sections = IMAGE_FIRST_SECTION(g_NtHeader);

  8.     // 遍历所有的区段表找到符合要求的区段
  9.     for (DWORD i = 0; i < dwCounts; ++i)
  10.     {
  11.         // 要求:RVA >= 区段的首地址 并且 RVA < 区段的结尾的地址
  12.         if (dwRva >= Sections[i].VirtualAddress &&
  13.             dwRva < (Sections[i].VirtualAddress + Sections[i].SizeOfRawData))
  14.         {
  15.             // FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)
  16.             // FOA = RVA - 所在区段的 RVA + 所在区段的 FOA
  17.             return dwRva - Sections[i].VirtualAddress + Sections[i].PointerToRawData;
  18.         }
  19.     }

  20.     // 如果找不到就返回 -1
  21.     return -1;
  22. }
复制代码

计算公式为:FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA) 或 FOA = RVA - 所在区段的 RVA + 所在区段的 FOA。

在上述代码中,有一个为 IMAGE_FIRST_SECTION,我们来看下它的定义,如下:
20181224150219502_9082.png
其实 IMAGE_FIRST_SECTION 为一个宏,它主要由三部分相加组成,作用是获取到第一个区段的首地址,参数为 NT 头。你可以把这个首地址理解成数组名,数组的首地址。在获取到了地址后,下面的 for 循环遍历所有的区段表找到符合要求的区段。这三部分内容具体如下:

  • IMAGE_NT_HEADERS 的起始地址
  • IMAGE_OPTIONAL_HEADER32 (PE 扩展头)在 IMAGE_NT_HEADERS 中的偏移
  • IMAGE_OPTIONAL_HEADER32 的大小

其中后两个加起来的大小恰好就是 IMAGE_NT_HEADERS 的大小,再跟第一个相加就得到区段表的地址了。看到这你可以会问,为什么不直接加上 IMAGE_NT_HEADERS 的大小呢?因为 IMAGE_OPTIONAL_HEADER32 大小不固定,32 位下该值为 0x00E0H,64 位下该值为 0x00F0H,并且用户还可以自定义其大小。
3. 额外说明
扩展头大小是由文件头中 SizeOfOptionalHeader 字段给出,FIELD_OFFSET 这个是给出 OptionalHeader 在 IMAGE_NT_HEADERS 结构中的偏移,如下:
20181224152425672_25587.png

demo.rar (2.33 KB, 下载次数: 16)

(完)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-18 14:39:35 | 显示全部楼层
这不叫解密,,,,这叫解析~~~。另外,代码有BUG
  1. // 遍历所有的区段表找到符合要求的区段
  2.     for (DWORD i = 0; i < dwCounts; ++i)
  3.     {
  4.         // 要求:RVA >= 区段的首地址 并且 RVA < 区段的结尾的地址
  5.         if (dwRva >= Sections[i].VirtualAddress &&
  6.             dwRva < (Sections[i].VirtualAddress + Sections[i].SizeOfRawData))
  7.         {
  8.             // FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)
  9.             // FOA = RVA - 所在区段的 RVA + 所在区段的 FOA
  10.             return dwRva - Sections[i].VirtualAddress + Sections[i].PointerToRawData;
  11.         }
  12.     }
复制代码


这段儿代码在解析某些畸形PE的时候会出问题。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-30 20:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表