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

x86_64近跳转地址计算疑惑:实际跳转地址为何不符?

问题背景

我用免费版IDA调试器学习Windows平台汇编,写了一段C++代码编译后调试:

#include <iostream>
#include <Windows.h>

int main()
{
    SIZE_T size = 0;
    unsigned char data[10] = {};
    ReadProcessMemory(GetCurrentProcess(), NULL, data, 10, &size);
}

跟踪ReadProcessMemory的调用流程时,走到了0x00007FFBD508AE80这个地址,这里是一条7字节的jmp指令:

KERNEL32.DLL:00007FFBD508AE80   jmp  cs:off_7FFBD50F1A08

指令编码是FF25816B0600,我知道FF25是近跳转的操作码,按公式计算:

0x00007FFBD508AE80 + 0x066B81 + 7 = 0x7FFBD50F1A08

结果和IDA显示的偏移完全一致,按理说应该跳转到这个地址,但按F7单步进入后,实际却跳到了KernelBase.dll的0x7FFBD29BAC90地址,这是哪里忽略了?

问题根源

这是Windows的API重定向机制导致的:

  • Kernel32.dll里的ReadProcessMemory只是个“跳板桩函数”,本身没有实际功能,唯一作用就是跳转到真正实现API逻辑的位置。
  • 你计算出的0x7FFBD50F1A08是Kernel32.dll中的一个内存地址,这个地址里存的不是最终跳转目标,而是指向KernelBase.dll真实函数入口的指针。
  • 这条jmp cs:off_7FFBD50F1A08是间接跳转——它会先读取0x7FFBD50F1A08地址里存储的值,再跳转到该值指向的位置,也就是你看到的KernelBase.dll的0x7FFBD29BAC90,这才是ReadProcessMemory真正干活的代码入口。

说白了,你算的是“存指针的地址”,而不是“指针指向的真实函数地址”,所以单步执行后会跳到KernelBase.dll的实际实现处。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:32:37