1 points par GN⁺ 2024-07-11 | 1 commentaires | Partager sur WhatsApp

Choses étranges apprises en écrivant un émulateur x86

  • Présentation de diverses anecdotes et bizarreries apprises en écrivant des émulateurs x86 et amd64
  • Dans Time Travel Debugging (TTD), un émulateur CPU est utilisé pour enregistrer l’exécution d’un processus au niveau des instructions
  • La première version de TTD s’appelait iDNA, était écrite en assembleur, rapide mais difficile à maintenir
  • La deuxième version a été écrite en C++, ce qui a amélioré sa maintenabilité

Anecdotes inutiles sur l’encodage x86

  • Le schéma d’encodage x86 permet d’encoder une même instruction de plusieurs façons
  • L’instruction int 3 peut être encodée en CD 03 ou CC
  • Le registre EAX est appelé « registre accumulateur », et cela se reflète réellement dans l’encodage
  • Le préfixe REX permet d’accéder à une plage plus large de registres en code 64 bits
  • Une instruction peut mesurer jusqu’à 15 octets ; au-delà, une exception est levée
  • Le préfixe d’override d’adresse permet de référencer des adresses 32 bits en mode 64 bits

Propriétés étranges des drapeaux

  • L’instruction INC ne met pas à jour le carry flag, contrairement à l’instruction ADD
  • Les instructions CMPXCHG8B/CMPXCHG16B ne modifient que le zero flag
  • Les instructions de décalage et de rotation laissent l’overflow flag dans un état indéfini lorsque la quantité de décalage est supérieure à 1

Encore plus de surprises avec les instructions de décalage

  • shr ax, 10h décale le registre ax de 16 bits et le met à 0
  • shr eax, 20h décale le registre eax de 32 bits, mais la valeur ne change pas
  • La quantité de décalage est masquée par 1FH

Override de segment

  • Les segments sont encore utilisés en code 32 bits et 64 bits, principalement pour le stockage local au thread
  • Sous Windows, les registres FS ou GS sont utilisés pour référencer le TEB (Thread Execution Block)
  • Les processus 32 bits utilisent FS, et les processus 64 bits utilisent GS
  • En mode 64 bits, la valeur du registre de segment n’a pas d’importance

Override de segment : encore quelques anecdotes

  • En mode 32 bits, la valeur réelle du registre de segment référence le descripteur de segment
  • En mode 64 bits, la base est contrôlée par le MSR
  • Dans WinDbg, il n’est pas possible de lire directement les valeurs de segment d’un processus 64 bits

Conclusion

  • Cet article propose une liste aléatoire d’anecdotes sur x86
  • Écrire un émulateur aide à comprendre en profondeur le fonctionnement du CPU
  • D’excellentes ressources sont disponibles sur le site web d’Agner Fog

Résumé GN⁺

  • Présentation de diverses anecdotes et bizarreries apprises en écrivant des émulateurs x86 et amd64
  • Écrire un émulateur aide à comprendre en profondeur le fonctionnement du CPU
  • L’article couvre diverses anecdotes, comme les différentes façons d’encoder l’instruction int 3, le préfixe REX ou encore les overrides de segment
  • Davantage de ressources sont disponibles sur le site web d’Agner Fog

1 commentaires

 
GN⁺ 2024-07-11
Commentaires Hacker News
  • L’Intel SDM précise que pour les instructions BSF/BSR, la valeur de destination est indéfinie si l’entrée vaut 0. AMD documente qu’en pareil cas, la destination n’est pas modifiée
    • glibc s’appuie sur le fait officieux que, chez Intel, la destination n’est pas modifiée
    • TZCNT/LZCNT sont des formes de BSF/BSR avec le préfixe F3, ignoré sur les anciens processeurs. Le même code peut se comporter différemment selon le CPU
  • Beaucoup se plaignent des préfixes, mais ce n’est pas le plus gros problème. Les bits d’extension REX/VEX/EVEX.RXB sont ignorés lorsqu’ils ne s’appliquent pas
    • APX permet au préfixe REX2 d’encoder les registres r16-r31, mais pas xmm16-xmm31
    • Le préfixe EVEX a des dispositions différentes selon les opcodes
    • L’utilisation des bits d’extension varie selon le type de registre
  • Avis d’une personne qui aime coder en assembleur. Elle apprécie sa qualité esthétique simple et verticale
    • Elle raconte avoir écrit une mini VM pour faire comprendre la pile à un ami qui fait du JS
    • Elle mentionne que son ami est trop occupé par le développement web pour avoir le temps d’étudier en profondeur
  • Souvenir erroné selon lequel une variante de Salsa20 et du code machine se trouvaient sur cryp.to. Le site de Dan Bernstein est cr.yp.to
    • Elle partage son expérience de test de diverses implémentations en travaillant sur le chiffrement des données dans une startup
  • Recommande Justine Tunney et son émulateur. La documentation explique bien comment fonctionne un CPU
  • Désaccord avec l’idée qu’écrire un émulateur CPU soit la meilleure façon de comprendre un CPU
    • Le construire au niveau des portes logiques serait une meilleure méthode
  • Désaccord avec l’idée que l’assembleur x86 cause plus de problèmes que le RISC
    • Le x86 est facile à analyser, alors que le MIPS est difficile
  • Exprime son respect envers les développeurs d’émulateurs de processeurs x86
    • En développant un émulateur i386, cette personne a beaucoup appris sur les appels système et ELF
  • Partage son expérience d’écriture d’un émulateur x86
    • Elle se souvient avoir écrit un émulateur-jouet capable d’exécuter le code BIOS initial
  • Partage l’avis selon lequel le style et la mise en page du blog sont réussis