我没有丰富的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个问题:我想做的是什么?如果是这样,我做错了什么?如果是这样,我做错了什么,我该如何解决?
我正在尝试做什么?
是的,您可以更改二进制文件的.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
都会向您展示您需要知道的一切.