【问题标题】:Is there a way to trick the .NET JIT compiler into running another method?有没有办法欺骗 .NET JIT 编译器运行另一种方法?
【发布时间】:2010-09-18 19:44:05
【问题描述】:

好的,假设我的应用程序正在将 (x86) 指令发送到内存中,使页面可执行等。有没有办法改变非 JIT 方法的方法存根以指向我发出的指令流?

例如:

假设我在内存中创建了一个 x86 指令流,它可以做一些任意的事情。现在,进一步假设我有一个方法'int Target()'。我还没有调用它,所以它还没有编译。有没有办法:

  1. 获取指向 Target 存根的指针
  2. 让它指向我发出的指令流。

我意识到 .NET 的几乎每一个安全功能都旨在防止这样的劫持。但是可以通过托管 API 来实现吗?

【问题讨论】:

    标签: .net security clr jit dynamic-execution


    【解决方案1】:

    这可以通过 Profiling API 实现。我从未使用过它,但它在 TypeMock 中用于类似目的。

    编辑:我认为 MSDN 博客上有一篇不错的帖子,会去寻找它。

    编辑 2:Doh,first hit

    【讨论】:

    • 我记得它在某处有“IL重写”。
    • 是的。我正要这么说。看起来它只是 IL。
    【解决方案2】:

    是的,你可以做到!

    hook mscorjit 的 getJit 方法。每次都会询问您是否有任何方法需要jitting。你可以通过任何你想要的。

    一些 .NET 保护器的工作原理是这样的。

    【讨论】:

      【解决方案3】:

      正如你所说,这并不容易,甚至不可能。如果我没记错的话,代码将包含一个方法的 JIT 编译器的地址,该方法尚未编译。因此,当您尝试调用此方法时,JIT 编译器将完成其工作并将地址插入新编译的方法。如果您可以更改此地址,则可以插入对您自己的代码的调用。你如何在不被发现的情况下做到这一点超出了我的范围。我当然希望 CLR 能够检测到这种篡改。

      我认为 Profiling API 在这种情况下不会帮助您(正如 Leppie 所建议的那样),因为您没有尝试修改 MSIL。如果您不这么认为,this article 可能有用,因为它描述了您必须做什么才能实现 TypeMock 正在做的事情。

      【讨论】:

        【解决方案4】:

        除了能够使用 ICorProfiler 并在它运行前重写您的方法之外,您还可以使用 ICorDebug(MDBG 已托管接口)。设置断点,当断点命中时,将下一条语句设置为您的拦截代码。所有这些过程都可以从代码中完成,但是非常具有侵入性,您需要一个“观察者”过程来协调它。

        另一件值得关注的事情是PostSharp 项目,如果您应用属性,它会为您提供进入和退出方法。

        【讨论】:

          【解决方案5】:

          我不会尝试直接弄乱内存,我甚至不确定是否有可能,您可以使用分析器 API - 那里有一些示例,但没有真正的文档。 看看 MSDN 杂志文章 - Rewrite MSIL Code on the Fly with the .NET Framework Profiling API

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-09
            • 1970-01-01
            • 1970-01-01
            • 2020-01-22
            • 2019-04-20
            • 1970-01-01
            相关资源
            最近更新 更多