Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

Aide à la compréhension objdump et assembleur


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre du Club
    Aide à la compréhension objdump et assembleur
    Bonjour à tous,

    Je m'interesse depuis peu à l'assembleur grace à la belle commande objdump. Néanmoins je tombe sur quelques problemes de compréhension au niveau assembleur et j'aurais bien besoin de vos lumieres.

    Voici l'extrait de code :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    0000000000000540 <_start>:
         540:   31 ed                   xor    ebp,ebp
         542:   49 89 d1                mov    r9,rdx
         545:   5e                      pop    rsi
         546:   48 89 e2                mov    rdx,rsp
         549:   48 83 e4 f0             and    rsp,0xfffffffffffffff0
         54d:   50                      push   rax
         54e:   54                      push   rsp
         54f:   4c 8d 05 ea 01 00 00    lea    r8,[rip+0x1ea]        # 740 <__libc_csu_fini>
         556:   48 8d 0d 73 01 00 00    lea    rcx,[rip+0x173]        # 6d0 <__libc_csu_init>
         55d:   48 8d 3d 1f 01 00 00    lea    rdi,[rip+0x11f]        # 683 <main>
         564:   ff 15 76 0a 20 00       call   QWORD PTR [rip+0x200a76]        # 200fe0 <__libc_start_main@GLIBC_2.2.5>
         56a:   f4                      hlt    
         56b:   0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]


    Pour commencer dans objdump, je ne vois nullpart ou la fonction <_start> est appelé, je vous juste à un moment :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
        Contenu de la section .text :
         0540 31ed4989 d15e4889 e24883e4 f050544c  1.I..^H..H...PTL
         0550 8d05ea01 0000488d 0d730100 00488d3d  ......H..s...H.=

    et ca contient 0540, mais il n' y a aucune jmp ou call à l'adresse 540. une idée la dessus ?

    ensuite je constate que la taille des instructions (dans la fonction start) vaut parfois 2 octets, puis 3, puis 1, puis plus loin 7... comment le processeur peut savoir que l'instruction vaut parfois des tailles différentes, sachant que la taille de mon bus est de 64 bits soit 8 octets, donc on pourrait penser que toutes les intructions vallent 8 octets ?

    je constate a la seconde instruction que l'on place au registre 9 la valeur du registre rdx, et à la 3eme instruction, on recupére la derniere valeur de la pile et on l'affecte a rsi, or on a fait aucun push, et on a placé aucune valeur dans des registres encore. Tout ce qu'il y a avant les différentes fonctions du programme c'est des :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        Contenu de la section .interp :
        ...
        Contenu de la section .init :
        ...
        Contenu de la section .plt :
        ...
        Contenu de la section .text :
        ...

    mais je n'ai aucune affectation de registre, ni d'insertion dans la pile.

    Et derniere question, je ne vois dans mon code aucun syscall, or j'ai un printf dans mon code, j'ai juste :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
        0000000000000520 <printf@plt>:
         520:   ff 25 aa 0a 20 00       jmp    QWORD PTR [rip+0x200aaa]        # 200fd0 <printf@GLIBC_2.2.5>
         526:   68 00 00 00 00          push   0x0
         52b:   e9 e0 ff ff ff          jmp    510 <.plt>


    qui renvoie à l'instruction 200fd0 qui a :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        0000000000200fb8 <_GLOBAL_OFFSET_TABLE_>:
          200fb8:       c8 0d 20 00             enter  0x200d,0x0
                ...
          200fd0:       26 05 00 00 00 00       es add eax,0x0
                ...


    et c'est tout ce que j'ai, je ne peux rien voir d'autre. Or je devrais pouvoir voir a l'exécution de mon programme via objdump le contenu de printf qui lance l'appel systeme write.

    Il y'a beaucoup de question. Donc je vous remercie d'avance pour votre temps.

  2. #2
    Responsable 2D/3D/Jeux

    Bonjour,

    J'espère réussir à répondre au mieux à vos questions.
    et ca contient 0540, mais il n' y a aucune jmp ou call à l'adresse 540. une idée la dessus ?
    La fonction _start est appelée par le mécanisme qui permet de lancer un programme. C'est, en C, le main() et je pense que vous ne vous êtes jamais demandé qui lance main().
    Surement qu'il n'y a pas d'appel direct à _start, mais lorsque le lanceur d'application à finir de lire l'entête du programme, il saute à l'adresse 540 et comment à exécuter ce qui s'y trouve.

    ensuite je constate que la taille des instructions (dans la fonction start) vaut parfois 2 octets, puis 3, puis 1, puis plus loin 7...
    Car certaines instructions attendent des paramètres. Le CPU va lire l'identifiant d'instruction (le premier octet) et suivant ce qu'il est, il va utiliser ce qui suit comme paramètres, ou non.

    de mon bus est de 64 bits soit 8 octets
    Je ne pense pas qu'il y ai de rapport. Le 64 bits signifie quelle est la taille possible des données à traitées. Dans le sens, quelle grandeur de nombre il est possible de traiter. Par exemple, un CPU 8 bits, ne sait faire des additions dont le max possible est : 255 + 255.

    mais je n'ai aucune affectation de registre, ni d'insertion dans la pile.
    Votre main() (en C) reçoit bien des arguments. Vous ne vous êtes jamais demandé qui les fournissaient . Il se passe des choses, avant que votre programme ne démarre

    Et derniere question, je ne vois dans mon code aucun syscall, or j'ai un printf dans mon code, j'ai juste :
    Le code du printf() est dans la GLIBC (une bibliothèque dynamique). Pour qu'il en soit autrement, il faut compiler en static.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Responsable Systèmes

    Pour commencer dans objdump, je ne vois nullpart ou la fonction <_start> est appelé,
    Normal, c'est le chargeur qui l'appelle (ld-linux.so).


    ensuite je constate que la taille des instructions (dans la fonction start) vaut parfois 2 octets, puis 3, puis 1, puis plus loin 7
    En x86, la taille des instructions est variable. Il faut voire lune instruction comme une suite de bits variable (pouvant être codée sur 1 octet ou plus). Cette suite peut sur 16 bits représenter par exemple 3 bits d'instructions et le reste des bits de données.

    et à la 3eme instruction, on recupére la derniere valeur de la pile et on l'affecte a rsi, or on a fait aucun push
    La fonction _start n'étant pas la 1ère appelée, il y des choses dans la pile.

    derniere question, je ne vois dans mon code aucun syscall, or j'ai un printf dans mon code, j'ai juste :
    Je t'invite à te documenter sur la résolution de symboles avec les sections .got et .plt.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutor...s/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

###raw>template_hook.ano_emploi###