-fno-builtin在这里到底在做什么? [英] What exactly is -fno-builtin doing here?

查看:379
本文介绍了-fno-builtin在这里到底在做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我读了《 利用剥削的艺术》 ,在书中,他们在C代码中使用了strcpy()函数:

So I was reading Hacking the Art of Exploitation and in the book, they use the strcpy() function in their C code:

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对其进行分析.他在第6行,strcpy函数和第8行上设置断点,但是在strcpy上设置断点时,它将读取以下内容:

They then proceed to compile their source code and analyze it with gdb. He sets a breakpoint on line 6, the strcpy function, and line 8, but when setting a break on strcpy it reads the following:

(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

我知道这是因为尚未加载库,所以询问他是否要将其作为挂起的断点.然后他运行程序并继续执行断点:

I understand that this is because the library has not yet been loaded, so it's asking if he wants to have it as a pending breakpoint. Then he runs the program and continues through the breakpoints:

一切对他来说都很好,但是当我尝试在计算机上重新创建它时,我得到以下信息:

Everything works well for him, but when I tried to re-create this on my computer, I get the following:

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) 

注意它如何完全跳过strcpy断点?好吧,我问了我的一个朋友,这里的问题是什么,他告诉我在编译时我遗漏了-fno-builtin参数.我对此参数做了一些最小化的google搜索,我真正理解的是,它可以让您在内置函数上设置断点.因此,我用-fno-builtin参数编译了程序,然后尝试再次重新创建它:

Notice how it completely skipped the strcpy breakpoint? Well, I asked a friend of mine what was the issue here, and he told me that I was missing the argument -fno-builtin when compiling. I did some minimal google searching on this argument and all I really understood is that it lets you set breakpoints on built-in functions. So I compiled the program with the -fno-builtin argument and then tried to re-create this again:

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) 

现在可以使用了!我有三个问题:

Now it works! I have three questions:

  1. -fno-builtin参数到底在做什么?
  2. 为什么它显示问号而不是
  3. 中的strcpy函数
  1. What exactly is the -fno-builtin argument doing?
  2. Why does it show question marks instead of the strcpy function in

Breakpoint 2, 0xf7e510b0 in ?? () from /lib/i386-linux-gnu/libc.so.6

  1. 当我使用-fno-builtin参数时,为什么不要求将strcpy断点设置为未决?
  1. Why doesn't it ask to set the strcpy breakpoint as pending when I use the -fno-builtin argument?

很抱歉,我想确保所有内容都被理解.

推荐答案

来自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))

函数内置函数允许通过内联函数来生成更快的代码,但是如手册中所述

function builtins allow to generate a faster code by inlining the function, but as stated in the manual

you cannot set a breakpoint on those calls

内联函数意味着,与其生成一个函数调用,不如将其效果替换为编译器直接插入的代码.这样可以节省函数调用,并且可以更有效地优化它,并且通常可以大大提高性能.

Inlining a function means that, instead of generating a function call, its effects are replaced by code directly inserted by the compiler. This saves a function call and can be more efficiently optimized and generally leads to a large improvement in performances.

但是,内联函数不再存在于代码中.调试器断点是通过用某些软件陷阱替换特定地址处的指令或使用特定硬件来识别何时到达断点地址来实现的.但是由于该功能不再存在,因此没有地址与之关联,也无法断点它.

But, the inlined function no longer exists in the code. Debugger breakpoints are implemented by replacing instructions at specific addresses by some software traps or by using specific hardware to recognize when the breakpointed address is reached. But as the function no longer exists, no address is associated with it, and there is no way to breakpoint it.

挂起的断点是在某些代码上设置断点的一种方法,这些代码稍后将由程序动态加载.使用-fno-builtin可以直接使用strcpy,并且bp可以由gdb直接设置.

Pending breakpoints are a mean to set a breakpoint on some code that will be dynamically loaded later by the program. With -fno-builtin, strcpy is directly available and the bp can be directly set by gdb.

请注意,调试需要-g标志生成的可执行文件中的特定信息.通常,像libc这样的系统库都没有嵌入调试信息,并且在这些库中输入函数时,gdb会用??指示缺少调试信息.

Note that debugging requires specific information in the executable generated by the -g flag. Generally system libraries like libc do not have the debugging information embedded and when entering function in these libraries, gdb indicates the lack of debugging information by ??.

这篇关于-fno-builtin在这里到底在做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆