c# 更改方法的指针 .NET 3.5 [英] c# changing method's pointers .NET 3.5

查看:21
本文介绍了c# 更改方法的指针 .NET 3.5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在运行时替换插件加载器中的方法(例如 Bukkit for Minecraft).在此实例中,我无法直接修改程序集文件.整个目的是能够知道何时调用方法.并在必要时取消它们.加载插件后,我运行以下代码:

I am trying to replace a method in a plugin loader(Like Bukkit for Minecraft) during run-time. I cannot modify the assembly file directly in this instance. The whole purpose is to be able to tell when the methods are being called. And cancel them if necessary. Once my plugin is loaded I run the following code:

public static void PluginLoaded()
{
    replace();
}       

public static void replace()
{
    MethodInfo oldMethod, newMethod;
    oldMethod = typeof(<other assembly>).GetMethod("<method name>", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic,null,new Type[]{typeof(ushort)},null);
    newMethod = typeof(NewEvents).GetMethod("<method name>", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(ushort) }, null);
    RuntimeHelpers.PrepareMethod(oldMethod.MethodHandle);
    RuntimeHelpers.PrepareMethod(newMethod.MethodHandle);

    ReplaceInner(oldMethod, newMethod);
}

static void ReplaceInner(MethodInfo methodToReplace, MethodInfo methodToInject)
{
    unsafe
    {
        if (IntPtr.Size == 4)
        {
            int* inj = (int*)methodToInject.MethodHandle.Value.ToPointer() + 2;
            int* tar = (int*)methodToReplace.MethodHandle.Value.ToPointer() + 2;
            *tar = *inj;
        }
        else
        {
            ulong* inj = (ulong*)methodToInject.MethodHandle.Value.ToPointer() + 1;
            ulong* tar = (ulong*)methodToReplace.MethodHandle.Value.ToPointer() + 1;
            *tar = *inj;
        }
    }
}

它工作正常,直到原始程序尝试调用更改后的方法.当它这样做时,整个程序停止,我得到一个访问波动.我该如何解决这个问题?

It works fine until the original program tries to call the changed method. When it does this the whole program stops and I get a access volation. How do I fix this?

推荐答案

您提供的功能特定于从 .Net 4.0 版开始的 CLR 的内存映射.以下是您的选择:

The functionality you have provided is specific for the memory mapping of the CLR starting in .Net version 4.0. Here are your options:

选项 1. 升级您机器上的 .NET Framework.这应该可以解决您的问题,而无需升级 Visual Studio.https://www.microsoft.com/en-us/download/details.aspx?id=42643

Option 1. Upgrade the .NET Framework on your machine. This should fix your issue without the need to upgrade visual studio. https://www.microsoft.com/en-us/download/details.aspx?id=42643

选项 2. 更新您的 ReplaceInner() 方法以反映 .NET 框架 4.0 之前的类型和方法的内存映射:

Option 2. Update your ReplaceInner() method to reflect the memory mapping of Types and Methods before the .NET framework 4.0:

static void ReplaceInner(MethodInfo methodToReplace, MethodInfo methodToInject)
{
    unsafe
    {
        if (IntPtr.Size == 4)
        {
            uint* tarPtr = (uint*)methodToReplace.MethodHandle.Value.ToPointer();
            uint* injPtr = (uint*)methodToInject.MethodHandle.Value.ToPointer();

            uint* tar = (uint*)*(tarPtr + 5) + 12;
            uint* inj = (uint*)*(injPtr + 5) + 12;
            *tar = *inj;
        }
        else
        {
            ulong* tarPtr = (ulong*)methodToReplace.MethodHandle.Value.ToPointer();
            ulong* injPtr = (ulong*)methodToInject.MethodHandle.Value.ToPointer();

            ulong* tar = (ulong*)*(tarPtr + 5) + 12;
            ulong* inj = (ulong*)*(injPtr + 5) + 12;
            *tar = *inj;
        }
    }
}

这篇关于c# 更改方法的指针 .NET 3.5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆