问题描述
PIMAGE_NT_HEADERS ntheaders = (PIMAGE_NT_HEADERS)(PCHAR(virtualpointer) + PIMAGE_DOS_HEADER(virtualpointer)->e_lfanew);
在上面的代码中,virtualpointer
指向加载了 PE 文件的内存位置。
为什么 virtualpointer
前面的括号里是 PIMAGE_DOS_HEADER
?
它是如何处理指针的,e_lfanew
是如何获取它的值的?
我理解更大的图景,最终,ntheaders
获得了一个内存地址,该地址指向 0x3c
所在的位置 NT_HEADER
,但是代码是如何工作的?幕后发生了什么?
解决方法
type(value)
是一个 函数风格 类型转换,而 (type)valu
是一个 C 风格 类型转换。但它们都只是类型转换(无论如何,对于此代码而言)。
所以,在这个声明中:
PIMAGE_NT_HEADERS ntheaders = (PIMAGE_NT_HEADERS)(PCHAR(virtualpointer) + PIMAGE_DOS_HEADER(virtualpointer)->e_lfanew);
-
PIMAGE_DOS_HEADER(virtualpointer)
将virtualpointer
类型转换为IMAGE_DOS_HEADER*
指针。我们称之为dos
。 -
PCHAR(virtualpointer)
将virtualpointer
类型转换为char*
指针。我们称之为pc
。 -
pc + dos->e_lfanew
使用指针算法将pc
的值增加char
的数量(即字节,在这种情况下)在e_lfanew
中指定,它包含一个IMAGE_NT_HEADERS
结构从 PE 开始的偏移量。 -
(PIMAGE_NT_HEADERS)(pc + dos->e_lfanew)
将该算术的结果类型转换为IMAGE_NT_HEADERS*
指针。
因此,代码只是取存储在virtualpointer
中的起始地址,读取位于该内存前面的e_lfanew
的{{1}}字段,向前推进指定的数字字节,然后访问位于该新位置的 IMAGE_DOS_HEADER
。
您应该阅读An In-Depth Look into the Win32 Portable Executable File Format了解更多详情。