web-dev-qa-db-fra.com

Assemblage d'apprentissage

J'ai décidé d'apprendre la langue de l'Assemblée. La principale raison pour le faire est de pouvoir comprendre le code désassemblé et peut-être d'être capable d'écrire des parties de code plus efficaces (par exemple, via c ++), en faisant quelque chose comme des grottes de code, etc. , donc, aux fins que je mentionne, comment dois-je commencer? Quel type d'assemblée dois-je apprendre? Je veux apprendre en faisant d'abord des programmes faciles (c'est-à-dire une calculatrice), mais le but lui-même sera de s'y familiariser afin que je puisse comprendre le code affiché, par exemple, par IDA Pro.

J'utilise Windows (si cela fait une différence).

edit: Donc, tout le monde semble pointer vers MASM. Bien que j'obtienne le point qu'il a des capacités de haut niveau, toutes bonnes pour le programmeur de code d'assemblage, ce n'est pas ce que je recherche. Il semble avoir des instructions if, invoke, etc. non affichées dans les désassembleurs populaires (comme IDA). Donc, ce que j'aimerais entendre si possible, c'est l'opinion de toute personne qui utilise ASM aux fins que je demande (lecture du code exe désassemblé dans IDA), pas seulement les programmeurs d'assemblage "généraux".

modifier: OK. J'apprends déjà l'Assemblée. J'apprends MASM, sans utiliser les trucs de haut niveau qui ne m'importe pas. Ce que je fais en ce moment est d'essayer mon code sur les directives __asm ​​en c ++, donc je peux essayer les choses beaucoup plus rapidement que si je devais tout faire à partir de zéro avec MASM.

99
devoured elysium

Commencez avec MASM32 et à partir de là, regardez FASM . Mais vous vous amuserez avec MASM.

40
Noon Silk

Je l'ai fait plusieurs fois et je continue de le faire. Dans ce cas où votre objectif principal est de lire et non d'écrire l'assembleur, je pense que cela s'applique.

Écrivez votre propre démonteur. Pas dans le but de faire le prochain plus grand démonteur, celui-ci est strictement pour vous. Le but est d'apprendre le jeu d'instructions. Que j'apprenne l'assembleur sur une nouvelle plate-forme, me souvenant de l'assembleur pour une plate-forme que j'ai connue. Commencez avec seulement quelques lignes de code, en ajoutant des registres par exemple, et en ping-pong entre le démontage de la sortie binaire et l'ajout d'instructions de plus en plus compliquées côté entrée:

1) apprendre le jeu d'instructions pour le processeur spécifique

2) Apprenez les nuances de la façon d'écrire du code en assemblage pour ledit processeur de sorte que vous puissiez faire bouger chaque bit d'opcode dans chaque instruction

3) vous apprenez le jeu d'instructions mieux que la plupart des ingénieurs qui utilisent ce jeu d'instructions pour gagner leur vie

Dans votre cas, il y a quelques problèmes, je recommande normalement le jeu d'instructions ARM pour commencer, il y a plus de produits à base de ARM livrés aujourd'hui que tout autre) (ordinateurs x86 inclus.) Mais la probabilité que vous utilisiez ARM maintenant et que vous ne connaissiez pas suffisamment l'assembleur pour qu'il écrive du code de démarrage ou d'autres routines sachant ARM peut ou peut ne pas aider ce que vous essayez de faire. La deuxième et plus importante raison pour ARM d'abord est parce que les longueurs d'instructions sont de taille fixe et alignées. Le démontage d'instructions de longueur variable comme x86 peut être un cauchemar comme votre premier projet, et le but ici est d'apprendre le jeu d'instructions pour ne pas créer un projet de recherche. Troisième ARM est un jeu d'instructions bien fait, les registres sont créés égaux et n'ont pas de nuances spéciales individuelles .

Vous devrez donc déterminer avec quel processeur vous souhaitez commencer. Je suggère le msp430 ou ARM d'abord, puis ARM d'abord ou deuxième puis le chaos de x86. Quelle que soit la plate-forme, toute plate-forme digne d'utilisation a des fiches techniques ou les programmeurs référencent des manuels gratuits du fournisseur qui incluent le jeu d'instructions ainsi que l'encodage des opcodes (les bits et octets du langage machine). Dans le but d'apprendre ce que fait le compilateur et comment écrire du code que le compilateur n'a pas à il est bon de connaître quelques jeux d'instructions et de voir comment le même code de haut niveau est mis en œuvre sur chaque jeu d'instructions avec chaque compilateur avec chaque paramètre d'optimisation. Vous ne voulez pas entrer dans l'optimisation de votre code uniquement pour découvrir que vous l'avez fait mieux pour un compilateur/plateforme mais bien pire pour les autres.

Oh pour désassembler des jeux d'instructions de longueur variable, au lieu de simplement commencer au début et de désassembler chaque mot de quatre octets linéairement à travers la mémoire comme vous le feriez avec le ARM ou tous les deux octets comme le msp430 (le msp430 a instructions de longueur variable mais vous pouvez toujours obtenir en parcourant linéairement la mémoire si vous commencez aux points d'entrée de la table vectorielle d'interruption). Pour une longueur variable, vous voulez trouver un point d'entrée basé sur une table vectorielle ou des connaissances sur la façon dont le processeur démarre et suivez le code dans l'ordre d'exécution. Vous devez décoder chaque instruction complètement pour savoir combien d'octets sont utilisés, puis si l'instruction n'est pas une branche inconditionnelle, supposez que l'octet suivant après cette instruction est une autre instruction. Vous devez stocker toutes les adresses de branche possibles comme bien et supposez que ce sont les adresses d'octet de départ pour plus d'instructions. La seule fois où j'ai réussi, j'ai fait plusieurs passages dans le binaire. En commençant au point d'entrée, j'ai marqué tha t octet comme début d'une instruction puis décodé linéairement dans la mémoire jusqu'à atteindre une branche inconditionnelle. Toutes les cibles de branche ont été marquées comme adresses de départ d'une instruction. J'ai effectué plusieurs passages dans le binaire jusqu'à ce que je n'aie trouvé aucune nouvelle cible de branche. Si, à tout moment, vous trouvez une instruction de 3 octets, mais pour une raison quelconque, vous avez marqué le deuxième octet comme début d'une instruction, vous avez un problème. Si le code a été généré par un compilateur de haut niveau, cela ne devrait pas se produire à moins que le compilateur ne fasse quelque chose de mal, si le code a un assembleur écrit à la main (comme, disons, un vieux jeu d'arcade), il est fort possible qu'il y ait des branches conditionnelles qui ne pourront jamais se produire. comme r0 = 0 suivi d'un saut sinon nul. Vous devrez peut-être les modifier manuellement pour continuer. Pour vos objectifs immédiats, je suppose que ce sera sur x86, je ne pense pas que vous aurez un problème.

Je recommande les outils gcc, mingw32 est un moyen simple d'utiliser les outils gcc sous Windows si x86 est votre cible. Sinon, mingw32 plus msys est une excellente plate-forme pour générer un compilateur croisé à partir de sources binutils et gcc (généralement assez facile). mingw32 a certains avantages par rapport à cygwin, comme des programmes beaucoup plus rapides et vous évitez l'enfer des cygwin dll. gcc et binutils vous permettront d'écrire en C ou assembleur et de désassembler votre code et il y a plus de pages Web que vous pouvez lire vous montrant comment faire l'une ou l'ensemble des trois. Si vous comptez le faire avec un jeu d'instructions de longueur variable, je vous recommande vivement d'utiliser un jeu d'outils comprenant un démonteur. Un démonteur tiers pour x86, par exemple, va être un défi à utiliser car vous ne savez jamais vraiment s'il a été démonté correctement. Une partie de cela dépend également du système d'exploitation, le but est de compiler les modules dans un format binaire qui contient des instructions de marquage des informations à partir des données afin que le désassembleur puisse faire un travail plus précis. Votre autre choix pour cet objectif principal est d'avoir un outil qui peut compiler directement vers l'assembleur pour votre inspection, puis espérer que lorsqu'il compile au format binaire, il crée les mêmes instructions.

La réponse courte (ok légèrement plus courte) à votre question. Écrivez un désassembleur pour apprendre un jeu d'instructions. Je commencerais par quelque chose de risqué et facile à apprendre comme ARM. Une fois que vous connaissez un jeu d'instructions, les autres deviennent beaucoup plus faciles à saisir, souvent en quelques heures, grâce au troisième jeu d'instructions, vous pouvez commencer à écrire du code presque immédiatement en utilisant la fiche technique/le manuel de référence pour la syntaxe. Tous les processeurs à utiliser ont une fiche technique ou un manuel de référence qui décrit les instructions jusqu'aux bits et octets des opcodes. Apprenez un processeur RISC comme ARM et un CISC comme x86 suffisamment pour avoir une idée des différences, des choses comme avoir à parcourir les registres pour tout ou être en mesure d'effectuer des opérations directement sur la mémoire avec moins ou aucun registre. Trois instructions d'opérande contre deux, etc. Lorsque vous ajustez votre code de haut niveau, compilez pour plus d'un processeur et comparez la sortie. La chose la plus importante que vous apprendrez est que, quelle que soit la qualité du code de haut niveau, la qualité du compilateur et les choix d'optimisation effectués font une énorme différence dans les instructions réelles. Je recommande llvm et gcc (avec binutils), ni produire un excellent code , mais ils sont multi-plates-formes et multi-cibles et ont tous deux des optimiseurs. Les deux sont gratuits et vous pouvez facilement créer des compilateurs croisés à partir de sources pour différents processeurs cibles.

44
old_timer

L'assembly que vous écririez à la main et l'assembly généré par un compilateur sont souvent très différents lorsqu'ils sont vus d'un niveau élevé. Bien sûr, les entrailles du programme seront très similaires (il n'y a que tant de façons différentes de coder a = b + c, après tout), mais ce n'est pas le problème quand vous essayez de faire du reverse engineering de quelque chose. Le compilateur ajoutera un tonne de code passe-partout aux exécutables même simples: la dernière fois que j'ai comparé, "Hello World" compilé par GCC était d'environ 4 Ko, alors que s'il est écrit à la main dans Assembly, il fait environ 100 octets. . C'est pire sur Windows: la dernière fois que j'ai comparé (certes, c'était la dernière siècle) le plus petit "Hello World" que j'ai pu obtenir mon compilateur Windows d'alors était de 52 Ko! Habituellement, ce passe-partout n'est exécuté qu'une fois, voire pas du tout, donc cela n'affecte pas beaucoup la vitesse du programme - comme je l'ai dit ci-dessus, le cœur du programme, la partie où la plupart du temps d'exécution est passé, est généralement assez similaire, qu'il soit compilé ou écrit à la main.

En fin de compte, cela signifie qu'un assemblage expert programmeur et un expert désassembleur sont deux spécialités différentes. Généralement, ils se trouvent dans la même personne, mais ils sont vraiment séparés, et apprendre à être un excellent codeur d'assemblage ne vous aidera pas beaucoup à apprendre la rétro-ingénierie.

Ce que vous voulez faire, c'est récupérer les manuels d'architecture IA-32 et AMD64 (les deux sont couverts ensemble) de Intel et AMD , et parcourez les premières sections sur les instructions et les opcodes. Peut-être lire un tutoriel ou deux sur le langage d'assemblage, juste pour avoir les bases du langage d'assemblage. Ensuite, prenez un petit exemple de programme qui vous intéresse et démontez-le: parcourez son flux de contrôle et essayez de comprendre ce qu'il fait. Voyez si vous pouvez le patcher pour faire autre chose. Ensuite, essayez à nouveau avec un autre programme et répétez jusqu'à ce que vous soyez suffisamment à l'aise pour essayer d'atteindre un objectif plus utile. Vous pourriez être intéressé par des choses comme les "crackmes", produites par la communauté de l'ingénierie inverse, qui sont des défis pour les personnes intéressées par l'ingénierie inverse à essayer et, espérons-le, à apprendre quelque chose en cours de route. Ils varient en difficulté de base (commencez ici!) À impossible.

Surtout, il vous suffit de - pratiquer. Comme dans beaucoup d'autres disciplines, avec l'ingénierie inverse, la pratique rend parfait ... ou au moins mieux.

33
kquinn

Je vais à l'encontre de la plupart des réponses et je recommande la variante MMIX de Knuth de l'architecture MIPS RISC. Ce ne sera pas aussi pratique que x86 ou ARM Langages d'assemblage (pas qu'ils soient tous aussi cruciaux eux-mêmes dans la plupart des travaux réels de nos jours ... ;-), mais il VOUS débloquera la magie de la dernière version de Knuth du plus grand chef-d'œuvre de l'histoire sur la compréhension approfondie des algorithmes et des structures de données - TAOCP , "The Art of Computer Programming ". Les liens des deux URL que j'ai citées sont une excellente façon de commencer à explorer cette possibilité!

15
Alex Martelli

(Je ne sais pas pour vous mais j'étais excité avec Assembly)

Un outil simple pour expérimenter avec Assembly est déjà installé sur votre PC.

Allez dans le menu Démarrer-> Exécuter et tapez debug

débogage (commande)

debug est une commande sous DOS, MS-DOS, OS/2 et Microsoft Windows (uniquement les versions x86, pas x64) qui exécute le programme debug.exe (ou DEBUG.COM dans les anciennes versions de DOS). Le débogage peut agir comme un programme d'assemblage, de désassemblage ou de vidage hexadécimal permettant aux utilisateurs d'examiner interactivement le contenu de la mémoire (en langage assembleur, hexadécimal ou ASCII), d'apporter des modifications et d'exécuter sélectivement COM, EXE et d'autres types de fichiers. Il a également plusieurs sous-commandes qui sont utilisées pour accéder à des secteurs de disque spécifiques, à des ports d'E/S et à des adresses de mémoire. Le débogage MS-DOS s'exécute à un niveau de processus 16 bits et est donc limité aux programmes informatiques 16 bits . FreeDOS Debug a une version "DEBUGX" prenant également en charge les programmes DPMI 32 bits.

Tutoriels:


Si vous voulez comprendre le code que vous voyez dans IDA Pro (ou OllyDbg ), vous devrez apprendre comment le code compilé est structuré. Je recommande le livre Reversing: Secrets of Reverse Engineering

J'ai expérimenté quelques semaines avec debug lorsque j'ai commencé à apprendre l'assemblage (il y a 15 ans).
Notez que debug fonctionne au niveau de la machine de base, il n'y a pas de commandes d'assemblage de haut niveau.

Et maintenant un exemple simple:

Donnez a pour commencer à écrire le code d'assemblage - tapez le programme ci-dessous - et enfin donnez g pour l'exécuter.

alt text


(INT 21 afficher à l'écran le caractère ASCII stocké dans le registre DL si le registre AH est défini sur 2 - INT 20 termine le programme)

12
Nick Dandoulakis

J'ai trouvé Hacking: The Art of Exploitation pour être un moyen intéressant et utile dans ce sujet ... ne peut pas dire que j'ai déjà utilisé les connaissances directement, mais ce n'est vraiment pas pourquoi je les ai lues. Il vous donne une appréciation beaucoup plus riche des instructions que votre code compile, ce qui a parfois été utile pour comprendre des bogues plus subtils.

Ne vous laissez pas rebuter par le titre. La plupart de la première partie du livre est "Hacking" au sens du mot Eric Raymond: des façons créatives, surprenantes, presque sournoises de résoudre des problèmes difficiles. J'étais (et peut-être vous) beaucoup moins intéressé par les aspects de sécurité.

8
mblackwell8

Je ne me concentrerais pas sur l'écriture de programmes dans Assembly, du moins pas au début. Si vous êtes sur x86 (ce que je suppose que vous êtes, puisque vous utilisez Windows), il y a des tonnes de cas spéciaux étranges qu'il est inutile d'apprendre. Par exemple, de nombreuses instructions supposent que vous travaillez sur un registre que vous ne nommez pas explicitement, et d'autres instructions fonctionnent sur certains registres mais pas sur d'autres.

J'apprendrais juste assez sur votre architecture prévue pour que vous compreniez les bases, puis j'interviens et j'essaie de comprendre la sortie de votre compilateur. Armez-vous avec les manuels Intel et plongez directement dans la sortie de votre compilateur. Isolez le code d'intérêt dans une petite fonction, de sorte que vous pouvez être sûr de comprendre le tout.

Je considérerais les bases comme:

  • registres: combien y en a-t-il, quels sont leurs noms et quelles sont leurs tailles?
  • ordre d'opérande: add eax, ebx signifie "Ajouter ebx à eax et stocker le résultat dans eax".
  • FPU: apprenez les bases de la pile à virgule flottante et comment convertir vers/depuis fp.
  • modes d'adressage: [base + offset * multiplicateur], mais le multiplicateur ne peut être que 1, 2 ou 4 (ou peut-être 8?)
  • conventions d'appel: comment les paramètres sont-ils passés à une fonction?

La plupart du temps, il sera surprenant de voir ce que le compilateur émet. Faites-en un casse-tête pour comprendre pourquoi diable le compilateur pensait que ce serait une bonne idée. Cela vous apprendra beaucoup.

Cela vous aidera probablement aussi à vous armer de manuels d'Agner Fog , en particulier de la liste d'instructions. Il vous dira à peu près le coût de chaque instruction, bien que ce soit plus difficile à quantifier directement sur les processeurs modernes. Mais cela aidera à expliquer pourquoi, par exemple, le compilateur va si loin pour éviter d'émettre une instruction idiv.

Mon seul autre conseil est de toujours utiliser la syntaxe Intel au lieu d'AT & T lorsque vous avez le choix. J'étais plutôt neutre sur ce point, jusqu'au jour où j'ai réalisé que certaines instructions étaient totalement différentes entre les deux (par exemple, movslq dans la syntaxe AT&T est movsxd dans la syntaxe Intel). Étant donné que les manuels sont tous écrits en utilisant la syntaxe Intel, respectez-le.

Bonne chance!

7
Josh Haberman

La suggestion d'utiliser le débogage est amusante, de nombreuses astuces peuvent être faites avec cela. Cependant, pour un système d'exploitation moderne, l'apprentissage de l'assemblage 16 bits peut être légèrement moins utile. Envisagez plutôt d'utiliser ntsd.exe. Il est intégré à Windows XP (il a été supprimé dans Server 2003 et supérieur, malheureusement), ce qui en fait un outil pratique à apprendre car il est si largement disponible.

Cela dit, la version originale de XP souffre d'un certain nombre de bogues. Si vous voulez vraiment l'utiliser (ou cdb, ou windbg, qui sont essentiellement des interfaces différentes avec la même syntaxe de commande et le même débogage) back-end), vous devez installer le package gratuit outils de débogage Windows .

Le fichier debugger.chm inclus dans ce package est particulièrement utile lorsque vous essayez de comprendre la syntaxe inhabituelle.

La grande chose à propos de ntsd est que vous pouvez l'afficher sur n'importe quelle machine XP vous êtes près et l'utiliser pour l'assemblage ou le démontage. Cela fait un outil d'apprentissage d'assemblage/great/X86. Par exemple ( en utilisant cdb car il est en ligne dans l'invite dos, il est par ailleurs identique):

(les erreurs de symbole sont ignorées car elles ne sont pas pertinentes - aussi, j'espère que cette mise en forme fonctionne, c'est mon premier message)

C:\Documents and Settings\User>cdb calc

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: calc
Symbol search path is: *** Invalid ***
Executable search path is:
ModLoad: 01000000 0101f000   calc.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\Shell32.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
(f2c.208): Break instruction exception - code 80000003 (first chance)
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> r eax
eax=001a1eb4
0:000> r eax=0
0:000> a eip
7c90120e add eax,0x100
7c901213
0:000> u eip
ntdll!DbgBreakPoint:
7c90120e 0500010000      add     eax,100h
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4
ntdll!NtCurrentTeb:
7c90121e 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c901224 c3              ret
0:000> t
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!DbgUserBreakPoint+0x1:
7c901213 c3              ret
0:000>`

Aussi - pendant que vous jouez avec IDA, assurez-vous de consulter le livre IDA Pro de Chris Eagle (non lié car StackOverflow ne veut pas me laisser poster plus de deux liens pour mon premier post). C'est de loin la meilleure référence sur le marché.

3
Jordan

J'ai récemment suivi un cours sur les systèmes informatiques. L'un des sujets était l'assemblage comme outil de communication avec le matériel.

Pour moi, la connaissance de Assembly n'aurait pas été complète sans comprendre les détails du fonctionnement des systèmes informatiques. Comprendre cela, apporte une nouvelle compréhension de la raison pour laquelle les instructions d'assemblage sur une architecture de processeur sont excellentes mais terribles sur une autre architecture.

Compte tenu de cela, je suis enclin à recommander mon manuel de classe:

Systèmes informatiques: le point de vue d'un programmeur .

Computer Systems:A programmer's perspective
(source: cmu.ed )

Il couvre x86 Assembly mais le livre est beaucoup plus large que cela. Il couvre la tuyauterie du processeur et la mémoire en tant que cache, le système de mémoire virtuelle et bien plus encore. Tout cela peut affecter la façon dont l'assemblage pourrait être optimisé pour les fonctionnalités données.

3
Frank V

J'ai commencé à apprendre MIPS qui est une architecture 32 bits très compacte. Il s'agit d'un ensemble d'instructions réduit, mais c'est ce qui le rend facile à comprendre pour les débutants. Vous pourrez toujours comprendre comment fonctionne Assembly sans être submergé par la complexité. Vous pouvez même télécharger un joli petit IDE, qui vous permettra de compiler votre code MIPS: clicky Une fois que vous aurez compris, je pense qu'il serait beaucoup plus facile de passer à des architectures plus complexes. C'est du moins ce que je pensais :) À ce stade, vous aurez les connaissances essentielles de l'allocation et de la gestion de la mémoire, du flux logique, du débogage, des tests, etc.

3
Sergey

Faites-vous d'autres travaux de développement sur Windows? Sur quel IDE? Si c'est VS, il n'y a pas besoin d'un IDE juste pour lire le code désassemblé: déboguez votre application (ou attachez-la à une application externe), puis ouvrez la fenêtre de désassemblage = (dans les paramètres par défaut, c'est Alt + 8). Parcourez et regardez la mémoire/les registres comme vous le feriez avec du code normal. Vous pouvez également garder une fenêtre de registres ouverte (Alt + 5 par défaut).

Intel donne gratuitement manuels , qui donnent à la fois un aperçu de l'architecture de base (registres, processeurs, etc.) et une référence d'instructions complète. À mesure que l'architecture mûrit et devient plus complexe, les manuels "d'architecture de base" deviennent de moins en moins lisibles. Si vous pouvez mettre la main sur une version plus ancienne, vous auriez probablement un meilleur endroit pour commencer (même les manuels P3 - ils expliquent mieux les mêmes basiques environnement d'exécution).

Si vous souhaitez investir dans un livre, ici est un joli texte d'introduction. Recherchez `` x86 '' sur Amazon et vous en obtiendrez beaucoup d'autres. Vous pouvez obtenir plusieurs autres directions à partir d'une autre question ici .

Enfin, vous pouvez bénéficier un peu des blogs lecturecertainsbas - nivea . Ces bits d'information de taille octet fonctionnent le mieux pour moi, personnellement.

2
Ofek Shilon

Cela ne vous aidera pas nécessairement à écrire du code efficace!

les codes opérationnels i86 sont plus ou moins un format "hérité" qui persiste en raison du volume considérable de code et de fichiers binaires exécutables pour Windows et Linux.

C'est un peu comme les anciens savants qui écrivent en latin, un locuteur italien comme Galileo écrirait en latin et son article pourrait être compris par un locuteur polonais comme Copernic. C'était encore le moyen le plus efficace de communiquer, même si le niether était particulièrement bon en latin, et le latin est une langue de poubelle pour exprimer des idées mathématiques.

Les compilateurs génèrent donc du code x86 par défaut, et les puces modernes lisent les codes anceint Op et transforment ce qu'ils voient en instructions de risc parallèles, avec une exécution réordonnée, une exécution spéculative, un pipelining, etc. utilisation des 32 ou 64 registres du processeur (contrairement au 8 pathétique que vous voyez dans les instructions x86).

Maintenant, tous les compilateurs d'optimisation savent que c'est ce qui se passe réellement, ils codent donc des séquences de codes OP qu'ils savent que la puce peut optimiser efficacement - même si certaines de ces séquences semblent inefficaces pour un programmeur .asm vers 1990.

À un moment donné, vous devez accepter que les 10s de milliers d'années-homme que les auteurs de compilateurs d'efforts ont investis ont porté leurs fruits, et faites-leur confiance.

Le moyen le plus simple et le plus simple d'obtenir un runtime plus efficace est d'acheter le compilateur Intel C/C++. Ils ont un marché de niche pour les compilateurs efficeint et ils ont l'avantage de pouvoir demander aux concepteurs de puces ce qui se passe à l'intérieur.

2
James Anderson

Pour faire ce que vous voulez faire, je viens de prendre Intel Instruction Set Reference (peut-être pas exactement celui que j'ai utilisé, mais il semble suffisant) et quelques programmes simples que j'ai écrits dans Visual Studio et commencé à les jeter dans IDAPro/Windbg. Quand j'ai dépassé mes propres programmes, le logiciel à crackmes était utile.

Je suppose que vous avez une compréhension de base de la façon dont les programmes s'exécutent sous Windows. Mais vraiment, pour lire Assembly, il n'y a que quelques instructions à apprendre et quelques versions de ces instructions (par exemple, il y a une instruction de saut, le saut a quelques saveurs comme jump-if-equal, jump-if-ecx-is-zero , etc). Une fois que vous avez appris les instructions de base, il est assez simple d'obtenir l'essentiel de l'exécution du programme. La vue graphique de l'IDA aide, et si vous suivez le programme avec Windbg, il est assez simple de comprendre ce que les instructions font si vous n'êtes pas sûr.

Après avoir joué un peu comme ça, j'ai acheté Hacker Disassembly Uncovered . En général, je reste loin des livres avec le mot "Hacker" dans le titre, mais j'ai vraiment aimé la façon dont celui-ci est allé en profondeur sur la façon dont le code compilé avait l'air désassemblé. Il va également dans les optimisations du compilateur et certaines choses d'efficacité qui étaient intéressantes.

Tout dépend vraiment de la profondeur à laquelle vous voulez aussi pouvoir comprendre le programme. Si vous inversez l'ingénierie d'une cible à la recherche de vulnérabilités, si vous écrivez du code d'exploitation ou analysez des logiciels malveillants emballés pour les capacités, vous aurez besoin de plus de temps de montée en puissance pour vraiment faire avancer les choses (en particulier pour les logiciels malveillants plus avancés). ). D'un autre côté, si vous voulez simplement pouvoir changer le niveau de votre personnage sur votre jeu vidéo préféré, vous devriez vous débrouiller dans un délai relativement court.

2
mrduclaw

Je pense que vous voulez apprendre les mnémoniques d'opcode ASCII (et leurs paramètres), qui sont générés par un désassembleur et qui sont compris par (peuvent être utilisés comme entrée pour) un assembleur.

Tout assembleur (par exemple MASM) ferait l'affaire.

Et/ou il pourrait être préférable pour vous de lire un livre à ce sujet (il y a eu des livres recommandés sur SO, je ne me souviens pas lesquels).

2
ChrisW

Mon préféré est le NASM, principalement parce qu'il est multi-plateforme, et qu'il compile MMX, SSE, 64 bits ...

J'ai commencé à compiler un simple fichier source C avec gcc et à "transcoder" l'instruction d'assembleur du format gcc au format NASM. Ensuite, vous pouvez modifier de petites portions de code et vérifier l'amélioration des performances qu'il apporte.

La documentation NASM est vraiment complète, je n'ai jamais eu besoin de rechercher des informations dans des livres ou d'autres sources.

1
G B

L'une des langues standard de l'Assemblée pédagogique est MIPS. Vous pouvez obtenir des simulateurs MIPS (spim) et divers matériels pédagogiques pour cela.

Personnellement, je ne suis pas fan. J'aime plutôt IA32.

1
Paul Nathan

Quelques liens que vous pourriez trouver utiles pour apprendre l'assemblage - mappage du code source -

L'assemblage et l'art du débogage

Débogage - Modification du code au moment de l'exécution

J'espère que vous les trouverez utiles.

1
mohit

Nous avons appris l'assemblage avec un kit de développement de microcontrôleur (Motorola HC12) et une fiche technique épaisse.

0
the_e

Vous pouvez consulter cours vidéo d'assemblage xorpd x86 . (Je l'ai écrit). Le cours lui-même est payant, mais les exercices sont open source, sur github. Si vous avez une certaine expérience en programmation, je pense que vous devriez pouvoir travailler uniquement avec les exercices et tout comprendre.

Notez que le code est pour la plate-forme Windows et est écrit en utilisant Fasm assembler . Le cours et les exercices ne contiennent aucune construction de haut niveau, mais vous pouvez utiliser Fasm pour créer des macros très compliquées, si vous le souhaitez.

0
xorpd

Hors sujet, je sais, mais comme vous êtes un programmeur Windows, je ne peux m'empêcher de penser que cela pourrait être une utilisation plus appropriée et/ou meilleure de votre temps pour apprendre MSIL. Non, ce n'est pas Assembly, mais c'est probablement plus pertinent à l'ère .NET.

0
slf

Connaître Assembly peut être utile pour le débogage, mais je ne serais pas trop enthousiaste à l'idée de l'utiliser pour optimiser votre code. Les compilateurs modernes sont généralement bien meilleurs pour optimiser cet être humain de nos jours.

0
Adam Pierce

Beaucoup de bonnes réponses ici. La programmation de bas niveau, l'assemblage, etc. sont populaires dans la communauté de la sécurité, il vaut donc la peine d'y chercher des trucs et astuces une fois que vous y êtes. Ils ont même de bons tutoriels comme celui-ci sur l'assemblage x86 .

0
Brian Lyttle

Pour atteindre réellement votre objectif, vous pouvez envisager de commencer par le IDE dans lequel vous vous trouvez. Il s'agit généralement d'une fenêtre de désassemblage, vous pouvez donc effectuer une seule étape dans le code. Il existe généralement une vue quelconque pour vous permettre de voir les registres et d'examiner les zones de mémoire.

L'examen du code c/c ++ non optimisé aidera à créer un lien dans le type de code que le compilateur génère pour vos sources. Certains compilateurs ont une sorte de mot réservé ASM qui vous permet d'insérer des instructions machine dans votre code.

Mon conseil serait de jouer avec ces sortes d'outils pendant un certain temps et de se mouiller les pieds, puis d'intensifier? vers le bas? au code assembleur simple sur la plate-forme que vous utilisez.

Il y a beaucoup d'excellents outils, mais vous pourriez trouver cela plus amusant, pour éviter la courbe d'apprentissage abrupte au début.

0
EvilTeach