有没有一种方法可以欺骗.NET JIT编译器运行另一个方法?

7

好的,假设我的应用程序正在将(x86)指令写入内存,使页面可执行等。是否有一种方法可以修改未JITted方法的方法存根,以指向我发出的指令流?

例如:

假设我在内存中创建了一个x86指令流,它执行任意操作。现在,进一步假设我有一个方法'int Target()'。我还没有调用它,因此它尚未编译。是否有一种方法:

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

我知道.NET的几乎所有安全功能都是设计用来防止这种劫持的。但是通过托管API是否可能呢?

5个回答

10

这是通过性能分析API实现的。我从未使用过它,但它在TypeMock中用于类似的目的。

编辑:我认为MSDN博客上有一篇不错的文章,我会去找找看。

编辑2:哎呀,第一个链接


我记得在某个地方看到过“IL 重写”。 - leppie
是的,我正要说那个。看起来只支持IL。 - TraumaPony

6

没问题,你可以做到!

钩取mscorjit的getJit方法。每次有方法需要jitting时都会询问您,您可以传递任何想要的内容。

一些.NET保护程序就是这样工作的。


2
正如你所说,这并不容易,甚至可能是不可能的。如果我没记错的话,代码将包含一个方法的JIT编译器地址,而该方法尚未编译。因此,当您尝试调用此方法时,JIT编译器将执行其工作,并插入到新编译的方法的地址。如果您可以更改此地址,则可能能够插入对自己代码的调用。如何在不被检测到的情况下进行此操作超出了我的能力范围。我当然希望CLR能够检测到这种篡改。
我认为Profiling API在这种情况下不会对您有所帮助(如Leppie所建议的那样),因为您没有尝试修改MSIL。如果您认为有所不同,可以参考这篇文章,因为它描述了TypeMock正在执行的操作。

0

除了能够使用ICorProfiler并在jit之前重写您的方法外,您还可以使用ICorDebug(MDBG具有托管接口)。设置断点,当断点命中时将下一条语句设置为拦截代码。所有这些过程都可以通过代码完成,但实际上非常侵入性,您需要一个“监视器”进程来协调此过程。

另一个值得关注的事情是PostSharp项目,如果应用属性,则可以提供入口和出口方法。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接