c - 安全地将 C 函数 Hook 到程序集中

标签 c visual-studio assembly x86

我正在尝试将一些 C 钩子(Hook)放入其他人用 asm 编写的代码中。我对 x86 asm 知之甚少,我想确保我这样做是安全的。

到目前为止我有这么多:

EXTERN _C_func

CALL _C_func

这似乎行得通,但我敢肯定这很危险。至少它可能会破坏 EAX,甚至可能更多。

所以我想我需要知道的是:C 破坏了哪些寄存器以及我如何确保寄存器被正确保存?我还能做些什么来确保我可以安全地将钩子(Hook)插入任意位置吗?

如果有帮助,我正在使用 Visual Studio 来处理 C 函数。 谢谢。

更新:

我查了几个人建议的“偏执”方法,它看起来像这样:

pushfd
pushad
call _C_func
popad
popfd

AD = (A)ll 通用寄存器

FD = (F)滞后

(我不确定“d”代表什么,但它表示 32 位寄存器而不是 16 位。)

但最有效的方法在下面 Kragen 的回答中有说明。 (假设您不需要保留标志。如果需要,请添加 FD 指令。)

此外,在 C 函数中分配大量堆栈变量时要小心,因为它可能会超出 asm 子例程的堆栈空间。

我想差不多就可以了,谢谢大家的帮助!

最佳答案

如果调用约定是 cdecl 并且 C_funct 的签名很简单:

void C_func(void);

那么这是完全“安全”的,但是寄存器 EAX、ECX 和 EDX“可在函数内部使用”,因此可能会被覆盖。

为了防止这种情况,您可以保存您关心的寄存器并在之后恢复它们:

push eax
push ecx
push edx

call _C_func

pop edx
pop ecx
pop eax

按照惯例,EBX、ESI、EDI 和 EBP 寄存器不应由被调用者修改。

我相信标志可能会被被调用者修改——同样,如果您关心保留标志的值,那么您应该保存它们。

请参阅 x86 calling conventions 上的维基百科页面.

关于c - 安全地将 C 函数 Hook 到程序集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7106900/

相关文章:

c# - 调试时在 Watch Window 中查看 Exception.Data

c - 错误 C2065 : 'i' : undeclared identifier when iterating in C

assembly - 提供一个使用 Rust 的内联汇编查询 Intel CPU 能力的例子

c - OCI UTF16 环境的 OCILogon 失败

c - 编写可移植的 C 程序 - 需要考虑哪些事项?

c++ - 使用 boost 线程时出现链接器错误

c - 通过 setcontext 从信号处理程序返回

c - i = i + j; 和有什么区别?我+=j;用c语言?

c - C 中 char 数组的 if 语句

c - Linux 汇编和 printf