PE节表详细分析

您所在的位置:网站首页 p值的表格怎么看表格大小 PE节表详细分析

PE节表详细分析

2024-02-22 09:35| 来源: 网络整理| 查看: 265

目录PE节表详细分析0x00 前言0x01 PE节表分析节表结构节表数量节表名字节表大小节位置节表属性0x02 代码编写

PE节表详细分析 0x00 前言

上一篇文章我们学习了PE结构中的PE头,我之前说过PE文件结构是PE头->节表->每个节,所以我们掌握了节表后也就知道怎么去获取每个节了。(当然后面还有输入表,输出表这些比较重要的东西。这些知识在后面的文章详细介绍。)

0x01 PE节表分析 节表结构

PE节表位于PE头的下面,PE节表中记录了各个节表的起始位置、大小,以及在内存中偏移位置和属性。

其结构体如下:

#define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//*[1]:节名 union { DWORD PhysicalAddress; DWORD VirtualSize; //*[2]:对其前节大小,内存中节大小 } Misc;//联合体 DWORD VirtualAddress; //*[3]:内存中偏移 DWORD SizeOfRawData; //*[4]:文件对其后节大小 DWORD PointerToRawData; //*[5]:文件中节位置 DWORD PointerToRelocations;// DWORD PointerToLinenumbers;// WORD NumberOfRelocations; // WORD NumberOfLinenumbers; // DWORD Characteristics; //*[6]:节属性的标志 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

image-20211106161212671

节表数量

节表数量不在节表中,而是在上一篇文章中已经介绍过,在标准PE头中。标准PE头中有一个成员是NumberOfSections他是节表的数量。

image-20211106161056869

节表名字

节表名字是各个节表的第一个成员,首先我们根据PE头大小来确定节表所在位置即DOS头+垃圾数据+NT头,下面在010Editor演示具体数据。

节表中第一个数据是节名,节名一共占用的数据大小是8个字节, 演示中第一个节名是.text。

image-20211106162142952

节表大小

节表中真实的大小在VirtualAddress中,也就是节名后的4个字节。他所代表的意思是对其前的大小也是在内存中的大小。

而在他后4四节之后的4字节数据,代表的是对其后的大小也是文件中的大小SizeOfRawData。

image-20211106183020009

节位置

节位置都是在节大小之后,占用大小也是为4字节。VirualAddress后的4字节代表的是内存中节偏移,SizeOfRawData后的4字节代表的是文件中节位置。

image-20211106183953593

在内存中锁定具体的节位置需要内存地址+节偏移得到的地址才是真实的内存节所在的位置,而在文件中的节位置则可以根据地址直接索引到,不需要+文件地址因为文件地址开始就是0。

image-20211106185117155

内存地址在可选PE头的ImageBase中,所以我们需要先获取到ImageBase的值这里是0x00400000,所以加上偏移位置就是0x00401000。

image-20211106184450035

image-20211106184804699

一般程序在没有被修改的情况下,默认.text段就是程序用来放代码的地方。所以我们也可以用OD直接载入程序,然后跳到.text段的位置可以看到程序的汇编代码。

(小知识:OD载入程序就是模拟了程序拉伸的过程,程序在内存中的样子。)

image-20211106185730814

节表属性

节表中的最后一个数据也是最重要的,他代表了这个节是否可读、可写、可执行或者是否包含可执行代码、初始化、未初始化的数据。所以一般我们判断一个段是否是代码段就是根据这个属性的值来判断的,因为节表名是可以改的,比如我把随便一个节表名改成.text、.code。那你就觉得他是代码段了吗?

代码段的属性一般是0x60000020,其中这4字节的数据,他每一位都对应下面表格中的数据。下面我们把0x60000020来拆分一下,首先最后2位对应下面的包含可执行代码的数据,然后最高位的6对应下面的(该块可执行)+(该块可读)的值。所以代码段的属性就是:(包括可执行代码)、(可执行)、(可读)。

--> 标志(属性块) 常用特征值对照表:> 7) ? 3 : 0); l_flag.push_back((l_Charctieristics >> 6) & 1 ? 2 : 0); l_flag.push_back((l_Charctieristics >> 5) & 1 ? 1 : 0); //高位 h_flag.push_back((h_Charctieristics >> 7) ? 7 : 0); h_flag.push_back((h_Charctieristics >> 6) & 1 ? 6 : 0); h_flag.push_back((h_Charctieristics >> 5) & 1 ? 5 : 0); h_flag.push_back((h_Charctieristics >> 4) & 1 ? 4 : 0); //包含数据情况 SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN); for (vector::iterator iter = l_flag.begin(); iter != l_flag.end(); iter++) { switch (*iter) { case 1: cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3