gdb - instrucciones - lenguaje ensamblador pdf
Parando en la primera instrucción de código de máquina en GDB (5)
Después de cargar un archivo ejecutable en gdb, ¿cómo rompo el punto de entrada antes de que se ejecute la primera instrucción?
El ejecutable que estoy analizando es una pieza de malware que está cifrada, por lo que break main
no hace absolutamente nada.
Después de cargar un archivo ejecutable en gdb, ¿cómo rompo el punto de entrada antes de que se ejecute la primera instrucción?
Puede encontrar las funciones a las que se llama antes de int main()
con set backtrace past-main on
y después de encontrarlas, establezca un punto de interrupción en ellas y reinicie su programa:
>gdb -q main
Reading symbols from /home/main...done.
(gdb) set backtrace past-main on
(gdb) b main
Breakpoint 1 at 0x40058a: file main.cpp, line 25.
(gdb) r
Starting program: /home/main
Breakpoint 1, main () at main.cpp:25
25 a();
(gdb) bt
#0 main () at main.cpp:25
#1 0x0000003a1d81ed1d in __libc_start_main () from /lib64/libc.so.6
#2 0x0000000000400499 in _start ()
(gdb) b _start
Breakpoint 2 at 0x400470
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/main
Breakpoint 2, 0x0000000000400470 in _start ()
" b _start
" o " b start
" puede o no funcionar. Si no es así, busque la dirección de punto de entrada con readelf / objdump y utilice " b *0x<hex address>
".
A partir de GDB 8.1, hay un comando especial para esto: starti
. Ejemplo de sesión GDB:
$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) starti
Starting program: /bin/true
Program stopped.
0xf7fdd800 in _start () from /lib/ld-linux.so.2
(gdb) x/5i $pc
=> 0xf7fdd800 <_start>: mov eax,esp
0xf7fdd802 <_start+2>: call 0xf7fe2160 <_dl_start>
0xf7fdd807 <_dl_start_user>: mov edi,eax
0xf7fdd809 <_dl_start_user+2>: call 0xf7fdd7f0
0xf7fdd80e <_dl_start_user+7>: add ebx,0x1f7e6
El comando de info files
puede darle una dirección en la que puede interrumpir:
(gdb) info files
...
Entry point: 0x80000000
...
(gdb) break *0x80000000
(gdb) run
La solución sencilla es utilizar el efecto secundario de no establecer un punto de interrupción:
$ gdb /bin/true
Reading symbols from /bin/true...(no debugging symbols found)...done.
(gdb) b *0
Breakpoint 1 at 0x0
(gdb) r
Starting program: /bin/true
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x0
(gdb) disas
Dump of assembler code for function _start:
=> 0xf7fdd800 <+0>: mov eax,esp
0xf7fdd802 <+2>: call 0xf7fe2160 <_dl_start>
End of assembler dump.
Idea tomada de esta respuesta en RE.SE.