实时编辑code使用gdb [英] Live editing code with gdb
问题描述
我没有使用gdb丰富的经验,所以我不知道什么,我问的是甚至有可能,但是它可以编辑code生活用gdb?
在运行(遇到断点后),disas看起来像这样:
0x080487d8 1 + 9计算值:MOVL $ 0x80485e4,0x1c(%ESP)
0x080487e0 1 + 17计算值:MOVL $ 0x8048640,0x20(%尤)
0x080487e8 1 + 25计算值:MOVL $ 0x804869c,0X24(%尤)
0x080487f0 1 + 33计算值:MOVL $ 0x8048719,0x28(%尤)
在试图在这些指令之一更改地址,我这样做:
设置(* 0x080487e1)= 0x5b870408
但是,而不是简单地改变地址,如我所料,新disas是这样的:
0x080487d8 1 + 9计算值:MOVL $ 0x80485e4,0x1c(%ESP)
0x080487e0 1 + 17计算值:(坏)
0x080487e1 1 + 18计算值:或%人,(%EDI,%eax中,4)
0x080487e4 1 + 21计算值:流行%EBX
0x080487e5 1 + 22:XCHG%人,(%eax中,%ecx中,1)
0x080487e8 1 + 25计算值:MOVL $ 0x804869c,0X24(%尤)
0x080487f0 1 + 33计算值:MOVL $ 0x8048719,0x28(%尤)
因此,我有3个问题:就是我试图做可能吗?如果是这样,我是不是做错了什么?如果是这样,我做错了,我该如何解决这个问题?
正是我试图做可能吗?
块引用>是的,你可以改变的.text二进制的。
请注意,这种变化只会影响当前执行;在
运行
你的变化将蒸发(如果你想永久修补二进制文件,这是可能的,但程序是不同的)。
如果这样,我是不是做错了什么?
块引用>可能的。你没告诉我们您正在试图改变指令的内容。
如果是这样,什么我做错了,我该如何解决这个问题?
块引用>使用
(GDB)disas / R
将显示实际原始的指令字节,并可能会更容易地看到你做错了什么。当我使用它,我看到:0x080483ed 1 + 9计算值:C7 44 24 1C D0 84 04 08 $ MOVL 0x80484d0,0x1c(%ESP)
也就是说,地址(你显然是想覆盖)为的 的上述指令[1]
&功放没有开始;指令+ 1
,它开始于&放大器;指令+ 4
。此外,当你问到GDB写一个字(我猜你想要的新地址是0x0804785b
,而不是你不应该扭转字节0x5b870408
)(GDB)集*(0x080483ed + 4)= 0x01020304
(GDB)disas
汇编code的转储为主要功能:
0x080483e4 1 + 0计算值:推%EBP
0x080483e5 1 + 1&GT ;: MOV%ESP,EBP%
0x080483e7 1 + 3计算值:和$ 0xfffffff0,%尤
0x080483ea 1 + 6个;:子$为0x20,%尤
= GT; 0x080483ed 1 + 9计算值:MOVL $ 0x1020304,0x1c(%尤)
0x080483f5 1 + 17计算值:MOV为0x1c(%ESP),%eax中
0x080483f9 1 + 21计算值:MOV%eax中,(%尤)
0x080483fc 1 + 24计算值:调用0x8048318&下;把@ PLT>
0x08048401 1 + 29计算值:MOV $为0x0,%eax中
0x08048406 1 + 34计算值:离开
0x08048407 1 + 35计算值:保留[1]是的非常的可能是您的指令:
0x080487e0 1 + 17计算值:MOVL $ 0x8048640,0x20(%ESP)
有同样的编码作为我的指令:
0x080483ed 1 + 9计算值:MOVL $ 0x80484d0,0x1c(%ESP)
,因为它们是相同的,并具有相同的8字节的长度,但如FrankH指出的那样,可能存在相同的指令的不同的编码。在任何情况下,
disas / R
会告诉你所有你需要知道的。I do not have extensive experience with gdb, so I am not sure if what I am asking is even possible, but is it possible to edit the code live with gdb?
When running (after hitting a breakpoint), the disas looks like so:
0x080487d8 <+9>: movl $0x80485e4,0x1c(%esp) 0x080487e0 <+17>: movl $0x8048640,0x20(%esp) 0x080487e8 <+25>: movl $0x804869c,0x24(%esp) 0x080487f0 <+33>: movl $0x8048719,0x28(%esp)
In an attempt to change the address in one of those instructions, I did this:
set (*0x080487e1)=0x5b870408
But instead of simply changing the address as I expected, the new disas looked like this:
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)
So I have 3 questions: Is what I am trying to do possible? If so, am I doing something wrong? If so, what am I doing wrong and how can I fix it?
解决方案Is what I am trying to do possible?
Yes, you can change .text of a binary.
Note that this change will only affect current execution; upon
run
your change will "evaporate" (if you wanted to permanently patch the binary, that's possible as well, but the procedure is different).If so, am I doing something wrong?
Likely. You didn't tell us what you are trying to change the instruction to.
If so, what am I doing wrong and how can I fix it?
Using
(gdb) disas/r
will show you actual raw instruction bytes, and will likely make it easier to see what you did wrong. When I use it, I see this:0x080483ed <+9>: c7 44 24 1c d0 84 04 08 movl $0x80484d0,0x1c(%esp)
That is, the address (which you apparently wanted to overwrite) for the instruction above [1] does not begin at
&instruction+1
, it begins at&instruction+4
. Also, you shouldn't reverse the bytes when you ask GDB to write a word (I am guessing you wanted the new address to be0x0804785b
and not0x5b870408
):(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
[1] It is very likely that your instruction:
0x080487e0 <+17>: movl $0x8048640,0x20(%esp)
has the same encoding as my instruction:
0x080483ed <+9>: movl $0x80484d0,0x1c(%esp)
as they are the "same", and have the same 8-byte length, but as FrankH pointed out, there might exist a different encoding of the same instruction. In any case,
disas/r
will show you all you need to know.这篇关于实时编辑code使用gdb的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!