我正在为一个为(我们)modder 提供 API 的游戏编写扩展程序。这个 API 提供了各种各样的东西,但它有一个限制。API 仅适用于“引擎”,这意味着基于引擎发布的所有修改(模组)不提供/具有任何类型的(特定于模组的)API。我创建了一个“签名扫描器”(注意:我的插件作为共享库加载,使用 -share 和 -fPIC 编译)找到感兴趣的功能(这很容易,因为我在 linux 上)。所以来解释一下,我将举一个具体的例子:我找到了一个感兴趣的函数的地址,它的函数头很简单int * InstallRules(void);
. 它需要一个空值(void)并返回一个整数指针(指向我感兴趣的对象)。现在,我想做的是创建一个绕道(并记住我有函数的起始地址)到我自己的函数,我想这样做:
void MyInstallRules(void)
{
if(PreHook() == block) // <-- First a 'pre' hook which can block the function
return;
int * val = InstallRules(); // <-- Call original function
PostHook(val); // <-- Call post hook, if interest of original functions return value
}
现在这是交易;我对函数挂钩没有任何经验,而且我对内联汇编(仅限 AT&T)知之甚少。网上预制的detour包只适用于windows或者是使用其他方法(即预加载一个dll来覆盖原来的)。所以基本上; 我应该怎么做才能走上正轨?我应该阅读调用约定(在这种情况下为 cdecl)并了解内联汇编,还是应该做什么?最好的可能是用于 linux 绕行的已经有功能的包装类。最后,我想要这样简单的东西:
void * addressToFunction = SigScanner.FindBySig("Signature_ASfs&43"); // I've already done this part
void * original = PatchFunc(addressToFunction, addressToNewFunction); // This replaces the original function with a hook to mine, but returns a pointer to the original function (relocated ofcourse)
// I might wait for my hook to be called or whatever
// ....
// And then unpatch the patched function (optional)
UnpatchFunc(addressToFunction, addressToNewFunction);
我知道我无法在这里得到一个完全令人满意的答案,但我非常感谢一些关于方向的帮助,因为我在这里如履薄冰......我读过关于绕道但几乎没有根本没有任何文档(特别是针对 linux),我想我想实现所谓的“蹦床”,但我似乎无法找到获取这些知识的方法。
注意:我也对 _thiscall 感兴趣,但从我读过的内容来看,使用 GNU 调用约定调用并不难(?)