OptionalHeader

时间:2018-08-14 15:24:37

标签: c reverse-engineering portable-executable

我正在研究PE解析器,仅出于学习目的。 正如文档所说,第一节标题应该紧接在OptionalHeader之后,但就我而言,我在第一标题之前有很多空数据。 这是我的代码,用于计算应在第一个节中放置的位置:

IMAGE_NT_HEADERS* inth = get_nt_headers(buffer);

DWORD optional_headers_size = inth->FileHeader.SizeOfOptionalHeader;
DWORD calculated_ptr = (DWORD)inth + optional_headers_size;

printf("Pointer to IMAGE_NT_HEADERS: %p\n", inth);

printf("Size of optional headers: %x\n", optional_headers_size);

printf("Pointer to first section header: %p\n", calculated_ptr);

BYTE* pointer = (BYTE*)calculated_ptr;

当我遍历“指针”时,我看到了很多可为空的数据,所以这不是我需要的部分。 PEView或Hexplorer也显示空数据。这是为什么? 数据的“空”部分大约需要24个字节。

我分析的应用程序是一个简单的HelloWorld.exe。

我对另一件事感到困惑。

在FileHeader中,我设置了13个部分,但是如果我在IMAGE_OPTIONAL_HEADER中查看PEView,我会看到16个部分,但是最后3个部分具有任何分配的值,这意味着RVA和Size设置为0。 这些部分是:DELAY_IMPORT_DESCRIPTORS,CLI_HEADER,但是最后一个没有任何名称。

我计算出这最后三个部分的大小为24个字节。 这和我之前提到的完全一样。

那么,如何计算IMAGE_SECTION_HEADER的解雇率在哪里?

问题已解决,但我不确定我的解决方案。

DWORD padding = (IMAGE_NUMBEROF_DIRECTORY_ENTRIES - inth->FileHeader.NumberOfSections) * sizeof(IMAGE_DATA_DIRECTORY);
DWORD calculated_ptr = (DWORD)inth + padding + optional_headers_size;

1 个答案:

答案 0 :(得分:0)

首先-切勿在位置指针上使用DWORD。这是错误。当指针4或8时,DWORD始终为4字节大小。代码如

DWORD calculated_ptr = (DWORD)inth + optional_headers_size;

总是错误的。您可以使用DWORD_PTR(恰好是指针大小)代替DWORD

然后SizeOfOptionalHeader很容易理解IMAGE_OPTIONAL_HEADER的大小,而IMAGE_NT_HEADERS的大小是{strong>一部分。但是这样的代码

DWORD_PTR calculated_ptr = (DWORD_PTR)inth + inth->FileHeader.SizeOfOptionalHeader;使用SizeOfOptionalHeader作为IMAGE_NT_HEADERS的大小。您只需将IMAGE_NT_HEADERS的大小和IMAGE_OPTIONAL_HEADER的大小混为一谈

因此正确的解决方案将是

    PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)(
        (ULONG_PTR)&inth->OptionalHeader + inth->FileHeader.SizeOfOptionalHeader);

不需要将SizeOfOptionalHeader添加到inth(地址PIMAGE_NT_HEADERS)上,而是添加&inth->OptionalHeader

或更好地使用PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(inth);

IMAGE_FIRST_SECTION-这是winnt.h中定义的ready宏,具有与(PIMAGE_SECTION_HEADER)((ULONG_PTR)&inth->OptionalHeader + inth->FileHeader.SizeOfOptionalHeader);相同的作用(产生相同的代码)