获取PE文件的.text节头

问题描述 投票:0回答:3

我正在尝试获取 .text 部分的标题。 似乎有效的是:

// 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);

以便指针按节标题方向移动。

另外,

(pNtHeaders->FileHeader.NumberOfSections - 1)
真的是.text部分吗?

c portable-executable
3个回答
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 位)。否则,您将默认使用系统上默认的架构大小。


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);

0
投票

.text
部分并不总是
.text
。 请注意这一点:

  1. PE 文件部分有一个

    IMAGE_SCN_CNT_CODE
    标志。为什么不使用它?

  2. 请注意

    sizeof(IMAGE_NT_HEADERS)
    仅获取分配所需的字节,请改用
    IMAGE_NT_HEADERS->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)

检查代码(C代码):

PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS)(hMod + ((PIMAGE_DOS_HEADER)hMod)->e_lfanew);
PIMAGE_SECTION_HEADER SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
PIMAGE_SECTION_HEADER codeSection2;
for (WORD SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++)
{
    PIMAGE_SECTION_HEADER SectionHeader = &SectionHeaders[SectionIndex];
    if (SectionHeader->Characteristics & IMAGE_SCN_CNT_CODE){
        codeSection2 = SectionHeader;
        break;
    }
}
IMAGE_SECTION_HEADER codeSection = *codeSection2;
© www.soinside.com 2019 - 2024. All rights reserved.