跳转至

完成跳转钩子

创建蹦床后,定义回调并设置钩子,像这样:

void jumpHookCallback() {
    // 做事情
}
restoreJumpHook = hookWithJump(0xDEADBEEF, 
&myTrampoline, 5);

最后,在 jumpHookCallback() 函数内部,执行依赖钩子的代码。如果你的代码需要读取或写入钩子执行时寄存器的值,你很幸运。PUSHAD 命令按 EAX、ECX、EDX、EBX、原始 ESP、EBP、ESI 和 EDI 的顺序把它们压入栈。蹦床在 jumpHookCallback() 调用前直接调用 PUSHAD,所以你可以把寄存器值作为参数引用,像这样:

void jumpHookCallback(DWORD EDI, DWORD ESI, DWORD 
EBP, DWORD ESP,
    DWORD EBX, DWORD EDX, DWORD ECX, DWORD EAX) {
    // 做事情
}
restoreJumpHook = hookWithJump(0xDEADBEEF, 
&myTrampoline, 5);

由于蹦床用 POPAD 直接从栈上的这些值恢复寄存器,你对参数所做的任何修改都会在从栈恢复时应用到实际寄存器。

与 VF 表钩子一样,跳转钩子很少需要,而且用简单示例模拟可能很棘手。为了帮你理解它们,我将在第一百七十五页「把跳转钩子和 VF 钩子应用到 Direct3D」中探索一个现实、实用的用例。