c# - 在 C# 中运行时 Hook 托管方法

标签 c# methods hook managed detours

我在程序集中有一个带有公共(public)方法的密封类,我想添加一个日志记录系统,但不幸的是我没有来源。所以我试图在特定的日志记录方法上绕过这个方法,并在退出时调用原始方法。 Hook 工作正常,但我无法获得任何类型的参数,或者至少我得到了一些完全错误的东西。

我也不能使用任何类型的注入(inject)或像 PostSharp 这样的库,所以我想知道这种东西是否可以在运行时以某种方式实现,或者我可以放弃吗?

为了给你更多的细节,我将在下面粘贴一些代码部分:

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();
    }
}

最佳答案

已解决,Marshal.GetFunctionPointerForDelegate:我无法使用此方法创建从函数指针到另一个托管委托(delegate)的委托(delegate)。

  this.target = target.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(target);
  targetDelegate = target;
  this.hook = hook.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(hook);

关于c# - 在 C# 中运行时 Hook 托管方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35206770/

相关文章:

javascript - 使用 scriptmanager.registerstartupscript 显示对话框

c++ - 想要分配 std::string 但编译器认为是 bool

linux - sys_execve Hook 3.5 内核

c++ - 如何在单独的线程中调用 QDialog::exec 以避免向主线程发出任何信号(包括重绘)?

用于检查更改的 SVN 钩子(Hook)也对相应的测试类进行了

c# - 将 C# 2.0 System.Data.SqlTypes.SqlXml 对象转换为 System.Xml.XmlNode

c# - iTextSharp 不显示所有列

c# - 仅使用单个搜索BackgroundWorker的自动完成文本框 - 代码示例?

java - 我的解决方案是否存在逻辑流程问题?

java - 在android中验证函数先决条件