更改助记符更改地址

时间:2018-09-18 05:12:22

标签: assembly x86 gdb machine-code

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

比方说,我正在尝试修改此内容:

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

所以,我做到了

$set *0x4005a5 = 0x7e

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

但是,他们都在改变跳转的位置。

请问有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

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


我认为2个问题:

  • set *0x4005a5 = 0x7e可能默认为dword存储,写入4个字节而不是1个字节。
  • 然后您用两种不同的方式将操作码弄错了:short与Near,然后是end的endian问题。

是的,原始指令使用的是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是小端的,因此jle作为小端0F 8E的操作码unsigned short的值为0x8e0f

8Emov Sreg, r/m16的操作码,因此0x0f8e8E 0F)将作为段reg的mov进行解码,而0F为ModR / M字节。修改后,使用GDB分解指令。

使用GDB的disas /r来分解原始十六进制和助记符。