Как разобрать диапазон памяти с 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 ответов:
вы только хотите разобрать ваш реальный? Если да, то попробуйте это:
(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