我有一个内存地址,它是另一个程序(其中一个dll)中函数的内存地址。我已经通过DLL注入加载到程序中。我已经有了低音地址,以及每次程序加载时函数的实际位置。所以,这不是问题。
我想简单地挂钩该位置,并获取变量。我知道函数的伪代码。所以这不是问题。或者另一种很棒的方法是在该存储器位置执行断点并获取调试寄存器。
我找不到任何明确的例子。我也没有该功能的“名称”,我只有内存地址。有没有办法只使用内存地址?大多数(如果不是全部)示例都使用了我没有的函数名称。
如果有人能指出我正确的方向,那么我可以完成这项任务,我将非常感激。它也可以帮助很多其他可能有同样问题的人。
编辑:我还应该提到Id而不是用别人的代码重载我的程序,我真的只想要准系统,就像一个带有翻转窗口的基本车。请不要给我豪华套餐。
答案 0 :(得分:4)
你错过了最重要的部分,是32位还是64位代码?在任何情况下,代码项目都有一个很好的破坏和lib here,它涵盖了两者。
如果你想做这个“老派”,那么可以很简单地完成:
首先,你需要找到你要挂钩的函数的虚拟地址(由于ASLR,你不应该依赖它在同一个地方),这通常用RVA +模块基本加载地址来完成未导出的导出函数可以使用GetProcAddress
。
从那里开始,类型钩子取决于你想要完成什么,在你的情况下,有两种方法:
第一个更简单,但更麻烦,因为它通常涉及一些内联汇编(除非你挂钩/HOTPATCH
二进制文件或者你只想存根),第二个更清晰,但需要一些工作用调试器。
你要跳出的函数应该具有与你挂钩的函数相同的参数和调用约定(ABI),这个函数可以捕获传递的参数,操作它们,过滤掉调用或者你之后的任何东西。
对于两者,您需要一种方法来编写一些程序集来进行修补,在Windows下,WriteProcessMemory
是您的第一个调用端口(注意:您需要RWX权限才能执行此操作,因此调用{{ 1}}),这是一个小实用函数,可以创建一个32位的相对调用或跳转(取决于作为VirtualProtect
传递的操作码)
eType
此函数适用于方法2,但对于方法1,您需要跳转到中间程序集蹦床以恢复修补程序覆盖的任何代码,然后返回到原始函数,这非常繁琐,这就是为什么最好只使用现有的和经过测试的库。
从它的声音中,使用方法1并在目标函数的序言上修改跳转将完成您所需要的操作,因为您似乎不关心执行您修补的功能。
(第三种方法使用HW断点,但这非常脆弱,并且可能会出现问题,因为您仅限于4个HW断点)。
答案 1 :(得分:0)
您的“样本”在这里:
通常当你“挂钩”到DLL中时,你实际上将你的函数放在被调用的DLL中的函数前面,所以你的函数会被调用。然后捕获你想要的任何东西,调用另一个函数,捕获它的返回值以及其他任何东西,然后返回原始调用者。