怎样让1+1=3?

Posted artech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样让1+1=3?相关的知识,希望对你有一定的参考价值。

如下所示的是一个.NET程序。我们在这段程序中定义了一个作整数加法运算的Add方法,但是我希望将针对这个方法的调用转移到另一个Add2方法上,为此我定义了一个Override方法。

class Program

    static void Main()
    
        Override(() => Add(default, default), () => Add2(default, default));
        Console.WriteLine($"Add(1, 1) == Add(1, 1)");
        Console.ReadLine();
    

    public static int Add(int x, int y) => x + y;
    public static int Add2(int x, int y) => x + y + 1;
    public static void Override(Expression<Action> originalCall, Expression<Action> targetCall);

从如下所示的输出可以看出:虽然源程序我们调用的是Add方法,实际上最终的调用被转移到Add2方法上。

技术图片

我们知道通过C#编写的.NET程序在编译后会转化成IL Code,在运行时以及时编译的方式转化成机器指令。如果想“篡改”某个方法的实现,要么在JIT之前改变IL代码,要么直接修改最终的机器指令。Override方法采用的是第二种解决方案,如下所示的该方法的实现,基本的思路就是将将原方法的机器指令修改为JUMP(对应x86二进制为0xE9)指令实现向目标方法的跳转。

public static void Override(Expression<Action> originalCall, Expression<Action> targetCall)

    var originalMethod = ((MethodCallExpression)originalCall.Body).Method;
    var targetMethod = ((MethodCallExpression)targetCall.Body).Method;

    RuntimeHelpers.PrepareMethod(originalMethod.MethodHandle);
    RuntimeHelpers.PrepareMethod(targetMethod.MethodHandle);

    var sourceAddress = originalMethod.MethodHandle.GetFunctionPointer();
    var targetAddress = (long)targetMethod.MethodHandle.GetFunctionPointer();

    int offset = (int)(targetAddress - (long)sourceAddress - 4 - 1); 

    byte[] instruction = 
        0xE9, // Long jump relative instruction
        (byte)(offset & 0xFF),
        (byte)((offset >> 8) & 0xFF),
        (byte)((offset >> 16) & 0xFF),
        (byte)((offset >> 24) & 0xFF)
    ;

    Marshal.Copy(instruction, 0, sourceAddress, instruction.Length);

以上是关于怎样让1+1=3?的主要内容,如果未能解决你的问题,请参考以下文章

java里怎样让float保留3位小数

[机缘参悟-66]:怎样才能让别人愿意帮你:利益共享法则“大道”“人性”

我怎样才能让这个继电器在我拥有的 3 个触摸传感器中的任何一个上打开?

matlab怎样让4*4矩阵两列合成一列变成4*2?

JS怎样让表格每个tr的第一个td按照1,2,3,4,5.....循环排序

matlab怎样让遗传算法ga从上次的运行结果开始继续寻优