使用 GDB 断点

Breakpoint using GDB

我使用 GDB 调试我的代码并在函数处设置断点时卡住(例如:使用来自 string.h 的 strcpy)。

1) 在这段代码中,gdb 在 strcpy 函数内的断点处停止。

 (gdb) list
1   #include<stdio.h>
2   #include<string.h>
3   main()
4   {
5   char a[20],b[]="ffff";
6   strcpy(a,b);
7   printf("%s\n",a);
8   }
(gdb) break 6
Breakpoint 1 at 0x8048486: file thu.c, line 6.
(gdb) break strcpy
Breakpoint 2 at 0x8048370
(gdb) break 7
Breakpoint 3 at 0x804849a: file thu.c, line 7.
(gdb) run
Starting program: /home/m/a.out 

Breakpoint 1, main () at thu.c:6
6   strcpy(a,b);
(gdb) c
Continuing.

Breakpoint 2, 0xb7ea2490 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) c
Continuing.

Breakpoint 3, main () at thu.c:7
7   printf("%s\n",a);

您可以看到 gdb 在断点 2 处停止(在 strcpy 内部)。

2) 在这段代码中,GDB 不会停在断点 2(在 strcpy 内部)而是转到断点 3。

(gdb) list
1   #include<stdio.h>
2   #include<string.h>
3   main()
4   {
5   char a[20];
6   strcpy(a,"hello world!");
7   printf("%s\n",a);
8   }
(gdb) break 6
Breakpoint 1 at 0x8048449: file thu.c, line 6.
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 2 (strcpy) pending.
(gdb) break 7
Breakpoint 3 at 0x8048469: file thu.c, line 7.
(gdb) run
Starting program: /home/m/a.out 

Breakpoint 1, main () at thu.c:6
6   strcpy(a,"hello world!");
(gdb) c
Continuing.

Breakpoint 3, main () at thu.c:7
7   printf("%s\n",a);

那么是什么让两种情况不同呢? 我按照书"Hacking: The Art of Exploitation" Jon Erickson,这是书中的一个例子,案例2与第39页的代码char_array2.c相似,但在断点的情况下输出与书中的不相似2.

感谢阅读!

在第一种情况下,编译器拥有所有细节(所有参数都是堆栈上已知偏移量的变量。因此编译器可能用宏替换了对 strcpy 的调用。在第二种情况下,不是所有细节关于参数是已知的,因此编译器插入了对 strcpy 的实际调用