使用gdb实时编辑代码

Jum*_*hyn 4 assembly gdb

我没有丰富的gdb经验,所以我不确定我的问题是否可行,但是可以用gdb编辑代码吗?

运行时(在遇到断点之后),disas看起来像这样:

0x080487d8 <+9>:    movl   $0x80485e4,0x1c(%esp)
0x080487e0 <+17>:   movl   $0x8048640,0x20(%esp)
0x080487e8 <+25>:   movl   $0x804869c,0x24(%esp)
0x080487f0 <+33>:   movl   $0x8048719,0x28(%esp)
Run Code Online (Sandbox Code Playgroud)

为了尝试更改其中一条指令中的地址,我这样做了:

set (*0x080487e1)=0x5b870408
Run Code Online (Sandbox Code Playgroud)

但不是像我预期的那样简单地改变地址,新的disas看起来像这样:

0x080487d8 <+9>:    movl   $0x80485e4,0x1c(%esp)
0x080487e0 <+17>:   (bad)  
0x080487e1 <+18>:   or     %al,(%edi,%eax,4)
0x080487e4 <+21>:   pop    %ebx
0x080487e5 <+22>:   xchg   %al,(%eax,%ecx,1)
0x080487e8 <+25>:   movl   $0x804869c,0x24(%esp)
0x080487f0 <+33>:   movl   $0x8048719,0x28(%esp)
Run Code Online (Sandbox Code Playgroud)

所以我有3个问题:我想做的是什么?如果是这样,我做错了什么?如果是这样,我做错了什么,我该如何解决?

Emp*_*ian 8

我正在尝试做什么?

是的,您可以更改二进制文件的.text.

请注意,此更改仅会影响当前执行; 当run你的变化将"蒸发"(如果你想永久修补二进制文件,这是可能的,但过程是不同的).

如果是这样,我做错了什么?

有可能.您没有告诉我们您要更改指令的内容.

如果是这样,我做错了什么,我该如何解决?

使用(gdb) disas/r将显示实际的原始指令字节,并可能更容易看到你做错了什么.当我使用它时,我看到了这个:

   0x080483ed <+9>: c7 44 24 1c d0 84 04 08 movl   $0x80484d0,0x1c(%esp)
Run Code Online (Sandbox Code Playgroud)

也就是说,上面 [1] 的指令的地址(你显然想要覆盖它)不是从&instruction+1它开始的,它始于&instruction+4.另外,当你要求GDB写一个单词时,你不应该反转字节(我猜你想要新的地址0x0804785b而不是0x5b870408):

(gdb) set *(0x080483ed+4)=0x01020304
(gdb) disas
Dump of assembler code for function main:
   0x080483e4 <+0>: push   %ebp
   0x080483e5 <+1>: mov    %esp,%ebp
   0x080483e7 <+3>: and    $0xfffffff0,%esp
   0x080483ea <+6>: sub    $0x20,%esp
=> 0x080483ed <+9>: movl   $0x1020304,0x1c(%esp)
   0x080483f5 <+17>:    mov    0x1c(%esp),%eax
   0x080483f9 <+21>:    mov    %eax,(%esp)
   0x080483fc <+24>:    call   0x8048318 <puts@plt>
   0x08048401 <+29>:    mov    $0x0,%eax
   0x08048406 <+34>:    leave  
   0x08048407 <+35>:    ret    
Run Code Online (Sandbox Code Playgroud)

[1] 你的指示可能是:

0x080487e0 <+17>: movl   $0x8048640,0x20(%esp)
Run Code Online (Sandbox Code Playgroud)

与我的指令具有相同的编码:

0x080483ed  <+9>: movl   $0x80484d0,0x1c(%esp)
Run Code Online (Sandbox Code Playgroud)

因为它们是"相同的",并且具有相同的8字节长度,但正如FrankH指出的那样,可能存在相同指令的不同编码.在任何情况下,disas/r都会向您展示您需要知道的一切.