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

如何用纯C++提取mov rcx,qword ptr [0xAddress]中的地址

纯C++提取mov rcx, qword ptr [0xAddress]中的目标地址指针

我来帮你搞定这个问题——不用内联汇编,纯C++就能从这条指令里提取出你要的0xAddress指针。核心是先搞懂x86-64架构下这条指令的机器码结构,然后直接读取内存解析就行。

先搞清楚指令的机器码格式

x86-64里,mov rcx, qword ptr [0xAddress]通常有两种常见编码,反汇编工具可能会把它们都显示成绝对地址,但底层机器码不一样:

1. 绝对直接寻址

这种编码的机器码是48 A1 XX XX XX XX XX XX XX XX:

  • 48是REX.W前缀,告诉CPU我们要操作64位数据
  • A1是指令 opcode,对应mov r64, [abs64]这个操作
  • 后面紧跟的8个字节就是你要的0xAddress,按小端字节序存储

2. RIP相对寻址(更常用)

大部分现代编译器会生成这种编码,汇编形式是mov rcx, qword ptr [rip+0xOffset],但反汇编工具会自动计算出rip+offset的绝对地址,显示成[0xAddress]。它的机器码是48 8B 0D XX XX XX XX:

  • 48同样是REX.W前缀
  • 8B 0D是opcode,对应mov rcx, [rip+32bit-offset]
  • 后面4个字节是有符号的32位偏移量,要得到绝对地址得算:0xAddress = 指令起始地址 + 7 + 偏移量(因为这条指令总长7字节,RIP指向指令的下一条,所以当前指令地址加7就是RIP的值,再加偏移就是目标地址)

纯C++实现代码

假设你已经用FindAddressLocation()拿到了这条指令的起始内存地址PatchAddress,下面分情况写代码:

处理绝对直接寻址的情况

#include <cstdint>

uint64_t GetAbsoluteAddress(uint64_t PatchAddress) {
    // 跳过前2字节的前缀和opcode,直接读后面8字节的地址
    auto addressPtr = reinterpret_cast<uint64_t*>(PatchAddress + 2);
    return *addressPtr;
}

处理RIP相对寻址的情况

#include <cstdint>

uint64_t GetRIPRelativeAddress(uint64_t PatchAddress) {
    // 跳过前3字节的前缀和opcode,读后面4字节的偏移量
    int32_t offset = *reinterpret_cast<int32_t*>(PatchAddress + 3);
    // 计算绝对地址:指令地址+7(指令长度)+偏移
    return PatchAddress + 7 + offset;
}

自动判断指令类型的通用版本

你可以先检查指令的前几个字节,自动适配两种情况:

#include <cstdint>
#include <stdexcept>

uint64_t ExtractTargetAddress(uint64_t PatchAddress) {
    uint8_t* instrBytes = reinterpret_cast<uint8_t*>(PatchAddress);
    
    // 判断是否是绝对直接寻址(48 A1 ...)
    if (instrBytes[0] == 0x48 && instrBytes[1] == 0xA1) {
        return *reinterpret_cast<uint64_t*>(instrBytes + 2);
    }
    // 判断是否是RIP相对寻址的mov rcx(48 8B 0D ...)
    else if (instrBytes[0] == 0x48 && instrBytes[1] == 0x8B && instrBytes[2] == 0x0D) {
        int32_t offset = *reinterpret_cast<int32_t*>(instrBytes + 3);
        return PatchAddress + 7 + offset;
    }
    // 遇到未知指令格式的情况,抛出异常或者返回你需要的默认值
    else {
        throw std::runtime_error("Unsupported instruction format - check the machine code!");
    }
}

几个要注意的点

  • 内存权限:要确保你有读取这块内存的权限,Windows下如果内存是只读的,可能需要先用VirtualProtect修改权限,不然会触发访问错误。
  • 字节序:x86是小端序,所以直接读内存就行,不用手动转字节顺序。
  • 指令准确性:一定要确认FindAddressLocation()返回的是指令的起始地址!可以用x64dbg或者IDA这类工具先看一下指令的机器码,再调整代码里的偏移量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:39:40