gpt4 book ai didi

c - 使用 GDB 更改 for 循环条件?

转载 作者:行者123 更新时间:2023-12-05 04:09:24 26 4
gpt4 key购买 nike

我正在尝试调试一个程序并且对 for(int i =0; i<10; i++) 这行感兴趣并想在 GDB 调试器中将 i <10 更改为 i<=10。我已经使用 print 来更改变量名称,但我该怎么做呢?谢谢。

最佳答案

want to change i <10 to i<=10 in the GDB debugger.

有几种方法可以做到这一点,完全取决于您的需要。

我假设您只需要执行一次,您的二进制文件是在 x86_64 上构建的,没有经过优化。

给定:

#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++)
printf("%d\n", i);
return 0;
}

gcc -g -std=c99 t.c && gdb -q ./a.out

gdb) disas main
Dump of assembler code for function main:
0x000000000040052d <+0>: push %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x10,%rsp
0x0000000000400535 <+8>: movl $0x0,-0x4(%rbp)
0x000000000040053c <+15>: jmp 0x400556 <main+41>
0x000000000040053e <+17>: mov -0x4(%rbp),%eax
0x0000000000400541 <+20>: mov %eax,%esi
0x0000000000400543 <+22>: mov $0x4005f4,%edi
0x0000000000400548 <+27>: mov $0x0,%eax
0x000000000040054d <+32>: callq 0x400410 <printf@plt>
0x0000000000400552 <+37>: addl $0x1,-0x4(%rbp)
0x0000000000400556 <+41>: cmpl $0x9,-0x4(%rbp)
0x000000000040055a <+45>: jle 0x40053e <main+17>
0x000000000040055c <+47>: mov $0x0,%eax
0x0000000000400561 <+52>: leaveq
0x0000000000400562 <+53>: retq
End of assembler dump.

在这里您可以看到地址 0x400556 的指令将 i 的值(存储在堆栈中 $rbp-4 的位置)与常量9,小于等于9则跳转。

因此您可以在 0x40055a 处的指令上设置一个断点,然后强制执行跳转,即使编译后的代码表明它不应该:

(gdb) b *0x40055a if i == 10
Breakpoint 1 at 0x40055a: file t.c, line 4.
(gdb) run
Starting program: /tmp/a.out
0
1
2
3
4
5
6
7
8
9

Breakpoint 1, 0x000000000040055a in main () at t.c:4
4 for (int i = 0; i < 10; i++)
(gdb) p i
$1 = 10
(gdb) jump *0x40053e
Continuing at 0x40053e.
10
[Inferior 1 (process 22210) exited normally]

瞧:我们打印了一个额外的值。

另一种可能的做法:在0x400556处设置断点,将i的值调整为i-1,单步执行,将i的值调整为i+1,继续。

另一种方法:对 0x400556 处的指令进行二进制修补,以与常数 10 而不是 9 进行比较:

(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 09 cmpl $0x9,-0x4(%rbp)
End of assembler dump.

在这里您可以看到常量 9 是指令字节的一部分,特别是地址 0x400559 处的字节。您可以更改该字节:

(gdb) start

Starting program: /tmp/a.out

Temporary breakpoint 1, main () at t.c:4
4 for (int i = 0; i < 10; i++)

让我们覆盖指令并再次反汇编:

(gdb) set *(char*)0x400559 = 10
(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 0a cmpl $0xa,-0x4(%rbp)
End of assembler dump.

看起来不错:我们现在比较 10 而不是 9。有用吗?

(gdb) c
Continuing.
0
1
2
3
4
5
6
7
8
9
10
[Inferior 1 (process 23131) exited normally]

是的,确实如此!

附言对指令进行二进制修补等同于编辑源代码并重建二进制文件,只是补丁在下一次运行时被“遗忘”。

关于c - 使用 GDB 更改 for 循环条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46026451/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com