1. 前述

在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体。

2. 区块表

区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含区块的信息,比如位置、长度、属性等,区块的数目是由 NT 头中的文件头里的 NumberOfSections 给出。以下为 `IMAGE_SECTION_HEADER` 结构:

在上述图中,有两个字段比较重要,分别为 `VirtualAddress`、`PointerToRawData`,这两个字段用于将相对虚拟地址或虚拟地址转换为文件偏移地址,以下为 RVA 转 FOA 函数:

DWORD RVAtoFOA(DWORD dwRva)
{
// 获取区段表的数量
DWORD dwCounts = g_NtHeader->FileHeader.NumberOfSections; // 获取区段表数组的首元素
auto Sections = IMAGE_FIRST_SECTION(g_NtHeader); // 遍历所有的区段表找到符合要求的区段
for (DWORD i = 0; i < dwCounts; ++i)
{
// 要求:RVA >= 区段的首地址 并且 RVA < 区段的结尾的地址
if (dwRva >= Sections[i].VirtualAddress &&
(Sections[i].VirtualAddress + Sections[i].SizeOfRawData))
{
// FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)
// FOA = RVA - 所在区段的 RVA + 所在区段的 FOA
return dwRva - Sections[i].VirtualAddress + Sections[i].PointerToRawData;
}
} // 如果找不到就返回 -1
return -1;
}

计算公式为:`FOA = VA - ImageBase - (所在区段的 RVA - 所在区段的 FOA)` 或 `FOA = RVA - 所在区段的 RVA + 所在区段的 FOA`。在上述代码中,有一个为 `IMAGE_FIRST_SECTION`,我们来看下它的定义,如下:

其实 `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` 结构中的偏移,如下:

(本小节完)

PE 学习之路 —— 区块表的更多相关文章

  1. 小甲鱼PE详解之区块表(节表)和区块(节)(PE详解04)

    到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的知识.接下来就该轮到SectionTable (区块表,也成节表).(视频教程:http://fishc.com ...

  2. PE 学习之路 —— DOS 头、NT 头

    1. 前述 可执行文件的格式是操作系统本身执行机制的反映,理解它有助于对操作系统的深刻理解,掌握可执行文件的数据结构及其一些机理,是研究软件安全的必修课.`PE(Portable Executable ...

  3. 小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)

    这一讲我们结合实例来谈谈区块表的定义以及各个属性的含义. 首先,我们先用之前学过的一点知识在二进制文件中手动翻找区块表,这样做的好处是可以使你很快的对PE结构牢记于心.学来的东西就是能用的东西,不能用 ...

  4. Python学习之路day4-列表生成式、生成器、Iterable和Iterator

    一.列表生成式 顾名思义,列表生成式就是用于生成列表的特殊语法形式的表达式. 1.1 语法格式 [exp for iter_var in iterable] 工作过程: 1.通过iter_var迭代i ...

  5. 小甲鱼PE详解之区块描述、对齐值以及RVA详解(PE详解06)

    各种区块的描述: 很多朋友喜欢听小甲鱼的PE详解,因为他们觉得课堂上老师讲解的都是略略带过,绕得大家云里雾里~刚好小甲鱼文采也没课堂上的教授讲的那么好,只能以比较通俗的话语来给大家描述~ 通常,区块中 ...

  6. PE解析器的编写(三)——区块表的解析

    PE文件中所有节的属性都被定义在节表中,节表由一系列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序是一致的. 具有相同属 ...

  7. FastAPI 学习之路(十六)Form表单

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  8. FastAPI 学习之路(十八)表单与文件

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  9. 小甲鱼PE详解之输入表(导入表)详解(PE详解07)

    捷径并不是把弯路改直了,而是帮你把岔道堵上! 走得弯路跟成长的速度是成正比的!不要害怕走上弯路,弯路会让你懂得更多,最终还是会在终点交汇! 岔路会将你引入万劫不复的深渊,并越走越深…… 在开始讲解输入 ...

随机推荐

  1. Python学习---Java和Python的区别小记

    Java和Python的区别小记 注意这里使用的是 and/or/not  非java中的&&,||,!Java中的true是小写 Python中函数就是对象,函数和我们之前的[1,2 ...

  2. C#网络编程(一)基础篇

    简介: C#网络编程API包含在System.Net和System.Net.Sockets命名空间下,大部分网络操作都可以在其中找到相应的类来实现:包括Socket的创建和连接,网络流收发方法的封装, ...

  3. python windows 远程执行bat

    本机环境:Win 10,python3.6 远程机器: Win7.WinServer 因python在windows上执行需要用到 wmi 模块. wmi 模块下载地址:https://sourcef ...

  4. HBase编程 API入门系列之create(管理端而言)(8)

    大家,若是看过我前期的这篇博客的话,则 HBase编程 API入门系列之put(客户端而言)(1) 就知道,在这篇博文里,我是在HBase Shell里创建HBase表的. 这里,我带领大家,学习更高 ...

  5. September 01st 2017 Week 35th Friday

    Each trauma, is another kind of maturity. 每一个创伤,都是另一种成熟. Sometimes the trauma may be too severe to h ...

  6. August 18th 2017 Week 33rd Friday

    If you shed tears when you miss the sun, you also miss the stars. 如果你因为错过太阳而哭泣,你也将会错过繁星. If you have ...

  7. Genymotion安卓模拟器和VirtualBox虚拟机安装、配置、测试(win7_64bit)

    1.概述 VirtualBox是一个优秀的虚拟机软件,它可以在电脑上提供另一个操作系统的运行环境,使多个系统同时运行.VirtualBox支持的操作系统包括Windows.Mac OS X.Linux ...

  8. jq封装-无缝滚动效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. 【[LNOI2014]LCA】

    这题好神啊 能够\(1A\)真是不可思议 首先看到要求的这个柿子\(\sum_{i=l}^{r}deep[LCA(i,z)]\),而且\(l\)和\(r\)并不是来自与一棵子树或者一条链,而是编号连续 ...

  10. POJ2724 Purifying Machine

    嘟嘟嘟 扒下来的题意:迈克有一台可以净化奶酪的机器,用二进制表示净化的奶酪的编号.但是,在某些二进制串中可能包含有\(*\).例如\(01*100\),\(*\)其实就代表可以取\(0\),\(1\) ...