Winapi:是否需要在可执行内存映射的文件上调用FlushInstructionCache
WinAPI: Is it needed to call FlushInstructionCache on an executable memory-mapped file?
我编写了一个简短的程序来读取Windows OBJ文件并找到.TEXT部分并在其中运行代码。为此,我对感兴趣的人进行以下Windows API函数调用(完整代码[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);
然后,i然后在文件中找到.TEXT部分,并将指针指向C 中的函数指针,然后简单地调用该函数。这实际上对我有用。
我是否犯了一个错误 我之所 创建可以执行的区域时,调用程序负责通过适当的调用将代码设置在适当的位置,以确保通过适当的拨打拨挡填充缓存相干性。否则,试图从新可执行的区域中执行代码可能会产生不可预测的结果。
我的代码可能会导致CPU在指令缓存中执行旧说明?
MapViewOffile或CreateFileMapping页面上没有这样的注释。
如果仅使用 MapViewOfFile
加载文件容器,则应该没关系。
如果您在内存中修改内容,则需要在执行代码之前刷新指令cache,因为它可能以未修饰的形式存在缓存中,然后可以在没有修改的情况下执行。
我使用这个词可能是因为两件事:
-
取决于处理器体系结构是否检测到即将执行的记忆的写入[某些处理器甚至没有硬件要注册的硬件写入指令caches中的数据 - 因为很少见这不太可能]。
-
,因为很难预测缓存中的内容 - 处理器拥有各种"聪明"的方式来预取和"填充"缓存。
显然,VirtualAlloc
的机会零包含您想要的数据,因此在此提到,因为您始终在执行之前写信。
修改包括"修复绝对地址"(例如,如果您想完成一个要加载一些复杂的项目以执行它的项目,或者在设置Breakpoint时,您必须要做的事情)或通过用x86上的INT 3
指令替换指令。
"修改"的第二种情况是,如果您卸载文件,并加载其他文件(例如,"相同"文件,但重建),在这种情况下,先前执行的代码仍然可能位于缓存,您会得到神秘的"为什么我的更改不做我期望的事情"
- C/C++ - 查询平台相关的换行符(用于内存映射文件)
- 写入映射文件
- 内存映射文件访问非常慢
- 我正在尝试创建一个C++映射,该映射在boost内存映射文件中具有向量值
- 无法从地址打开映射文件
- 为什么 du -sh 输出错误大小的内存映射文件
- 使用 mmap 映射文件中的不同段
- Growing Boost.使用单个写入器的进程间内存映射文件
- 调整窗口内存映射文件的大小,而不会使指针失效
- 映射文件中成员结构的地址
- 与从C++到C#的内存映射文件共享链式结构
- 在 C++ 和 C# 之间共享内存映射文件结构
- 如何使用 Boost 的"mapped_file_sink"类刷新内存映射文件?
- 使用Solaris 64位或Linux 32位到Linux 64位的内存映射文件
- 循环访问提升mapped_region/内存映射文件
- 使用 Win32/WINAPI 通过内存映射文件传输数据
- qtCreator 错误:无法映射文件,errno=22 文件用于架构x86_64?
- 复制存储在内存映射文件中的数组的一部分
- 用于读取输入文件的内存映射文件的安全
- 写入和读取映射文件C++