You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MS Detours挂钩函数后RAX寄存器值异常的问题

问题描述

正常未挂钩时,在EXE地址242685处断点,RAX寄存器包含游戏数据指针;但挂钩后在此处断点,RAX值为0。若将Objects_detour改为void*返回类型,RAX变为某个指针,但并非游戏数据指针。请问哪里操作错误?RAX值不应被改变才对?


相关代码与汇编

Hook代码

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&Objects_orig, Objects_detour);
DetourTransactionCommit();

Detour函数

void Objects_detour(uint64_t a1, int a2, int a3) {
    return Objects_orig(a1,a2,a3);
}

头文件定义

void Objects_detour(uint64_t a1, int a2, int a3);
typedef void(*Objects_deb)(uint64_t a1, int a2, int a3);
inline Objects_deb Objects_orig = nullptr;

原EXE汇编代码

.exe+24267F - CC                    - int 3 
.exe+242680 - 44 89 44 24 18        - mov [rsp+18],r8d
.exe+242685 - 89 54 24 10           - mov [rsp+10],edx

挂钩后的EXE汇编代码

.exe+24267F - CC                    - int 3 
.exe+242680 - E9 F3DAFEBF           - jmp 7FF766E50178
.exe+242685 - 89 54 24 10           - mov [rsp+10],edx

问题分析与解决

核心问题是你定义的函数签名和原函数不匹配。x64调用约定下,RAX寄存器专门用于存储函数返回值,未挂钩时RAX在断点处有有效数据指针,说明原函数绝对不是void类型。

  1. 错误原因:

    • 你把原函数类型定义为void(*Objects_deb)(...),hook函数也用void返回类型,编译器生成的代码会在函数返回时清空RAX,导致回到原断点处RAX值被修改为0。
    • 改成void*后结果不对,是因为你仍未匹配原函数的真实返回类型,或者没有正确传递原函数的返回值。
  2. 修复步骤:

    • 先确定原函数的正确返回类型:从RAX存储游戏数据指针的现象来看,原函数应该返回对应的数据结构指针(比如uint64_t*或自定义结构体指针,需根据实际逻辑确认)。
    • 同步修改头文件定义和hook函数的返回类型,确保和原函数完全一致,并且在hook中正确返回原函数的结果:
      // 示例:假设原函数返回uint64_t类型指针,需根据实际情况调整
      uint64_t* Objects_detour(uint64_t a1, int a2, int a3) {
          return Objects_orig(a1,a2,a3);
      }
      
      // 头文件同步修改
      uint64_t* Objects_detour(uint64_t a1, int a2, int a3);
      typedef uint64_t*(*Objects_deb)(uint64_t a1, int a2, int a3);
      inline Objects_deb Objects_orig = nullptr;
      
    • 这样原函数的返回值会通过RAX正确传递,回到原断点处RAX的值就会和未挂钩时一致。

另外要注意,x64调用约定中除了返回值,寄存器的保存规则也有要求——Detour本身会处理寄存器的保存,但如果函数签名错误,编译器生成的代码会破坏寄存器状态,直接导致返回后RAX不符合预期。

内容的提问来源于stack exchange,提问作者ayes l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:57:22