PE解析器的编写(三)——区块表的解析
来源:互联网 发布:乐乐抢红包软件 编辑:程序博客网 时间:2024/06/14 17:17
PE文件中所有节的属性都被定义在节表中,节表由一系列的IMAGE_SECTION_HEADER结构排列而成,每个结构用来描述一个节,结构的排列顺序和它们描述的节在文件中的排列顺序是一致的。
具有相同属性的数据被安排到同一个区块中。
区块表的结构为IMAGE_SECTION_HEADER,在PE文件中存在一个该结构的数组,用来保存各个区块的信息,这个数组的大小在PE头的结构 IMAGE_NT_HEADERS 的成员NumberOfSections描述。
区块表结构IMAGE_SECTION_HEADER结构如下:
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;
在程序中我们主要列出了,区块名称、RVA、在进行内存对齐后的尺寸,在磁盘中的大小,在文件中的偏移,节属性。
在界面中,定义了一个listctrl来显示这些信息。
在CPeFileInfo类中定义了一个vector m_SectionTable;专门用来存储区块表的属性信息。获取这个信息。
在这个类中与区块表有关的函数主要有两个:
GetSectionHeader : 用来获取指向表的指针
InitSectionTable:初始化上面定义的结构
下面来一一说明这两个函数
PIMAGE_SECTION_HEADER CPeFileInfo::GetSectionHeader(){ PIMAGE_FILE_HEADER pFileHeader = GetFileHeader(); PIMAGE_SECTION_HEADER pSectionHeader = NULL; if (NULL == pFileHeader) { return NULL; } PIMAGE_OPTIONAL_HEADER pOptionHeader = GetOptionalHeader(); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)(pOptionHeader) + pFileHeader->SizeOfOptionalHeader); return pSectionHeader;// PIMAGE_NT_HEADERS pNtHeader = GetNtHeaders();// return (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + sizeof(IMAGE_NT_HEADERS));}
在PE文件中区块表的属性信息是紧密排列在PE头结构后面的,所以我们只要知道OptionHeader结构的指针,然后加上这个结构的大小就可以获取到区块表的地址,上面的代码也是这样做的,首先获取了FileHeader的指针,这个结构中的SizeOfOptionalHeader定义了OptionHeader这个结构的大小,我们利用FileHeader + SizeOfOptionalHeader这样就偏移到了区块表所在的位置。
或者更简单的方式是利用PE文件头的地址 + 文件头的大小也一样可以获取到区块表的地址
void CPeFileInfo::InitSectionTable(){ if (!m_SectionTable.empty()) { return ; } PIMAGE_SECTION_HEADER pSectionHeader = GetSectionHeader(); PIMAGE_FILE_HEADER pFileHeader = GetFileHeader(); if (NULL != pSectionHeader && NULL != pFileHeader) { DWORD dwCountOfSection = pFileHeader->NumberOfSections; int nCount = 0; while (nCount < dwCountOfSection) { IMAGE_SECTION_HEADER ImageSec = pSectionHeader[nCount]; m_SectionTable.push_back(ImageSec); nCount++; } }}
后面就是循环遍历将所有信息写入m_SectionTable这个动态数组中。在这份代码中我们首先利用FileHeader的NumberOfSections成员获取区块表的个数,然后在循环中以这个个数作为条件,以此往后寻址,将信息写入到对应的数组中,最后在输出的时候只需要根据需求输出我们感兴趣的内容即可
- PE解析器的编写(三)——区块表的解析
- PE文件解析器的编写(二)——PE文件头的解析
- PE解析器的编写(四)——数据目录表的解析
- 编写PE文件解析器(三)
- PE解析器的编写(一)——总体说明
- 编写PE文件解析器(二)
- 编写PE文件解析器(一)
- PE导出表的解析
- C++PE文件格式解析类(轻松制作自己的PE文件解析器)
- 关于PE病毒编写的学习(三)
- 关于PE病毒编写的学习(三)
- 关于PE病毒编写的学习(三)
- 关于PE病毒编写的学习(6)——关于PE文件结构操作的程序编写
- 【C++源码】PE文件结构中导出表的解析
- 语言的学习(4)---- PE文件格式解析
- PE头部的解析(总结于小甲鱼)
- 解析PE文件的附加数据
- 学破解 <三> PE格式之 区块表与区块
- noip 数论总结
- Android中如何在Fragment中添加点击事件切换新的Fragment
- 漫谈程序员系列:你的幸运女神呢
- Web Cache替换算法分析(二)
- 学习设计模式-中介者模式
- PE解析器的编写(三)——区块表的解析
- socket通信简介
- 同余定理的应用
- CDN相关介绍
- 【工业4.0系列谈之五】建设智能工厂 可从这6个方面着手
- 解决Linux系统输入登陆密码正确,但闪回登陆界面,无法登录的问题
- eclipse添加作者时间注释
- 学习设计模式-享元模式
- 简单计算器