5 c gcc gdb reverse-engineering strcpy
所以我正在阅读Hacking the Art of Exploitation并且在书中,他们strcpy()在他们的 C 代码中使用了这个函数:
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 char str_a[20];
6
7 strcpy(str_a, "Hello, world!\n");
8 printf(str_a);
9 }
Run Code Online (Sandbox Code Playgroud)
然后他们继续编译他们的源代码并使用gdb. 他在第 6 行、strcpy函数和第 8行设置了一个断点,但是在设置断点时strcpy会显示以下内容:
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Run Code Online (Sandbox Code Playgroud)
我知道这是因为库还没有加载,所以它问他是否想把它作为一个挂起的断点。然后他运行程序并继续通过断点:

一切对他来说都很好,但是当我尝试在我的计算机上重新创建它时,我得到以下信息:
frinto@kali:~/Documents/theclang/programs/helloworld$ gcc -m32 -g -o char_array char_array.c
frinto@kali:~/Documents/theclang/programs/helloworld$ gdb -q char_array
Reading symbols from char_array...done.
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 char str_a[20];
6
7 strcpy(str_a, "Hello, world!\n");
8 printf(str_a);
9 }
(gdb) break 6
Breakpoint 1 at 0x11b6: file char_array.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 8
Breakpoint 3 at 0x11d7: file char_array.c, line 8.
(gdb) run
Starting program: /home/frinto/Documents/theclang/programs/helloworld/char_array
Breakpoint 1, main () at char_array.c:7
7 strcpy(str_a, "Hello, world!\n");
(gdb) cont
Continuing.
Breakpoint 3, main () at char_array.c:8
8 printf(str_a);
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 4021) exited normally]
(gdb)
Run Code Online (Sandbox Code Playgroud)
注意它是如何完全跳过strcpy断点的?好吧,我问我的一个朋友这里有什么问题,他告诉我-fno-builtin编译时我错过了参数。我对这个论点做了一些最小的谷歌搜索,我真正理解的是它允许你在内置函数上设置断点。所以我用-fno-builtin参数编译了程序,然后尝试再次重新创建它:
frinto@kali:~/Documents/theclang/programs/helloworld$ gcc -m32 -fno-builtin -g -o char_array char_array.c
frinto@kali:~/Documents/theclang/programs/helloworld$ gdb -q char_array
Reading symbols from char_array...done.
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 char str_a[20];
6
7 strcpy(str_a, "Hello, world!\n");
8 printf(str_a);
9 }
(gdb) break 6
Breakpoint 1 at 0x11c6: file char_array.c, line 6.
(gdb) break strcpy
Breakpoint 2 at 0x1040
(gdb) break 8
Breakpoint 3 at 0x11dc: file char_array.c, line 8.
(gdb) run
Starting program: /home/frinto/Documents/theclang/programs/helloworld/char_array
Breakpoint 1, main () at char_array.c:7
7 strcpy(str_a, "Hello, world!\n");
(gdb) cont
Continuing.
Breakpoint 2, 0xf7e510b0 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) cont
Continuing.
Breakpoint 3, main () at char_array.c:8
8 printf(str_a);
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 3969) exited normally]
(gdb)
Run Code Online (Sandbox Code Playgroud)
现在它起作用了!我有三个问题:
-fno-builtin论证究竟在做什么?strcpy函数Breakpoint 2, 0xf7e510b0 in ?? () from /lib/i386-linux-gnu/libc.so.6
strcpy当我使用-fno-builtin参数时,为什么不要求将断点设置为挂起?对不起,我想确保一切都被理解了。
来自 man gcc
-fno-builtin
-fno-builtin-function
Don't recognize built-in functions that do not begin with
__builtin_ as prefix. GCC normally generates special code to
handle certain built-in functions more efficiently; for
instance, calls to "alloca" may become single instructions
which adjust the stack directly, and calls to "memcpy" may
become inline copy loops. The resulting code is often both
smaller and faster, but since the function calls no longer
appear as such, you cannot set a breakpoint on those calls, nor
can you change the behavior of the functions by linking with a
different library. In addition, when a function is recognized
as a built-in function, GCC may use information about that
function to warn about problems with calls to that function, or
to generate more efficient code, even if the resulting code
still contains calls to that function. For example, warnings
are given with -Wformat for bad calls to "printf" when "printf"
is built in and "strlen" is known not to modify global memory.
With the -fno-builtin-function option only the built-in
function function is disabled. function must not begin with
__builtin_. If a function is named that is not built-in in
this version of GCC, this option is ignored. There is no
corresponding -fbuiltin-function option; if you wish to enable
built-in functions selectively when using -fno-builtin or
-ffreestanding, you may define macros such as:
#define abs(n) __builtin_abs ((n))
#define strcpy(d, s) __builtin_strcpy ((d), (s))
Run Code Online (Sandbox Code Playgroud)
函数内置允许通过内联函数来生成更快的代码,但如手册中所述
you cannot set a breakpoint on those calls
Run Code Online (Sandbox Code Playgroud)
内联函数意味着,它的效果被编译器直接插入的代码所取代,而不是生成函数调用。这节省了函数调用,并且可以更有效地优化,并且通常会导致性能的大幅提高。
但是,代码中不再存在内联函数。调试器断点是通过用一些软件陷阱替换特定地址处的指令或使用特定硬件来识别何时到达断点地址来实现的。但由于该函数不再存在,因此没有与其关联的地址,并且无法对其进行断点。
挂起断点是在某些代码上设置断点的方法,这些代码稍后将由程序动态加载。有了-fno-builtin,strcpy就可以直接使用,并且可以通过 gdb 直接设置 bp。
请注意,调试需要 -g 标志生成的可执行文件中的特定信息。一般像libc这样的系统库没有嵌入调试信息,当进入这些库中的函数时,gdb通过??表示缺少调试信息。
| 归档时间: |
|
| 查看次数: |
3082 次 |
| 最近记录: |