Fsm*_*smv 6 c++ windows winapi memory-mapped-files self-modifying
我写了一个简短的程序来读取一个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);
Run Code Online (Sandbox Code Playgroud)
然后,我在文件中找到.text部分,并将指针转换为C++中的函数指针,并简单地调用该函数.这实际上似乎对我有用.
我是否在映射到文件的虚拟内存范围内调用FlushInstructonCache时出错?
我问这个是因为我最近阅读的是VirtualAlloc文档,它在底部注明:
在创建一个可执行的区域时,调用程序负责通过在代码设置到位后适当调用FlushInstructionCache来确保缓存一致性.否则,尝试从新的可执行区域执行代码可能会产生不可预测的结果.
我的代码是否可能导致CPU在指令缓存中执行旧指令?
MapViewOfFile或CreateFileMapping页面上没有这样的注释.
如果你只使用文件内容加载到内存中MapViewOfFile,没有它应该没问题.
如果修改内存中的内容,则需要在执行代码之前刷新instructioncache,因为它可能以未修改的形式存在于缓存中,然后可以在不进行修改的情况下执行.
我使用MAY这个词是因为两件事:
这取决于处理器架构,处理器是否检测到它将要执行的存储器的写入[某些处理器甚至没有硬件来注册写入指令缓存中的数据 - 因为它非常罕见,因此非常不可能].
因为很难预测缓存中可能存在的内容 - 处理器具有各种"聪明"的预取方式,并且通常可以"填充"缓存.
显然,VirtualAlloc没有机会包含你想要的数据,因此在那里提到它是因为你总是在执行之前写入它.
修改包括"修复绝对地址"(例如,如果要完成加载复杂的项目以执行它,则必须执行的操作),或者如果编写调试器,则在通过替换设置断点时INT 3有关x86 指令的指令.
第二种"修改"的情况是,如果你卸载文件,并加载一个不同的文件(例如"同一"文件,但重建,例如),在这种情况下,先前执行的代码可能仍在缓存中,并且你得到了神秘的"为什么我的改变不符合我的期望"
| 归档时间: |
|
| 查看次数: |
1048 次 |
| 最近记录: |