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

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

问题描述

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

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 Framework 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天全站免登陆