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

StackOverflow https://stackoverflow.com/questions/1237489

  •  11-09-2019
  •  | 
  •  

Вопрос

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

Я смог следить за вызовом fopen с помощью 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;
}
Это было полезно?

Решение

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

(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    $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 21 час, последнее, что я помню

Другие советы

Да, дизассемблирование — не лучшая команда для использования здесь.Вам нужна команда «x/i» (см. инструкции):

(gdb) x/i 0xdeadbeef

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

objdump -d program

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

fopen() - это функция библиотеки C, поэтому вы не увидите никаких инструкций системного вызова в своем коде, просто обычный вызов функции.В какой-то момент он вызывает 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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top