如何从委托中获取功能存储器地址

问题描述

我想从同一进程中加载​​的DLL中钩住一个函数,因此每次执行该函数时,我的自定义函数都会被执行。

为此,我声明了一个虚拟函数,该函数将替代DLL中的原始函数执行:

 public static bool hookFunc(string a,ulong b,string c,IntPtr d)
{
     Console.WriteLine("hi");
     return true;
}

此后,我声明一个Delegate,并生成一个指向我的 hookFunc 函数的新实例,然后使用GetFunctionPointerForDelegate()从委托中获取一个指针。我还生成了用于修补原始函数的内存的字节序列,并使用函数 hookFunc (从新指针获取)的内存地址来完成此序列:

public delegate bool hookDel(string a,IntPtr d);

public void hookManager()
        {

            var a = new hookDel(hookFunc);
            var hookPtr = Marshal.GetFunctionPointerForDelegate(a);
            var hookPointerBytes = BitConverter.GetBytes(hookPtr.ToInt64());
            newBytes = new byte[] { 0x49,0xbb,hookPointerBytes[0],hookPointerBytes[1],hookPointerBytes[2],hookPointerBytes[3],hookPointerBytes[4],hookPointerBytes[5],hookPointerBytes[6],hookPointerBytes[7],0x41,0xff,0xe3 };
        }

这时,转换为汇编的变量newBytes的内容应为以下指示:

mov r11,[memory address of my hookFunc function]
jmp r11

最后,我使用GetProcAddress获得了原始DLL的函数存储地址,并使用WriteProcessMemory对第一个字节进行了修补,以替换变量newBytes的内容。收到多个StackOverflow错误后,我用 WinDbg 调试了代码,发现变量hookPointerBytes不包含 hookFunc 的地址,因此在执行钩子操作时触发jmp指令将代码执行流驱动到没有可执行代码的内存地址,这可能是我的程序崩溃的原因。

我已验证DLL的函数挂钩已成功完成,并且正在执行jmp指令。我的问题是,为什么我没有使用从Delegate获得的指针来获取 hookFunc 的真实内存地址? C#中还有其他方法可以获取我的 hookFunc 函数的内存地址吗?

解决方法

我不确定您是否要在没有不安全代码的情况下使其正常工作。 我认为您将需要一个不受管理的指针,该指针可以通过bootJar { requiresUnpack "**/jython-slim*" } 上的ToPointer获得。

IntPtr

我自己还没有尝试过,但是您可以在此处找到一个示例:https://github.com/wledfor2/PlayHooky

特定类别: https://github.com/wledfor2/PlayHooky/blob/master/HookManager.cs

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...