ordenador - ¿Cómo desmontar un rango de memoria con GDB?
expandir memoria ps4 slim (8)
Estoy tratando de desmontar un programa para ver una instrucción de ensamblaje de syscall (la instrucción INT, creo) y el controlador con GDB y he escrito un pequeño programa (ver a continuación) para que abra y cierre un archivo.
Pude seguir la llamada para abrir con GDB hasta que ejecutó una llamada.
Cuando traté de decirle a GDB "disassemble 0x ...." (dirección de llamada) respondió con ''No function contains specified address''.
¿Es posible obligar a GDB a desmontar (o mostrarlo en el ensamblador lo mejor posible) esa dirección de memoria? ¿Si es así, cómo?
#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;
}
¿Solo quieres desmontar tu principal real? Si es así, intente esto:
(gdb) info line main
(gdb) disas STARTADDRESS ENDADDRESS
Al igual que:
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.
Sin embargo, no veo su llamada de interrupción del sistema. (Ha pasado un tiempo desde la última vez que intenté hacer una llamada al sistema en el ensamblaje. INT 21h sin embargo, la última vez que recuerdo
Esta no es la respuesta directa a tu pregunta, pero dado que pareces querer desensamblar el binario, quizás podrías usar objdump
:
objdump -d program
Esto debería darle su desmontaje. Puede agregar -S
si lo quiere anotado en origen.
No tiene que usar gdb. GCC lo hará.
gcc -S foo.c
Esto creará foo.s que es el ensamblaje.
gcc -m32 -c -g -Wa,-a,-ad foo.c > foo.lst
La versión anterior creará un archivo de listado que tiene tanto el C como el conjunto generado por él. Preguntas frecuentes sobre GCC
Puede forzar que gcc emita directamente el código ensamblador agregando el interruptor -S
gcc -S hello.c
Sí, desarmar no es el mejor comando para usar aquí. El comando que desea es "x / i" (examine como instrucciones):
(gdb) x/i 0xdeadbeef
Si todo lo que desea es ver el desmontaje con la llamada INTC, use objdump -d como alguien mencionó pero use la opción -static al compilar. De lo contrario, la función fopen no se compila en el duende y se vincula en el tiempo de ejecución.
fopen () es una función de biblioteca C y, por lo tanto, no verá ninguna instrucción syscall en su código, solo una llamada a función normal. En algún momento, llama abierta (2), pero lo hace a través de un trampolín. Simplemente hay un salto a la página VDSO, que proporciona el kernel a cada proceso. El VDSO luego proporciona el código para hacer que el sistema llame. En los procesadores modernos, se usarán las instrucciones SYSCALL o SYSENTER, pero también se puede usar INT 80h en procesadores x86.
gdb disassemble tiene un / m para incluir el código fuente junto con las instrucciones. Esto es equivalente a objdump -S, con el beneficio adicional de limitar solo a la función (o rango de direcciones) de interés.