gpt4 book ai didi

c++ - WinAPI:是否需要在可执行内存映射文件上调用 FlushInstructionCache?

转载 作者:可可西里 更新时间:2023-11-01 13:23:31 28 4
gpt4 key购买 nike

我编写了一个简短的程序来读取 Windows obj 文件并找到 .text 部分并运行其中的代码。为此,我进行了以下 Windows API 函数调用(Full code [gist.github.com],对于那些感兴趣的人):

HANDLE FileHandle = CreateFile("lib.obj",
GENERIC_READ | GENERIC_EXECUTE,
FILE_SHARE_READ, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

HANDLE MappingHandle = CreateFileMapping(FileHandle, 0, PAGE_EXECUTE_READ, 0, 0, 0);

void *Address = MapViewOfFile(MappingHandle, FILE_MAP_EXECUTE | FILE_MAP_READ,
0, 0, 0);

然后我找到文件中的 .text 部分,并将指向代码的指针转换为 C++ 中的函数指针,然后简单地调用该函数。这实际上似乎对我有用。

是不是我没有在映射到文件的虚拟内存范围内调用 FlushInstructonCache 时出错?

我问这个是因为我最近正在阅读 VirtualAlloc文档及其底部注释:

When creating a region that will be executable, the calling program bears responsibility for ensuring cache coherency via an appropriate call to FlushInstructionCache once the code has been set in place. Otherwise attempts to execute code out of the newly executable region may produce unpredictable results.

我的代码是否可能导致 CPU 执行指令缓存中的旧指令?

MapViewOfFile上没有这样的注释或 CreateFileMapping页面。

最佳答案

如果您只使用 MapViewOfFile 将文件内容加载到内存中,那么没有它应该没问题。

如果您修改内存中的内容,您需要在执行代码之前刷新指令缓存,因为它可能以未修改的形式存在于缓存中,然后可能在没有您修改的情况下执行。

我使用 MAY 这个词是因为两件事:

  1. 处理器是否检测到对即将执行的内存的写入取决于处理器架构[有些处理器甚至没有硬件来注册对指令缓存中数据的写入——因为这种情况非常罕见,以至于这不太可能]。

  2. 因为很难预测缓存中可能有什么 - 处理器有各种“聪明”的方式来预取和一般的“填充”缓存。

显然,VirtualAlloc 包含您想要的数据的可能性为零,因此在此处提及它是因为您总是在执行之前写入它。

修改包括“修复绝对地址”(如果你想完成一个加载复杂的东西来执行它的项目,你必须做的事情),或者如果你写一个调试器,当你设置一个断点通过在 x86 上用 INT 3 指令替换指令。

“修改”的第二种情况是,如果您卸载文件,然后加载一个不同的文件(例如,可能是“相同”文件,但重新构建),在这种情况下,先前执行的代码可能仍在缓存,你会得到神秘的“为什么我的更改没有达到我的预期”

关于c++ - WinAPI:是否需要在可执行内存映射文件上调用 FlushInstructionCache?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42479247/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com