5

I have a sealed class with a public method inside an assembly, I would like to add a logging system but unfortunatley I don't have the sources. So I was trying detour this method on a specific logging method and calling the original one on exit. The hooking is working properly but I am not able to get any type of parameters or at least I am getting something completly wrong.

I can not use any kind of injection or libraries like PostSharp as well, so I am wondering if this kind of stuff can be achieved in someway at runtime or can I just give up?

Just to give you some more details I am going to paste some code parts below:

public Hook(Delegate target, Delegate hook)
{
  this.target = Marshal.GetFunctionPointerForDelegate(target);
  targetDelegate = target;
  this.hook = Marshal.GetFunctionPointerForDelegate(hook);

  originalBytes = new byte[6];
  Marshal.Copy(this.target, originalBytes, 0, 6);

  byte[] hookPointerBytes = BitConverter.GetBytes(this.hook.ToInt32());
  // Jump
  newBytes = new byte[]
  {
    0x68, hookPointerBytes[0], hookPointerBytes[1], hookPointerBytes[2], hookPointerBytes[3], 0xC3
  };
}

public object CallOriginal(params object[] args)
{
  // Remove the patch
  Uninstall();
  // Invoke the original method
  object ret = targetDelegate.DynamicInvoke(args);
  // Re-apply the patch
  Install();
  return ret;
}


public sealed class Foo
{
    public void DoSomething(Int32 value1)
    {
      // and here I am getting value1 = -1919988997
      Console.WriteLine(value1);
    }
}

class Program
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void DoSomethingDelegate(Int32 value1);

    private static DoSomethingDelegate Original { get; set; }
    private static DoSomethingDelegate Hooked { get; set; }

    private static HookManager _hookManager;

    public static void DoSomething(Int32 value1)
    {
      // This is called as well after foo.DoSomething but value1 is 251934152
      Console.WriteLine("Hooked DoSomething: " + value1) ;
      var hook = _hook["DoSomethingHook"];

      // Call the original Foo.DoSomething
      hook.CallOriginal(value1);
    }

    static void Main(string[] args)
    {
      RuntimeHelpers.PrepareMethod(typeof(Foo).GetMethod("DoSomething").MethodHandle);
      _hookManager = new HookManager();
      var originalPointer = typeof(Foo).GetMethod("DoSomething").MethodHandle.GetFunctionPointer();
      Original = (DoSomethingDelegate)Marshal.GetDelegateForFunctionPointer(originalPointer, typeof(DoSomethingDelegate));
      Hooked = DoSomething;
      _hookManager.Add(Original, Hooked, "DoSomethingHook");

      // Call Hook method, HookManager it is just an extended dictionary...
      _hookManager.InstallAll();

      var foo = new Foo();

      // Calling the original method here with 1
      foo.DoSomething(1);

      Console.ReadLine();
    }
}
Luca Bottani
  • 93
  • 1
  • 9
  • GetMethod will give you a MethodInfo with all the information about the method, including the parameter types – Gusman Feb 04 '16 at 16:50
  • You might find this article helpful: http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer –  Feb 04 '16 at 16:51
  • Thanks @Gusman, I've already seen it. But it is replacing the original method with another one, it is not properly what I need – Luca Bottani Feb 04 '16 at 16:57
  • 2
    Solved, Marshal.GetFunctionPointerForDelegate: you cannot use this method to create a delegate from a function pointer to another managed delegate. – Luca Bottani Feb 05 '16 at 17:14
  • Did you release the full code somewhere? I'm highly interested in this. – Evengard Feb 18 '19 at 15:45
  • @Evengard sure thing...take a look here: https://gitlab.altralogica.it/caos/insider – Luca Bottani Feb 19 '19 at 16:53

1 Answers1

3

Solved, Marshal.GetFunctionPointerForDelegate: I can not use this method to create a delegate from a function pointer to another managed delegate.

  this.target = target.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(target);
  targetDelegate = target;
  this.hook = hook.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(hook);
Luca Bottani
  • 93
  • 1
  • 9