c++ - C/C++ 在 x86 应用程序中使用 x64 结构参数导入 WinAPI 函数
问题描述
我有一个 x86 windows 应用程序(32 位),我正在导入一个带有 x64 结构参数定义的函数。
有问题的函数是:ImageRvaToSection。当您使用 ImageRvaToSection 时,函数定义会自动具有您的应用程序所需的结构 ( winnt.h );如果您的应用程序是 x86 (32),它使用扩展为 PIMAGE_NT_HEADERS32 的 PIMAGE_NT_HEADERS。
当然,如果您的应用程序是 x64,它使用相同的 PIMAGE_NT_HEADERS,但会扩展为 PIMAGE_NT_HEADERS64。
我需要能够在我的 x86 应用程序中使用 32 和 64 结构参数调用 ImageRvaToSection。
基本上我所做的是:
typedef PIMAGE_SECTION_HEADER(WINAPI* pImageRvaToSection64) (PIMAGE_NT_HEADERS64, PVOID, ULONG);
pImageRvaToSection64 pointerImageRvaToSection64;
pointerImageRvaToSection64 = (pImageRvaToSection64)::GetProcAddress(::GetModuleHandle(L"Dbghelp.dll"),"ImageRvaToSection");
这在我的测试中效果很好,我可以使用 pointerImageRvaToSection64 和 IMAGE_NT_HEADERS64 作为从 32 位应用程序内部调用的参数。
但是,我不知道这样做有多安全?我知道 wow64ext,但我不确定这是否适用于这种情况。
请指教。
解决方案
原始答案MSDN
上没有关于此的评论,但我认为它应该是通用的,因为 PE 格式。请记住,在达到. 因此,该宏是 WoW64 安全的。您需要做的就是遍历并检查传递的 VA 是否在 VA 部分范围内。IMAGE_OPTIONAL_HEADER
IMAGE_FIRST_SECTION(Nt)
ImageFileHeader.NumberOfSections
更新
当我回答时我在移动设备上,但我只是去看看ImageRvaToSection
Windows 10。正如预期的那样,没有架构检查,它适用于两者PE32
并且PE64
文件相同。应该注意的Base
是,甚至没有使用该参数,这可能是由于从那时起的向后兼容性,在这种情况下,这些旧版本的体系结构之间可能存在问题。由于 MSDN 没有关于架构的评论,我不能从技术上保证它对所有以前版本的 Windows 都是安全的。但是,确实没有理由不这样做,特别是因为它在 W10 上是安全的,并且没有任何评论表明这种情况已经改变。
替代方案
正如我在最初的回答中提到的那样,以独立于架构的方式实现自己是微不足道的。下面的代码使用与ImageRvaToSection
我的系统相反的方法,并保证对PE32
和都有效PE64
。
template<typename T>
PIMAGE_SECTION_HEADER ImageRvaToSectionEx(T NtHeaders, uint32_t Rva)
{
auto nt = NtHeaders;
auto num_sections = nt->FileHeader.NumberOfSections;
auto cur_section = IMAGE_FIRST_SECTION(nt);
for (auto i = 0; i < num_sections; ++i, ++cur_section)
{
auto sec_beg = cur_section->VirtualAddress;
auto sec_end = (sec_beg + cur_section->Misc.VirtualSize);
if (Rva >= sec_beg && Rva < sec_end)
return cur_section;
}
return reinterpret_cast<PIMAGE_SECTION_HEADER>(nullptr);
}
推荐阅读
- python - Python-Protobuf 浮点值转换为 fixed64
- javascript - 从字符串中添加单个负数
- node.js - NodeJs Express 使用响应数据渲染同一页面
- powershell - Powershell ForEach-Object 输出
- javascript - Telegraf 从 Telegram API 发送图像
- git - 当我们在vscode中点击“accept both changes”时,合并冲突时会执行哪个命令?
- visual-studio - 如何在 Visual Studio 中调试启动之前强制评估 startarguments
- java - 如何在Spring中为每个类使用抽象实体和条件属性类型WITH表
- reactjs - 创建动态组件而不是复制 Reactjs
- javascript - 角度展开/折叠表格行 - 使用 ng-bootstrap