【问题标题】:How is JIT compiled code injected in memory and executed?JIT编译后的代码是如何注入内存并执行的?
【发布时间】:2011-03-22 07:49:41
【问题描述】:

“考虑一个典型的 Windows x86 或 AMD64架构,内存为 分为可执行部分 不能写入和数据部分 可以写但不能 执行(想想 DEP)。”

"JIT 在内存中编译方法, (通常)不存储任何东西 磁盘,而是将它移动到哪里 下一条指令指针可以到达 它,改变当前指令 指针(指向 JIT)指向 到新生成的代码,然后 执行它。”

这两段虽然有点过于简单化了,但基本上是我对JIT和Windows内存模型的理解。我也知道,当我尝试手动将一些可执行代码复制到内存中并尝试执行时,我通常会做不到(除非使用 DLL 注入)。

JIT 设计者是如何克服这个障碍的?他们是使用 ring-0 驱动程序还是在用户模式下完成所有操作?

【问题讨论】:

    标签: .net clr jit


    【解决方案1】:

    只需使用 Windows VirtualProtect() API 函数即可完成。它改变了虚拟内存页的属性。从 PAGE_READWRITE 开始,JIT 编译器可以将机器代码写入 PAGE_EXECUTE_READ 以便执行。这样做不需要特殊权限,因为该页面由同时运行 JIT 编译器的进程拥有。

    【讨论】:

    • 真的,那么简单吗?说得通。 (OT) 啊,我记得,上次我需要注入一些不在我自己进程中的东西(即删除当前正在运行的可执行文件,您需要先卸载可执行文件,典型的鸡/蛋问题)。
    • @Hans:进一步阅读,我想知道这与 Social MSDN post 有何关系,解释说您需要管理员权限才能使用 VirtualProtect 更改标志并声称它不能那样工作.对于 ActionScript,同样的原理也适用于 VirtualAllocas apparently shown by this blogger(他的名字弄错了,见他的第三张图片的下标)。这两个帖子都让我假设它是VirtualAlloc。您对此有何看法?
    • @Abel:看起来很眼熟。不,我在那篇文章中指出不需要管理员权限。 OP 同意了。
    • @Hans:是的,我反应很快。浏览VirtualProtect 也没有提到这一点。请注意,在 SSCLI 中,我没有找到 fjitcompiler.cpp 中使用的 VirtualProtect,只有 VirtualAlloc。 VirtualProtect 在hosting.cpp 中经常被重新定义/未定义(到Dont_Use_VirtualProtectlol)。最后,它似乎归结为对IHostMemoryManager->VirtualProtect 的调用,如果可用,否则调用::VirtualProtect(Win32 API)(这就是你所说的)
    • @Hans:您是否碰巧知道 CLR JIT 在编译完成时是否确实删除了对包含生成代码的页面的写访问权限?还是留给他们PAGE_EXECUTE_READWRITE 访问权限?
    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2011-03-18
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多