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

如何从64位应用的反汇编代码中获取目标QWORD对象地址?

问题:从64位汇编地址中获取目标QWORD地址

我有一个可在内存中匹配字节序列的模式:

0x74, 0x26, 0x48, 0x8B, 0x05, 0, 0, 0, 0, 0x48, 0x8D, 0x0D, 0, 0, 0, 0

其中0可匹配任意字节,该模式运行正常。匹配到的反汇编代码如下:

.text:000000014002AD99 74 26     jz  short loc_14002ADC1

.text:000000014002AD9B 48 8B 05 86 D1 64 01      mov  rax, qword_141677F28

我的问题是:如何从地址0x14002AD99中获取qword_141677F28?
在32位应用中,我可以通过类似0x000000014002AD9B + 2的方式得到所需地址,但64位环境下此方法失效,无法得到正确的qword_141677F28,只会得到错误结果。
内存中qword_后的地址是正确的,请问我需要解析汇编代码,还是有其他方法可获取qword_141677F28?

附相关代码:

DWORD WINAPI thread(_In_ LPVOID core)
{
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

    std::vector<BYTE> pattern{ 0x74, 0x26, 0x48, 0x8B, 0x05, 0, 0, 0, 0, 0x48, 0x8D, 0x0D, 0, 0, 0, 0 };
    
    uintptr_t* address = get_address<uintptr_t*>(pattern, "xrEngine.exe");
    
    std::cout << std::hex << address + 5; // wrong result
    
    std::cin.get();
    
    FreeLibraryAndExitThread(static_cast<HMODULE>(core), 0);

}
解决方案

64位x86架构中,mov rax, qword ptr [rip+offset]这类指令用的是RIP相对寻址,和32位的绝对寻址逻辑完全不同,你之前的32位方法自然失效。

具体计算逻辑

  1. 先确定mov rax, qword_141677F28的起始地址:模式匹配到的0x14002AD99是jz指令的地址,mov指令从0x14002AD9B开始(跳过jz的2字节)。
  2. 这条mov指令的结构是:0x48 0x8B 0x05(3字节操作码) + 4字节有符号偏移量offset(对应你模式中0x48,0x8B,0x05后面的四个占位0)。
  3. 目标qword_141677F28的地址计算公式:
    目标地址 = mov指令起始地址 + 指令总长度(7字节) + offset
    
    对应你的例子:0x14002AD9B + 7 + 0x0164D186 = 0x141677F28,和反汇编结果一致。

代码修改

调整代码实现上述逻辑:

DWORD WINAPI thread(_In_ LPVOID core)
{
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

    std::vector<BYTE> pattern{ 0x74, 0x26, 0x48, 0x8B, 0x05, 0, 0, 0, 0, 0x48, 0x8D, 0x0D, 0, 0, 0, 0 };
    
    // 获取模式匹配到的起始地址(0x14002AD99)
    uintptr_t match_addr = reinterpret_cast<uintptr_t>(get_address<void*>(pattern, "xrEngine.exe"));
    // 定位到mov指令的起始地址(跳过jz的2字节)
    uintptr_t mov_inst_addr = match_addr + 2;
    // 读取4字节的有符号偏移量
    int32_t offset = *reinterpret_cast<int32_t*>(mov_inst_addr + 3);
    // 计算目标qword地址
    uintptr_t qword_addr = mov_inst_addr + 7 + offset;
    
    std::cout << std::hex << qword_addr; // 正确结果:0x141677F28
    
    std::cin.get();
    
    FreeLibraryAndExitThread(static_cast<HMODULE>(core), 0);

}

关键说明

  • 用int32_t读取偏移量:因为RIP相对偏移是有符号32位整数,能正确处理正向和反向的偏移。
  • 指令长度固定:mov rax, [rip+offset]的总长度是7字节(3字节操作码+4字节偏移),这是x86-64架构的固定编码。

内容的提问来源于stack exchange,提问作者Sora Aoi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:07:07