Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

可以支持.net core吗 #21

Open
hxbb00 opened this issue Jun 13, 2020 · 3 comments
Open

可以支持.net core吗 #21

hxbb00 opened this issue Jun 13, 2020 · 3 comments

Comments

@hxbb00
Copy link

hxbb00 commented Jun 13, 2020

如题,需要在.net core中使用,可以发布.net core nuget包吗?

@mchudie
Copy link

mchudie commented May 10, 2023

同问,作者好像不在了?没有见到关于项目的任何回复

@labbbirder
Copy link

labbbirder commented Apr 16, 2024

不出意外应该是不支持的。根据仓库动态我猜测这个最开始为.Net Framewrok设计的。然而,在dotnet/runtime仓库中,RuntimeMethodHandle.Value对应的MonoMethod*+8字节后并不是函数入口地址。

如果想要支持需要改写目标地址,获取ValuePtr(MonoMethod*)后,lookup_method(MonoMethod*)能获取到JitInfo*,而lookup_method需要根据code hash查表。遗憾的是lookup_method并不是export function

see https://github.com/dotnet/runtime/blob/main/src/mono/mono/mini/mini-runtime.c#L1908 入口查找代码
see https://github.com/dotnet/runtime/blob/8aea53e25f1e78bfbc31f91c6342177eb548eaa5/src/mono/mono/metadata/jit-info.h#L200 JitInfo结构体

好在发现了一个mono_jit_info_table_find(MonoDomain*,void*)方法,可以通过ftnptr获取jitInfo。第一个参数接收MonoDomain,直接使用AppDomain.CurrentDomain肯定是不行的,需要拿到底层对象的地址,这就需要另外一个mono_domain_get函数。

最终的代码如下,可供参考:

// Unity 编辑器环境
[DllImport("mono-2.0-bdwgc", EntryPoint = "mono_jit_info_table_find", CharSet = CharSet.Unicode)]
extern static IntPtr FindJitInfo(IntPtr ptrDomain, IntPtr ptrFunc);

[DllImport("mono-2.0-bdwgc", EntryPoint = "mono_domain_get", CharSet = CharSet.Unicode)]
extern static IntPtr GetDomain();


static unsafe void SetFunctionPtr(MethodInfo mi,nint addr)
{
    RuntimeHelpers.PrepareMethod(mi.MethodHandle);
    var monoDomain = GetDomain();
    var funcPtr = mi.MethodHandle.GetFunctionPointer();
    var jitInfoPtr = (int*)FindJitInfo(monoDomain, funcPtr).ToPointer();
    jitInfoPtr += IntPtr.Size / 4 * 2;
    *(nint*)jitInfoPtr = addr; // overwrite me!
}

测试代码:

public static void Test1()
{
    Debug.Log("Test1");
}

public static void Test2()
{
    Debug.Log("Test2");
}

[InitializeOnLoadMethod]
static void HookMethods()
{
    var mi1 = ((Action)Test1).Method;
    var mi2 = ((Action)Test2).Method;
    RuntimeHelpers.PrepareMethod(mi1.MethodHandle);
    RuntimeHelpers.PrepareMethod(mi2.MethodHandle);
    SetFunctionPtr(mi1, mi2.MethodHandle.GetFunctionPointer());
    Test1(); // output: Test2
}

纯C#环境同理,需要判断下运行时类型,如果是mono或.net core,就执行此逻辑。需要根据实际情况修改入口点。

This was referenced Apr 17, 2024
@labbbirder
Copy link

btw, 可以参考MonoHook的实现,不修改入口,直接修改originMethod jit code。也是一个可行的方法。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants