I will give the code:

public class Base { public virtual void test() { } } public class Target : Base { public override void test() { Console.WriteLine("Target.test()"); } public void test3() { Console.WriteLine("Target.test3()"); } } public class Target2 { public void test() { Console.WriteLine("Target.test2()"); } } public class Injection { public static void replace() { MethodInfo methodToReplace = typeof(Target).GetMethod("test", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); MethodInfo methodToInject = typeof(Target2).GetMethod("test", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); RuntimeHelpers.PrepareMethod(methodToReplace.MethodHandle); RuntimeHelpers.PrepareMethod(methodToInject.MethodHandle); ReplaceInner(methodToReplace, methodToInject); } static void ReplaceInner(MethodInfo methodToReplace, MethodInfo methodToInject) { unsafe { if (IntPtr.Size == 4) { int* inj = (int*)methodToInject.MethodHandle.Value.ToPointer(); int* tar = (int*)methodToReplace.MethodHandle.Value.ToPointer(); *tar = *inj; } else { ulong* inj = (ulong*)methodToInject.MethodHandle.Value.ToPointer() + 1; ulong* tar = (ulong*)methodToReplace.MethodHandle.Value.ToPointer() + 1; *tar = *inj; } } } } class Program { static void Main(string[] args) { Injection.replace(); Target target = new Target(); target.test(); Console.Read(); } } 

When replacing a pointer of a non-redefined (non-virtual) method, everything works, i.e. instead of the test () method of the Target class, the test () method of the Target2 class is called. In the case of replacing a virtual method pointer, the same overridden method is called.

In other words, if you replace a pointer, such as the test3 () method from the Target class with the test () method pointer from the Target2 class, then when you call target.test (), the test () method from the Target2 class is called. But with virtual methods this does not work.

  • You can try to change the address of the base method - Grundy
  • You are doing some kind of totally weird and very rude hack. If you are trying to do this, you should know very clearly and well what you are doing and why, and not ask for help. There should be no such constructions in a good code. - VladD
  • VladD, I need to explain why I need it? Sounds like an accusation. - Eugene
  • The optimizer has the right to zainlaynit function - where is your god now? - Grundy
  • An example is taken of stackoverflow.com/questions/7299097/ ... No injections from one process to another's are carried out. Therefore, there can be no hacking. Everything is done exclusively for peaceful purposes, namely, to create a shell for each method in which the original method call will be performed. By analogy with the work profiler. - Eugene

1 answer 1

The answer in the English version: https://stackoverflow.com/questions/38782934/how-to-replace-the-pointer-to-the-overridden-virtual-method-in-the-pointer-of

Build in Release x86 and x64. For Debug, you must additionally consider the offset.