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
    Homme Profil pro
    Inscrit en
    août 2013
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2013
    Messages : 270
    Points : 56
    Points
    56
    Par défaut 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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    24 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : mai 2008
    Messages : 24 569
    Points : 181 374
    Points
    181 374
    Billets dans le blog
    51
    Par défaut
    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


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    11 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 11 746
    Points : 26 259
    Points
    26 259
    Par défaut
    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/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

Discussions similaires

  1. Aide à la compréhension des OCCURS.
    Par Hanakimi dans le forum Cobol
    Réponses: 4
    Dernier message: 31/07/2009, 19h35
  2. aide à la compréhension d'un script
    Par miltone dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 19/01/2009, 18h29
  3. Réponses: 1
    Dernier message: 29/12/2007, 14h13
  4. Petite aide et compréhension à mon problème
    Par swirtel dans le forum Boost
    Réponses: 5
    Dernier message: 10/09/2007, 15h24
  5. [ClearCase]AIDE pour compréhension svp!
    Par wrida dans le forum Framework .NET
    Réponses: 3
    Dernier message: 07/02/2007, 12h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo