-
-
[原创]CLR v4 HOOK JIT 的一些变化
-
发表于:
2012-8-6 11:58
15564
-
[原创]CLR v4 HOOK JIT 的一些变化
新人发帖,高手们就不要看了,过程很简单,仅作抛砖引玉。

网上有很多JIT Injection的文章,但都是针对.net framework runtime 2.0的。我也用这样的JIT Injection做过一些自己的小程序,比如Display Calls,以便在破解.net assembly的过程中,找到调用顺序。但是到了CLR 4.0,Display Calls不起作用了。于是经过研究,终于调试好了Display Calls的程序。下面是整个的研究过程:
1. 在网上搜索 .net 4 compileMethod,可以发现getJit这个方法现在在clrjit.dll中,而不是在原来的mscorjit.dll中。于是修改GetModuleHandle处代码为:
hJitMod = GetModuleHandle(“clrjit.dll”);
2. ICorJitInfo类的变化。
如果不想得到method的name,上面的修改足以让Display Calls程序跑起来,但我们的目的是显示即时编译的方法和所在的类名,因此必须调整这个类。
为什么调整这个类呢?首先让我们看看在runtime 2.0下,调用我们自己的compileMethod时,这个类是怎样的一个内存分布。首先用windbg载入Display Calls的程序,在my_compileMethod上设置断点,当程序中断后,查看参数:

根据x64程序的调用约定,第一个参数放到rcx(xmm0)中,第二个参数放到rdx(xmm1)中,第三个参数放到r8(xmm2)中,第四个参数放到r9(xmm3)中,剩下的参数从左向右依次放到堆栈上。用dv命令也可以查看参数,但是不知道为什么和寄存器中的不一样,且dv显示的地址也是不正确的。
而我们是要调用ICorJitInfo接口中的getMethodName,ICorJitInfo是第二个参数,因此它的地址在rdx中,调用dps @rdx可以显示ICorJitInfo实现类的vftable地址:

我们可以发现具体实现类是CEEJitInfo,虚函数表地址是7fef9537d60,接着继续dps 7fef9537d60:

虚表中的方法是顺序排列的,getMethodName相对虚表基址的偏移量是7fef9537de0-7fef9537d60=0x80。
接下来我们看看runtime 4.0下的情况,滤过一些过程,直接看看传入my_compileMethod的第二个参数及它的虚表:

实际虚表地址是7fef8f890c0。再次使用dps命令:
0:000> dps 7fef8f890c0 l 100
000007fe`f8f890c0 000007fe`f88fe4d0 clr!CEEInfo::getMethodAttribs
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!