如何用纯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
相关产品推荐
相关产品推荐

