PE文件解析-区段头
有几个区段,就会有几个对应的区段头。区段头存放区段的信息,相当于一本书的目录。
如何访问区段头
通过DOS头拿到NT头,然后再通过NT头拿到标准PE头,标准PE头中存放了PE头的大小,然后通过内存偏移来找到区段头。
也可以利用Windows封装的结构体来处理
void CPeUtil::PrintSectionHeaders()
{
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
for (int i = 0; i < this->pFileHeader->NumberOfSections; i++)
{
char name[9]{ 0 };
for (int i = 0; i < 8; i++)
{
name[i] = pSectionHeader->Name[i];
}
std::cout << "区段名称:" << name<<std::endl;
pSectionHeader++;
}
}
区段头解析
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_SIZEOF_SECTION_HEADER 40 #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //节表名称.大小8字节.一般情况下是以"\0"结尾的ASCII码字符串.内容可自定义. union { DWORD PhysicalAddress; //联合体. DWORD VirtualSize; //节在内存中按照内存对齐前的大小(该值可以不准确). } Misc; DWORD VirtualAddress; //(RVA)节在内存中的偏移地址.加上ImageBase才是在内存中的地址. DWORD SizeOfRawData; //节在文件中按照文件对齐后的大小. DWORD PointerToRawData; //(FOA)节在文件中的偏移地址. DWORD PointerToRelocations; //.OBJ文件中使用,指向重定位表的指针. DWORD PointerToLinenumbers; //行号表的偏移,提供调试. WORD NumberOfRelocations; //.OBJ文件中使用,重定位项数目. WORD NumberOfLinenumbers; //行号表中行号的数量. DWORD Characteristics; //节的属性. } IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER;
该结构体参考:IMAGE_SECTION_HEADER (winnt.h) - Win32 应用 |微软文档 (microsoft.com)
PE文件解析-各种头解析代码实现