Sh4DoW321 发表于 2023-10-14 02:54

Hook .Net JIT ?

Hi friends
For example I have a compiled C# program that it has a Fucntion with two string arguments like below code :
static string MyFunc(string a, string b)
{
   return a + " *** " + b;
}
Now I am gonna write C++ program hook JIT and log MyFunc arguments value , I mean value of a and b variables
How can I do that ?
Thanks

Aen920 发表于 2023-10-14 09:14

周易 发表于 2023-10-14 11:38

本帖最后由 周易 于 2023-10-14 12:09 编辑

Hooking into the JIT compiler for .NET to monitor and log function arguments can be quite complex, as there is no straightforward way provided. Typically, you would need to use the profiling API (`ICorProfilerInfo`) provided by the CLR (Common Language Runtime), which allows you to monitor and manipulate .NET applications as they are running.

If you insist on hooking into the JIT compiler, you should have a deep understanding of not only the .NET CLR and its internal workings but also the target platform's architecture and machine code.

The (https://godbolt.org/) can be very useful when working with such low-level aspects of programming.

```cs
using System;

class Program
{
    static string MyFunc(string a, string b)
    {
      return a + " *** " + b;
    }
}
```

Considering instruction set amd64 and .NET 7.0.105 on Linux. A call to jitted `MyFunc` may look like:

```asm
       mov      rdi, string_handle
       mov      rdi, gword ptr
       mov      rsi, string_handle
       mov      rsi, gword ptr
       call   
```

Here `rdi` and `rsi` are used to pass parameters.This refers to the System V AMD64 ABI used by most Unix-like systems, where `rdi` and `rsi` are used for the first two arguments. On Windows, however, it would be `rcx` and `rdx`.

Also, it's very important to be aware of the impact of function inlining when dealing with JIT compilation. If `MyFunc` was inlined, you wouldn't see a `call` instruction for `MyFunc` in your assembly code.

In C#, you can prevent a method from being inlined by the JIT compiler using the `MethodImpl` attribute with the `MethodImplOptions.NoInlining` flag.

Here is a sample (https://frida.re/) script on Windows to hook into .NET Framework jit. You may manually add some code to check the `methodInfo_ILCode` and `Interceptor.attach` the `entryAddress`.

```js
(function () {
    let p_LoadLibraryExW = Module.getExportByName("kernel32.dll", "LoadLibraryExW");
    Interceptor.attach(p_LoadLibraryExW, {
      onEnter: function (args) {
            this.lpLibFileName = args;
      },
      onLeave: function (retval) {
            if (retval === 0) {
                return;
            }
            let fileName = this.lpLibFileName.readUtf16String().split("\\").reverse();
            if (fileName === "clrjit.dll") {
                let p_getJit = Module.getExportByName("clrjit.dll", "getJit");
                let getJit = new NativeFunction(p_getJit, "pointer", []);
                let cilJit = getJit();
                let cilJit_vftable = cilJit.add(0x0).readPointer();
                let p_compileMethod = cilJit_vftable.add(0x0).readPointer();
                Interceptor.attach(p_compileMethod, {
                  onEnter: function (args) {
                        this.self = args;
                        this.compHnd = args;
                        this.methodInfo = args;
                        this.flags = args;
                        this.entryAddress = args;
                        this.nativeSizeOfCode = args;
                  },
                  onLeave: function (retval) {
                        if (retval === 0) { //CORJIT_OK
                            let methodInfo_ftn = this.methodInfo.add(0x0).readPointer();
                            let methodInfo_scope = this.methodInfo.add(0x4).readPointer();
                            let methodInfo_ILCode = this.methodInfo.add(0x8).readPointer();
                            let methodInfo_ILCodeSize = this.methodInfo.add(0xc).readUInt();
                            console.log("ftn =", methodInfo_ftn);
                            console.log("scope =", methodInfo_scope);
                            console.log("entryAddress =", this.entryAddress.readPointer());
                            console.log("nativeSizeOfCode =", this.nativeSizeOfCode.readUInt());
                            console.log(methodInfo_ILCode.readByteArray(methodInfo_ILCodeSize));
                            console.log();
                        }
                  }
                });
            }
      }
    });
}());
```

苏紫方璇 发表于 2023-10-14 11:54

以前使用过一次这种hook,能用,但是不太好用,当时抄的这篇文章的代码,可以参考一下
https://blog.csdn.net/xfgryujk/article/details/79053312

Sh4DoW321 发表于 2023-10-14 19:31

周易 发表于 2023-10-14 11:38
Hooking into the JIT compiler for .NET to monitor and log function arguments can be quite comple ...

Thanks friend , but is it possible in C++ code ?

周易 发表于 2023-10-14 23:12

Sh4DoW321 发表于 2023-10-14 19:31
Thanks friend , but is it possible in C++ code ?

Yes it is possible to implement in C++. (https://frida.re/) has C API.

See <https://frida.re/docs/c-api/>.

Sh4DoW321 发表于 2023-10-16 09:40

I mean write C++ code inside Visual Studio expect frida
页: [1]
查看完整版本: Hook .Net JIT ?