PE文件详解(四)

摘要:
本文转自《小乌龟》详细PE文件系列的原始门户网站。到目前为止,小乌龟和每个人都了解了很多关于多西耶和PEheader的知识。节表始终存储在PE文件头的旁边。此外,节表中的IMAGE _ section_HEADER结构的总数始终由HEADER结构NumberOfSections字段中的PE文件HEADER IMAGE_NT_FileHeader决定。因此,小乌龟建议,当我们想从PE文件中读取所需的块时,不能使用块名作为定位标准和依据。PointerToRelocations:这个家伙在EXE文件中没有任何意义。在OBJ文件中,它表示此块的重定位信息的偏移值。

本文转自小甲鱼的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文件详解(四)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【原创】用MyEclipse搭建和配置SSH框架详解(图文)Android_三种菜单介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

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

1. 前述 可执行文件的格式是操作系统本身执行机制的反映,理解它有助于对操作系统的深刻理解,掌握可执行文件的数据结构及其一些机理,是研究软件安全的必修课。`PE(Portable Executable File Format)`是目前 windows 平台上的主流可执行文件格式。PE 文件衍生于早期的 COFF 文件格式,描述 PE 格式及 COFF 文件...

【C#进阶系列】02 PE文件,程序集,托管模块,元数据——还是那个Hello world

好了,还是这张图,还是一样的Hello world。 因为本章其实很多都是讲一些命令行编译啊什么鬼的配置类的东西,要用的时候直接百度或者回头查书就可以了, 所以了解一下也就行了,也没有记录下来,接下来讲得只是我认为很有用的东西。 关于引用 请看上图,MyTest程序集下面有个引用,引用里面大家都知道有很多dll,而我们的源代码中只有那5个using引用某...

PE文件格式基本结构信息

一)win32下PE文件格式的文件有:*.exe;*.dll;*.scr;*.fon;*.drv;*.sys 二)pe文件基本结构 附加数据 其它节区 .reloc节区 .rsrc节区 .data节区 .text节区 节表 数据目录 选项头 文件头 PE标志 DOS stub DOS头 格式说明: 1)dos头: 0000 0000:4D 5A 000...

计算PE文件校验和

// 计算PE校验和 #include <ImageHlp.h> #pragma comment(lib,"Imagehlp.lib") void Getchecksum(TCHAR* pszPath) { /* Code by Lthis 转载请注明出处 */ DWORD dwHeaderSum, dw...