Подтвердить что ты не робот

Как я могу заставить GDB разбираться?

Я пытаюсь разобрать программу, чтобы увидеть инструкцию сборки syscall (инструкция INT, я считаю), и обработчик с GDB и написал небольшую программу (см. ниже) для нее, которая открывает и закрывает файл. Я смог выполнить вызов, чтобы открыть с GDB, пока он не выполнит вызов. Когда я попытался сказать GDB "разобрать 0x...." (адрес вызова), он ответил "Нет функции содержит указанный адрес". Можно ли заставить GDB дизассемблировать (или как можно лучше отобразить его на ассемблере) этот адрес памяти? Если да, то как?

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE* f;
    f = fopen("main.c", "r");
    if (!f) { 
      perror("open");
      return -1;
    }
fclose(f);
return 0;
}
4b9b3361

Ответ 1

Вы хотите только разобрать свой основной? Если да, попробуйте следующее:

(gdb) info line main 
(gdb) disas STARTADDRESS ENDADDRESS

Так же:

[email protected] /cygdrive/c/prog/dsa
$ gcc-3.exe -g main.c

[email protected] /cygdrive/c/prog/dsa
$ gdb a.exe
GNU gdb 6.8.0.20080328-cvs (cygwin-special)
...
(gdb) info line main
Line 3 of "main.c" starts at address 0x401050 <main> and ends at 0x401075 <main+
(gdb) disas 0x401050 0x401075
Dump of assembler code from 0x401050 to 0x401075:
0x00401050 <main+0>:    push   %ebp
0x00401051 <main+1>:    mov    %esp,%ebp
0x00401053 <main+3>:    sub    $0x18,%esp
0x00401056 <main+6>:    and    $0xfffffff0,%esp
0x00401059 <main+9>:    mov    $0x0,%eax
0x0040105e <main+14>:   add    $0xf,%eax
0x00401061 <main+17>:   add    $0xf,%eax
0x00401064 <main+20>:   shr    $0x4,%eax
0x00401067 <main+23>:   shl    $0x4,%eax
0x0040106a <main+26>:   mov    %eax,-0xc(%ebp)
0x0040106d <main+29>:   mov    -0xc(%ebp),%eax
0x00401070 <main+32>:   call   0x4010c4 <_alloca>
End of assembler dump.

Я не вижу ваш вызов прерывания системы. (это было некоторое время с тех пор, как я в последний раз пытался сделать системный вызов в сборке. INT 21h, хотя, последний раз я помню

Ответ 2

Да, дизассемблер - не самая лучшая команда для использования здесь. Команда, которую вы хотите, это "x/i" (проверьте как инструкции):

(gdb) x/i 0xdeadbeef

Ответ 3

Это не прямой ответ на ваш вопрос, но поскольку вы просто хотите разобрать двоичный файл, возможно, вы можете просто использовать objdump:

objdump -d program

Это должно дать вам разборку. Вы можете добавить -S, если хотите, чтобы он был аннотирован исходным кодом.

Ответ 4

fopen() является библиотечной функцией C, поэтому вы не увидите никаких команд syscall в своем коде, а просто обычный вызов функции. В какой-то момент он вызывает open (2), но он делает это через батут. Существует просто переход на страницу VDSO, которая предоставляется ядром для каждого процесса. Затем VDSO предоставляет код для вызова системы. На современных процессорах будут использоваться команды SYSCALL или SYSENTER, но вы также можете использовать INT 80h на процессорах x86.

Ответ 5

Вы можете заставить gcc выводить непосредственно на код сборки, добавив ключ -S

gcc -S hello.c

Ответ 6

Если все, что вы хотите, это увидеть разборку с вызовом INTC, используйте objdump -d, как и кто-то, но используйте параметр -static при компиляции. В противном случае функция fopen не будет скомпилирована в эльф и связана во время выполнения.

Ответ 7

Вам не нужно использовать gdb. GCC это сделает.

 gcc -S foo.c

Это создаст foo.s, который является сборкой.

gcc -m32 -c -g -Wa,-a,-ad foo.c > foo.lst

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

Ответ 8

gdb дизассемблер имеет a/m для включения исходного кода вместе с инструкциями. Это эквивалентно objdump -S, с дополнительным преимуществом, ограничивающим только одну функцию (или адрес-диапазон), представляющую интерес.