You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何查找汇编中mov指令偏移量及代码修改的原始内存地址?

汇编指令偏移量与内存地址计算问题解答

一、如何查找汇编语言中MOV指令的偏移量?

偏移量得分两种场景来看,具体取决于你关注的是指令本身的偏移,还是内存操作数的偏移:

  • 如果是指令自身的偏移(相对于代码段基址)
    用调试器(比如x64dbg、OllyDbg)查看指令的实际地址(比如0x00401020),再获取代码段(CS寄存器)的基址——实模式下是CS值左移4位,保护模式下可以通过调试器的段信息窗口查看GDT/LDT里的基址。用指令地址减去代码段基址,得到的就是指令的偏移量。举个例子,指令地址是0x00401020,CS基址是0x00400000,那偏移就是0x1020
  • 如果是内存操作数的偏移(比如[esi+10]里的10
    直接看汇编指令里的立即数就是偏移,比如[ebp+18]里的0x18就是相对于EBP的偏移。要是调试器里显示的是符号名(比如[ebp+var_8]),可以去栈窗口或者符号表查对应的数值——var_XX一般对应ebp-XX,所以偏移是-XX(也就是相对于EBP的负偏移)。

二、计算两条指令操作的原始内存地址

先把你的已知条件梳理清楚:

  • 目标指令:mov [esi+10],eaxmovzx eax,byte ptr [ebp+18]
  • 寄存器值:EAX=0x003F6C39,ESI=0x20847BA0,EBP=0x010FF1B8
  • 提到的新地址:0x20847BB0

我们逐条拆解分析:

1. 指令 mov [esi+10],eax 的目标内存地址

这条指令的作用是把EAX的值写入到ESI寄存器值 + 0x10对应的内存单元,计算过程很直接:

0x20847BA0(ESI的值) + 0x10(偏移量) = 0x20847BB0

这个结果正好是你说的“新地址”,说明这个地址就是这条指令要修改的内存单元。这里的地址本身是固定的,不存在“原始/新”的区别,你提到的“新地址”应该是指写入后存储了新值的地址,而它本身就是指令操作的原始目标地址,写入前是一个存储原有数据的内存单元,写入后就换成了EAX的值0x003F6C39。

2. 指令 movzx eax,byte ptr [ebp+18] 的源内存地址

这条指令是从EBP寄存器值 + 0x18对应的内存单元读取一个字节,再零扩展为32位存入EAX,计算过程如下:

0x010FF1B8(EBP的值) + 0x18(偏移量) = 0x010FF1D0

这个0x010FF1D0就是指令读取的原始内存地址,当前EAX的值0x003F6C39就是从这个地址读取的字节(低8位是0x39,零扩展后得到32位的0x003F6C39)。


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

火山引擎 最新活动