我正在尝试获取 .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?
答案 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_XYZ32
和IMAGE_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);