修复编译错误C2440:无法将IMAGE_NT_HEADERS64*转换为IMAGE_NT_HEADERS*
错误原因
这个类型转换错误是PE头类型和编译平台不匹配导致的:
Windows头文件中IMAGE_NT_HEADERS是条件编译的类型别名:32位编译环境下它等价于IMAGE_NT_HEADERS32,64位编译环境下等价于IMAGE_NT_HEADERS64。你代码中手动把计算出的地址强转为const IMAGE_NT_HEADERS64*类型,再赋值给const IMAGE_NT_HEADERS*类型的变量时,如果当前项目是32位编译配置,两个指针指向的结构大小、字段偏移完全不同,编译器会直接阻止这个不安全的隐式转换。
修复方案
根据你的开发场景二选一即可:
方案1:适配当前编译架构(注入场景推荐)
直接去掉手动指定的64位类型强转,用IMAGE_NT_HEADERS做统一转换,编译器会自动根据当前目标平台匹配正确的32/64位结构类型:
const IMAGE_NT_HEADERS* ntHeader = reinterpret_cast<const IMAGE_NT_HEADERS*>( reinterpret_cast<const uint8_t*>(dosHeader) + dosHeader->e_lfanew );
这个写法和Windows系统API解析PE头的逻辑一致,不会出现类型不匹配问题,后续访问NT头字段时也不会出现偏移错误。
方案2:固定解析64位PE文件
如果你明确要处理64位PE目标(比如你的DLL只注入64位进程),就把接收变量的类型也改成64位NT头类型,保持左右类型完全一致:
const IMAGE_NT_HEADERS64* ntHeader = reinterpret_cast<const IMAGE_NT_HEADERS64*>( reinterpret_cast<const uint8_t*>(dosHeader) + dosHeader->e_lfanew );
注意事项
- 不要混用32位和64位的NT头指针,否则后续访问
OptionalHeader里的字段(比如映像基址、入口点、节表偏移)时会读错内存位置,轻则拿到错误数值,重则触发内存访问崩溃。 - 如果要写同时支持解析32、64位PE的通用逻辑,需要先读取NT头开头的
Signature和OptionalHeader.Magic字段判断PE位宽,再分别强转为对应类型处理,不要直接硬编码类型转换。
内容的提问来源于stack exchange,提问作者end41r
相关产品推荐
相关产品推荐

