改变助记词改变地址

changing mnemonic changes address

我是 gdb 和汇编的新手。我试图将助记符指令从 jg 更改为 jle,但每当我更改助记符时,它也会更改目标地址。例如,

假设我正在尝试修改这个:

4005a5 0f 8f 1e 01 00 00 jg 400c74 <Function_1>

所以,我做到了

$set *0x4005a5 = 0x7e

然后,它会将 400c74 更改为某个随机地址,例如 400ae4。 我以为可能是短跳和近跳的问题, 所以我什至做了 = 0x0f8e = 0x74400c7e = 0x0f8e400c74 等等。

但是,他们都在改变跳转到位置..

谁能解释一下为什么会这样?

set *(unsigned short*)0x4005a5 = 0x8e0f


2个我认为的问题:

  • set *0x4005a5 = 0x7e 可能默认为双字存储,写入 4 个字节而不是 1 个字节。
  • 并且您以两种不同的方式弄错了操作码:short 与 near,然后是 near 的字节序问题。

是的,原来的指令是使用Near encoding (jcc rel32),其中操作码是2个字节0f 8f。您可以看出,因为完整的指令是 6 个字节而不是 2 个字节,并且以 0f 开头(因此它不是单字节操作码。)

您将其替换为 1 字节的 Short jle rel8,因此第二个操作码字节变为 rel8。

(原始 8086 只有 jcc rel8 用于条件跳转,只有像 jmp 这样的无条件跳转具有 rel8 和 rel16 编码;在 186 和 386 之间的某处 jcc rel16/rel32 编码是已添加。)


您设置 0x0f8e 的尝试存在字节序问题。 x86 是小端,所以 jle 的操作码 0F 8E 作为小端 unsigned short 的值是 0x8e0f.

8Emov Sreg, r/m16 的操作码,因此 0x0f8e (8E 0F) 将解码为 mov 到段 reg,0F 为ModR/M 字节。修改后使用GDB反汇编指令

使用 GDB 的 disas /r 使用原始十六进制和助记符进行反汇编。