web-dev-qa-db-fra.com

Comment démonter une plage mémoire avec GDB?

J'essaie de démonter un programme pour voir une instruction d'assemblage syscall (l'instruction INT, je crois) et le gestionnaire avec GDB et j'ai écrit un petit programme (voir ci-dessous) pour cela qui ouvre et ferme un fichier.

J'ai pu suivre l'appel à ouvrir avec GDB jusqu'à ce qu'il exécute un appel.

Lorsque j'ai essayé de dire à GDB "démonter 0x ...." (adresse de l'appel), il a répondu "Aucune fonction ne contient l'adresse spécifiée".

Est-il possible de forcer GDB à démonter (ou à l'afficher dans l'assembleur aussi bien que possible) cette adresse mémoire? Si c'est le cas, comment?

#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;
}
58
Patrick

Souhaitez-vous uniquement démonter votre alimentation principale? Si oui, essayez ceci:

(gdb) info line main 
(gdb) disas STARTADDRESS ENDADDRESS

Ainsi:

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.

Je ne vois pas votre appel d'interruption système cependant. (ça fait un moment que je n'ai pas essayé d'appeler le système pour la dernière fois. INT 21h cependant, la dernière je me souviens

45
nont

Ouais, démonter n'est pas la meilleure commande à utiliser ici. La commande que vous voulez est "x/i" (examinez comme instructions):

(gdb) x/i 0xdeadbeef
95
Michael Snyder

Ce n'est pas la réponse directe à votre question, mais comme vous semblez vouloir simplement désassembler le binaire, vous pouvez peut-être simplement utiliser objdump:

objdump -d program

Cela devrait vous donner son démontage. Vous pouvez ajouter -S si vous voulez l'annoter à la source.

30
Falaina

fopen () est une fonction de bibliothèque C et vous ne verrez donc aucune instruction syscall dans votre code, juste un appel de fonction normal. À un moment donné, il appelle open (2), mais il le fait via un trampoline. Il y a simplement un saut à la page VDSO, qui est fournie par le noyau à chaque processus. Le VDSO fournit ensuite le code pour effectuer l'appel système. Sur les processeurs modernes, les instructions SYSCALL ou SYSENTER seront utilisées, mais vous pouvez également utiliser INT 80h sur les processeurs x86.

7
Joel

Vous pouvez forcer gcc à sortir directement dans le code d'assemblage en ajoutant le commutateur -S

gcc -S hello.c
6
askjhdf

Si tout ce que vous voulez est de voir le désassemblage avec l'appel INTC, utilisez objdump -d comme quelqu'un l'a mentionné mais utilisez l'option -static lors de la compilation. Sinon, la fonction fopen n'est pas compilée dans l'elfe et est liée au moment de l'exécution.

3
Al.

Vous n'avez pas besoin d'utiliser gdb. GCC le fera.

 gcc -S foo.c

Cela créera foo.s qui est l'Assemblée.

gcc -m32 -c -g -Wa,-a,-ad foo.c > foo.lst

La version ci-dessus créera un fichier de liste qui a généré à la fois le C et l'assembly. FAQ GCC

1
Milhous

gdb disassemble a un/m pour inclure le code source à côté des instructions. C'est l'équivalent de objdump -S, avec l'avantage supplémentaire de se limiter à la seule fonction (ou plage d'adresses) qui nous intéresse.

1
Lakshman Kumar