获取PE文件的.text节头

时间:2015-03-25 17:02:03

标签: c portable-executable

我正在尝试获取 .text -section的标题。 似乎的工作原理是:

// Get the DOS header.
pDosHeader = (PIMAGE_DOS_HEADER) hMap;

// Get header of first section
pSectionHeader = (PIMAGE_SECTION_HEADER) ((DWORD) hMap + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));

// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);

但我并不完全明白为什么。我原以为最后一条指令必须是:

// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1) * sizeof(IMAGE_SECTION_HEADER);

使指针移动 section-header -wise。

另外,(pNtHeaders->FileHeader.NumberOfSections - 1)真的是 .text -section?

2 个答案:

答案 0 :(得分:3)

原因

pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);

是正确的,pSectionHeader的类型是PIMAGE_SECTION_HEADER。向C中的指针添加整数值时,该值将首先乘以指向的对象的大小(即IMAGE_SECTION_HEADER)。这就是指针运算的工作方式!

您不应该假设链接器放置不同部分的顺序。循环遍历所有节标题会更好,例如将该部分的名称与.text匹配。

此外,我不建议使用sizeof(IMAGE_NT_HEADERS)跳过可选标头。这是因为IMAGE_OPTIONAL_HEADER结构(包含在IMAGE_NT_HEADERS中)以IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];结尾,并且您实际上并不保证PE图像中存在所有数据目录。更好的方法是读取可选标头,并使用NumberOfRvaAndSizes字段确定应跳过多少数据目录以查找节标题表。

最后,我建议您使用结构的IMAGE_XYZ32IMAGE_XYZ64版本,而不仅仅是IMAGE_XYZ,具体取决于您是否要解析PE32(32位)或PE32 +(64位)。否则,您将默认使用系统上默认的体系结构大小。

答案 1 :(得分:0)

给你:

// Get DOS and PE Header
PIMAGE_DOS_HEADER hdos = (PIMAGE_DOS_HEADER)pe_file.data();
PIMAGE_NT_HEADERS hpe = (PIMAGE_NT_HEADERS)((DWORD)hdos + hdos->e_lfanew);

// Get header of first section
DWORD section_offset = (DWORD)hdos + hdos->e_lfanew + sizeof(IMAGE_NT_HEADERS);
PIMAGE_SECTION_HEADER text_section = (PIMAGE_SECTION_HEADER)(section_offset);