PE文件详解(四)
本文转自小甲鱼的PE文件详解系列原文传送门
到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的知识。接下来就该轮到SectionTable (区块表,也成节表)。
越学越多的结构,大家可能觉得PE挺乱挺杂的哈,所以这里插播下一下必要知识的详细注释,大伙可以按需要看。
PE文件中所有节的属性都被定义在节表中,节表由一系列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序是一致的。
全部有效结构的最后以一个空的IMAGE_SECTION_HEADER结构作为结束,所以节表中总的IMAGE_SECTION_HEADER结构数量等于节的数量加一。
节表总是被存放在紧接在PE文件头的地方。
另外,节表中 IMAGE_SECTION_HEADER 结构的总数总是由PE文件头 IMAGE_NT_HEADERS 结构中的 FileHeader.NumberOfSections 字段来指定的。
typedef struct _IMAGE_SECTION_HEADER
{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 节表名称,如“.text”
//IMAGE_SIZEOF_SHORT_NAME=8
union
{
DWORD PhysicalAddress; // 物理地址
DWORD VirtualSize; // 真实长度,这两个值是一个联合结构,可以使用其中的任何一个,一般是取后一个
} Misc;
DWORD VirtualAddress; // 节区的 RVA 地址
DWORD SizeOfRawData; // 在文件中对齐后的尺寸
DWORD PointerToRawData; // 在文件中的偏移量
DWORD PointerToRelocations; // 在OBJ文件中使用,重定位的偏移
DWORD PointerToLinenumbers; // 行号表的偏移(供调试使用地)
WORD NumberOfRelocations; // 在OBJ文件中使用,重定位项数目
WORD NumberOfLinenumbers; // 行号表中行号的数目
DWORD Characteristics; // 节属性如可读,可写,可执行等
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
Name:
区块名。这是一个由8位的ASCII 码名,用来定义区块的名称。
多数区块名都习惯性以一个“.”作为开头(例如:.text),这个“.” 实际上是不是必须的。
值得我们注意的是,如果区块名超过 8 个字节,则没有最后的终止标志“NULL” 字节。
并且前边带有一个“”的区块名字会从连接器那里得到特殊的待遇,前边带有“” 的相同名字的区块在载入时候将会被合并,在合并之后的区块中,他们是按照“$” 后边的字符的字母顺序进行合并的。
另外小甲鱼童鞋要跟大家啰嗦一下的是:每个区块的名称都是唯一的,不能有同名的两个区块。
但事实上节的名称不代表任何含义,他的存在仅仅是为了正规统一编程的时候方便程序员查看方便而设置的一个标记而已。
所以将包含代码的区块命名为“.Data” 或者说将包含数据的区块命名为“.Code” 都是合法的。
因此,小甲鱼建议大家:当我们要从PE 文件中读取需要的区块时候,不能以区块的名称作为定位的标准和依据。
正确的方法是按照 IMAGE_OPTIONAL_HEADER32 结构中的数据目录字段结合进行定位。
Virtual Size:
对应的区块的大小,这是区块的数据在没有进行对齐处理前的实际大小。
Virtual Address:
该区块装载到内存中的RVA 地址。这个地址是按照内存页来对齐的,因此它的数值总是 SectionAlignment 的值的整数倍。
在Microsoft 工具中,第一个块的默认 RVA 总为1000h。在OBJ 中,该字段没有意义地,并被设为0。
SizeOfRawData:
该区块在磁盘中所占的大小。在可执行文件中,该字段是已经被FileAlignment 潜规则处理过的长度。
PointerToRawData:
该区块在磁盘中的偏移。这个数值是从文件头开始算起的偏移量哦。
PointerToRelocations:
这哥们在EXE文件中没有意义,在OBJ 文件中,表示本区块重定位信息的偏移值。
(在OBJ 文件中如果不是零,它会指向一个IMAGE_RELOCATION 结构的数组)
PointerToLinenumbers:
行号表在文件中的偏移值,文件的调试信息,于我们没用,鸡肋。
NumberOfRelocations:
这哥们在EXE文件中也没有意义,在OBJ 文件中,是本区块在重定位表中的重定位数目来着。
NumberOfLinenumbers:
该区块在行号表中的行号数目,鸡肋。
Characteristics:
该区块的属性。该字段是按位来指出区块的属性(如代码/数据/可读/可写等)的标志。
具体内容可以参考MSDN在线文档:传送门
下面通过一个例子来详细朔门这些内容:还是以上次那个为例
根据以前的内容可以知道这个文件PE头在0xf0的位置,上一次是通过各个结构体大小来找到PE头中这个OptionalHeader结构的地址,但是当时我忘记了,在FileHeader 这个结构中有一个SizeOfOptionalHeader这个域专门用来记录OptionalHeader结构的大小,它在PE头的偏移为0x14也就是在0xf0 + 0x14 = 0x104的位置
查看文件得知这个值为0xe0, OptionalHeader偏移0x18 + 大小0xe0 + pe头的偏移0xf0 = 0x1e8
根据这个结构中的成员很容易计算出来,这个结构占0x28个字节,这样根据上一个的起始地址 + 0x28就可以得到下一个的地址,这样可以陆陆续续找到所有的节
节表中的最后一个为全0,这样这个PE文件中总共有.textbss、.text、.radta、.data、.idata、.rsrc、.reloc这样几个节。
接下来读取各个部分的内容,比如说在text节中,
VirtualSize = 0x00014360
PointerToRawData = 0x000400
VirtualAddress = 0x00011000
SizeOfRawData = 0x00014400
Characteristics = 0x60000020
这些节区都是按照文件中的某个值对齐,然后在紧密排列的,所以根据它在文件中的偏移 + 对齐后的值可以得到下一个节在文件中的偏移地址,根据这点在text节中
PointerToRawData + SizeOfRawData = 0x000400 + 0x00014400 = 0x00014800,而下一个的文件偏移地址正好是这个,这个根据在PE中查找到的数据,发现下一个确实是这个值
PE文件详解(四)的更多相关文章
- PE文件详解(八)
本文转载自小甲鱼PE文件详解系列教程原文传送门 当应用程序需要调用DLL中的函数时,会由系统将DLL中的函数映射到程序的虚拟内存中,dll中本身没有自己的栈,它是借用的应用程序的栈,这样当dll中出现 ...
- PE文件详解(六)
这篇文章转载自小甲鱼的PE文件详解系列原文传送门 之前简单提了一下节表和数据目录表,那么他们有什么区别? 其实这些东西都是人为规定的,一个数据在文件中或者在内存中的位置基本是固定的,通过数据目录表进行 ...
- PE文件详解(三)
本文转自小甲鱼的PE文件详解系列传送门 PE文件到内存的映射 在执行一个PE文件的时候,windows 并不在一开始就将整个文件读入内存的,二十采用与内存映射文件类似的机制. 也就是说,windows ...
- PE文件详解(九)
本篇文章转载自小甲鱼的一篇日志,原文地址 我们知道,Windows 将程序的各种界面定义为资源,包括加速键(Accelerator).位图(Bitmap).光标(Cursor).对话框(Dialog ...
- PE文件详解(七)
本文转载自小甲鱼PE文件讲解系列原文传送门 这次主要说明导出表,导出表一般记录着文件中函数的地址等相关信息,供其他程序调用,常见的.exe文件中一般不存在导出表,导出表更多的是存在于dll文件中.一般 ...
- PE文件详解(五)
在前面几节中经常提到相对虚拟地址RVA,在这篇博客中主要说明这个概念.本来是想接着转载小甲鱼的,但是我自己根据这篇文章和他的视频来学习的时候,发现在RVA与文件的相对偏移地址进行转化的时候,那块我看不 ...
- PE文件详解二
本文转自小甲鱼的PE文件相关教程,原文传送门 咱接着往下讲解IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用! 接着我们来谈谈 IMAGE_OPTIONAL_HEADER 结构 ...
- MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询
支持的 JDBC 类型为了未来的参考,MyBatis 通过包含的 jdbcType 枚举型,支持下面的 JDBC 类型. BITFLOATCHARTIMESTAMPOTHERUNDEFINEDTINY ...
- PE文件结构详解(四)PE导入表
PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...
随机推荐
- 最全Pycharm教程(28)——Pycharm搜索导航之搜索应用实例
1.主题 这里我们将介绍Pycharm另外一项强力的搜索导航功能.如果你希望知道某个特定的类或方法都在project中的哪些地方发挥了作用.也就是找出其全部的usages,这将是一个很巨大而繁琐的pr ...
- Java 并发专题 : Executor具体介绍 打造基于Executor的Webserver
转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985 继续并发,貌似并发的文章非常少有人看啊~哈~ 今天准备具体介绍jav ...
- 【jQuery】复选框的全选、反选,推断哪些复选框被选中
本文与<[JavaScript]复选框的全选.反选.推断哪些复选框被选中>(点击打开链接)为姊妹篇,把里面内容再与jQuery框架中实现一次,相同做到例如以下的效果: 布局还是相同的布局, ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- Linux禁用显示“缓冲调整”
Linux禁用显示"缓冲调整" youhaidong@youhaidong-ThinkPad-Edge-E545:~$ free -o total used free shared ...
- hdu 4939
题意: 长度为n个单位的map,每一个单位须要时间t来走完. 每一个单位能够放置一个塔.一共同拥有三种塔,每种塔的作用不同: 1.仅仅能攻击当前单位.每秒x点伤害(红塔) 2.攻击当前单位之后的全部单 ...
- 我的Java开发学习之旅------>Base64的编码思想以及Java实现
Base64是一种用64个字符来表示随意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,由于二进制文件包括非常多无法显示和打印的字符.所以,假设要让记事本这种 ...
- Spring基础知识之依赖注入
Spring框架的四大原则: 1)使用POJO进行轻量级和最小侵入式的开发. 2)通过依赖注入和基于接口编程实现松耦合. 3)通过AOP和默认习惯进行声明式编程. 4)使用AOP和模板(templat ...
- F12调试模式下使用console自动提交
F12调试模式下使用console自动提交(F12 的console->输入代码->按enter即可运行) 1.使用定时器setInterval进行自动提交 //方法中可使用jquery调 ...
- 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南
1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...