【问题标题】:changing mnemonic changes address更改助记词更改地址
【发布时间】:2018-09-18 05:12:21
【问题描述】:

我是 gdb 和程序集的新手。我正在尝试将助记符指令从jg 更改为jle,但是每当我更改助记符时,它也会更改目标地址。例如,

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

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

原来如此

$set *0x4005a5 = 0x7e

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

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

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

【问题讨论】:

  • 你能从 GDB 显示之后的反汇编吗?我不确定set 的默认大小,它可能会覆盖多个字节。而 x86 是 little-endian,所以 0x0f8e 不是 0f 8e

标签: assembly x86 gdb machine-code


【解决方案1】:

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


我认为的2个问题:

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

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

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

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


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

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

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

【讨论】:

  • 感谢您的快速回复!我尝试了jle rel32,即0x0F8E,但它仍然改变了地址......还有其他原因吗?谢谢!
  • 非常感谢.. 解决所有问题的无符号短...非常感谢您花时间解开这个谜团!我从你那里学到了一些有价值的东西。
猜你喜欢
  • 2020-08-01
  • 2016-03-02
  • 2020-07-27
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多