Как разобрать диапазон памяти с GDB?


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

Я был в состоянии следовать вызову fopen с GDB, пока он не выполнил вызов.

когда я пытался сказать GDB " disassemble 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;
}
8 55

8 ответов:

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

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

вот так:

USER@MACHINE /cygdrive/c/prog/dsa
$ gcc-3.exe -g main.c

USER@MACHINE /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    x18,%esp
0x00401056 <main+6>:    and    xfffffff0,%esp
0x00401059 <main+9>:    mov    x0,%eax
0x0040105e <main+14>:   add    xf,%eax
0x00401061 <main+17>:   add    xf,%eax
0x00401064 <main+20>:   shr    x4,%eax
0x00401067 <main+23>:   shl    x4,%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.

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

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

(gdb) x/i 0xdeadbeef

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

objdump -d program

Это должно дать вам его декомпиляцию. Вы можете добавить -S Если вы хотите его источник-аннотированный.

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

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

gcc -S hello.c

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

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

 gcc -S foo.c

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

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

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

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