获取 PE 文件的 .text 部分 header
Getting .text section header of PE file
我正在尝试获取 .text 部分的 header。 似乎起作用的是:
// 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 部分吗?
的原因
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);
是正确的,就是pSectionHeader
是PIMAGE_SECTION_HEADER
类型。当您在 C 中将一个整数值添加到一个指针时,该值将首先乘以所指向的 object 的大小(即 IMAGE_SECTION_HEADER
)。这就是指针算法的工作原理!
您不应假设链接器放置不同部分的顺序。最好遍历所有 header 部分,例如将部分名称与 .text
.
匹配
此外,我不建议使用 sizeof(IMAGE_NT_HEADERS)
来跳过可选的 header。这是因为 IMAGE_OPTIONAL_HEADER
结构(包含在 IMAGE_NT_HEADERS
中)以 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
结尾,您实际上无法保证所有数据目录都存在于 PE 映像中。更好的方法是读取可选的 header,并使用 NumberOfRvaAndSizes
字段来确定您应该跳过多少个数据目录以找到 header table.[=24 部分=]
最后,我建议您使用结构的 IMAGE_XYZ32
和 IMAGE_XYZ64
版本,而不仅仅是 IMAGE_XYZ
,这取决于您是否要解析 PE32 (32-位)或 PE32+(64 位)。否则,您将默认使用系统默认的体系结构大小。
给你:
// 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);
我正在尝试获取 .text 部分的 header。 似乎起作用的是:
// 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 部分吗?
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);
是正确的,就是pSectionHeader
是PIMAGE_SECTION_HEADER
类型。当您在 C 中将一个整数值添加到一个指针时,该值将首先乘以所指向的 object 的大小(即 IMAGE_SECTION_HEADER
)。这就是指针算法的工作原理!
您不应假设链接器放置不同部分的顺序。最好遍历所有 header 部分,例如将部分名称与 .text
.
此外,我不建议使用 sizeof(IMAGE_NT_HEADERS)
来跳过可选的 header。这是因为 IMAGE_OPTIONAL_HEADER
结构(包含在 IMAGE_NT_HEADERS
中)以 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
结尾,您实际上无法保证所有数据目录都存在于 PE 映像中。更好的方法是读取可选的 header,并使用 NumberOfRvaAndSizes
字段来确定您应该跳过多少个数据目录以找到 header table.[=24 部分=]
最后,我建议您使用结构的 IMAGE_XYZ32
和 IMAGE_XYZ64
版本,而不仅仅是 IMAGE_XYZ
,这取决于您是否要解析 PE32 (32-位)或 PE32+(64 位)。否则,您将默认使用系统默认的体系结构大小。
给你:
// 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);