Что именно здесь делает -fno-builtin? - PullRequest
0 голосов
/ 21 января 2019

Итак, я читал Взламывая искусство эксплуатации , и в книге они используют функцию 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       }

Затем они приступают к компиляции своихИсходный код и проанализируйте его с помощью gdb.Он устанавливает точку останова в строке 6, функции strcpy и строке 8, но при установке остановки в strcpy он читает следующее:

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

Я понимаю, что это потому, что библиотека имеетеще не загружен, поэтому он спрашивает, хочет ли он иметь его в качестве ожидающей точки останова.Затем он запускает программу и продолжает через точки останова:

image

У него все работает хорошо, но когда я попытался воссоздать это на своем компьютере, я получил следующее:

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, а затем попытался воссоздать ее снова:

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) 

Теперь это работает!У меня есть три вопроса:

  1. Что именно делает аргумент -fno-builtin?
  2. Почему в
вместо функции strcpy отображаются знаки вопроса

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

Почему не запрашивается установка точки останова strcpy как ожидающей, когда я использую аргумент -fno-builtin?

Извините за длинный поток, я просто хотел сделатьуверен, что все поняли.

1 Ответ

0 голосов
/ 21 января 2019

От 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))

Встроенные функции функции позволяют генерировать более быстрый код путем вставки функции, но, как указано в руководстве

you cannot set a breakpoint on those calls

Подстановка функции означает, что вместогенерации вызова функции, его эффекты заменяются кодом, непосредственно вставленным компилятором.Это сохраняет вызов функции и может быть более эффективно оптимизировано и, как правило, приводит к значительному улучшению производительности.

Но встроенная функция больше не существует в коде.Точки останова отладчика реализуются путем замены инструкций по определенным адресам на некоторые программные ловушки или с помощью специального оборудования для распознавания, когда достигается точка останова.Но так как функция больше не существует, с ней не связан ни один адрес, и ее невозможно остановить.

Ожидание точек останова означает установку точки останова для некоторого кода, который позже будет динамически загруженпрограмма.С -fno_builtin, strcpy доступен напрямую, и bp может быть напрямую установлен gdb.

Обратите внимание, что для отладки требуется конкретная информация в исполняемом файле, генерируемом флагом -g.Как правило, системные библиотеки, такие как libc, не имеют встроенной информации, и при вводе функции в эти библиотеки gdb указывает на отсутствие отладочной информации ??.

...