考虑一个典型的 Windows x86 或 AMD64 架构,内存被划分成可执行部分和数据部分。可执行部分不能被写入,数据部分可以被写入但不能被执行(DEP)。JIT 在内存中编译方法,并且通常不将任何内容存储到磁盘上,而是将其移动到下一个指令指针可以到达的位置,将当前指令指针(指向 JIT)更改为指向新生成的代码,然后执行它。这两段话虽然有点过于简单化,但基本解释了JIT和Windows的内存模型。我还知道,当我试图手动复制一些可执行代码到内存中并尝试执行它时,通常情况下无法执行(除非使用 DLL 注入)。JIT 设计者是如何克服这个障碍的?他们使用 ring-0 驱动程序还是在用户模式下完成所有操作呢?
VirtualProtect
更改标志,并声称它不能以这种方式工作。对于ActionScript,相同的原理适用于VirtualAlloc
,正如这位博主所示(他弄错了名称,请参见他的第三张图片的下标)。两篇文章都让我认为应该使用VirtualAlloc
。你对此有什么想法? - AbelVirtualProtect
,也没有提到这一点。请注意,在SSCLI中,我没有在fjitcompiler.cpp中找到使用VirtualProtect,只有VirtualAlloc。VirtualProtect在hosting.cpp中经常被重新定义/未定义(变成Dont_Use_VirtualProtect
哈哈)。最后,如果可用,则似乎归结为调用IHostMemoryManager->VirtualProtect
,否则将调用Win32 API的::VirtualProtect
(这就是你说的)。 - Abel