web-dev-qa-db-fra.com

Arrêt à la première instruction de code machine dans GDB

Après avoir chargé un exécutable dans gdb, comment puis-je m'arrêter au point d'entrée, avant l'exécution de la première instruction?

L'exécutable que j'analyse est un logiciel malveillant chiffré, donc break main ne fait absolument rien.

51
rickythefox

Le info files la commande peut vous donner une adresse sur laquelle vous pouvez vous baser:

(gdb) info files
    ...
    Entry point: 0x80000000
    ...
(gdb) break *0x80000000
(gdb) run
59
Jeff Ames

À partir de GDB 8.1, il existe une commande spéciale pour cela: starti. Exemple de session 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
26
Ruslan

La solution évidente consiste à utiliser l'effet secondaire de l'échec pour définir un point d'arrêt:

$ 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.

Idée tirée de cette réponse sur RE.SE .

13
Ruslan

"b _start" ou "b start "pourrait ou pourrait ne pas fonctionner. Sinon, recherchez l'adresse du point d'entrée avec readelf/objdump et utilisez" b *0x<hex address> ".

5
Igor Skochinsky

Après avoir chargé un exécutable dans gdb, comment puis-je m'arrêter au point d'entrée, avant l'exécution de la première instruction?

Vous pouvez trouver quelles fonctions sont appelées avant int main() avec set backtrace past-main on et après les avoir trouvés, définissez un point d'arrêt et redémarrez votre programme:

>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 ()
4
Sergei Kurenkov