web-dev-qa-db-fra.com

Comment écrire et exécuter Windows .exe manuellement (code machine avec éditeur Hex)?

Je voudrais savoir comment est-il possible d'écrire quelque chose d'aussi simple qu'un programme Hello World simplement en utilisant un éditeur hexadécimal. Je sais que je pourrais utiliser un assembleur et un langage d'assemblage à un niveau proche de la machine, mais je veux juste expérimenter avec vraiment l'écriture de code machine dans un exemple de jouet tel que Hello World.

Cela pourrait être un simple fichier DOS .COM que je peux exécuter sur DOSBox. Mais ce serait bien si quelqu'un pouvait fournir un exemple de fichier .EXE pour l'exécuter directement sur mon PC Windows.

Ce n'est que pure curiosité. Non ... je ne pense pas à écrire des programmes directement en code machine binaire (je n'écris même pas d'habitude du code Assembly, j'utilise juste C/C++ comme mes outils les plus bas niveau la plupart du temps). Je veux juste voir si c'est possible de le faire, car probablement quelqu'un a dû le faire au tout début des ordinateurs.

P.S .: Je sais qu'il y a des questions similaires sur ce sujet, mais aucune ne fournit un exemple de travail. Je veux juste un exemple simple pour qu'il puisse m'aider à comprendre comment les compilateurs et les assembleurs génèrent un fichier exécutable. Je veux dire ... quelqu'un a dû le faire à la main dans le passé pour les tout premiers programmes. En outre, pour le format EXE Windows, il doit y avoir eu quelqu'un chez Microsoft qui a écrit les premiers outils pour générer le format et la façon dont Windows lui-même le lit puis l'exécute.

37
petersaints

Il y a un exe assez minimaliste mais pleinement fonctionnel (sur Win7 aussi) corkami/wiki/PE101 , chaque octet est expliqué dans le graphique de Nice. Vous pouvez tout taper à la main dans un éditeur hexadécimal, mais les rembourrages peuvent rendre cela un peu fastidieux.

En ce qui concerne l'histoire, oui, quelqu'un chez Microsoft a inventé le format exe (l'ancien format exe DOS MZ) et il (ou quelqu'un d'autre chez Microsoft) a écrit un chargeur pour cela et un éditeur de liens, qui est la chose qui tourne traditionnellement la sortie d'un compilateur ("fichiers objets") en fichiers exécutables. Il est possible (et même probable, je dirais) que les premiers programmes exe ont été écrits à la main, après tout, ils étaient uniquement destinés à tester le nouveau chargeur.

Plus tard, le format COFF d'AT & T a été étendu par Microsoft au format PE, qui a toujours l'en-tête MZ et généralement (mais facultativement, ce n'est pas dans l'exemple corkami, et cela peut être vraiment n'importe quoi) comprend un petit programme DOS juste pour imprimer le message Msgstr "Ce programme ne peut pas être exécuté en mode DOS".

16
harold

1) un fichier .com est l'endroit le plus simple pour démarrer et s'exécutera sur une dosbox, fondamentalement, le programme démarre à quelque chose comme offset 0x100 dans le fichier, je pense que le premier 0x100 peut être n'importe quoi, ne me souviens pas

2) bien qu'il soit vrai que les premiers programmes sont souvent écrits et assemblés à la main en code machine, nous parlons lorsque vous ajoutez deux chiffres, enregistrez-les dans la mémoire et êtes si heureux que vous preniez le reste de la journée. un programme "bonjour le monde" qui imprime des trucs sur une carte vidéo est beaucoup plus compliqué. Maintenant, vous pouvez en faire un très simple en utilisant les appels système dos, et ce n'est peut-être pas ce qui vous intéresse, peut-être que c'est.

3) basé sur 2, quelque chose de plus compliqué qu'une ou quelques instructions à la fois pour les tests dans les années 1960 ou 1970, même lors de l'écriture manuelle d'un programme, vous écrivez votre programme dans l'assembleur à la main, puis l'assemblez au code machine, puis chargez-le. Fondamentalement, apprenez d'abord le langage d'assemblage, puis apprenez à générer le code machine pour celui-ci, puis commencez à taper ces octets dans un éditeur hexadécimal. Ce n'est pas alors les années 1960, sauf si vous ressentez une douleur excessive, apprenez ce qui précède en écrivant asm, en utilisant un assembleur pour générer le code machine, puis utilisez un désassembleur pour le démonter et examinez côte à côte le langage d'assemblage et le code machine pour améliorer considérablement le temps qu'il vous faudra pour obtenir un programme de travail. Si vous travailliez pour une société de puces avant qu'il n'y ait des systèmes d'exploitation et des jeux d'instructions, vous profiteriez toujours des autres membres de l'équipe, des concepteurs de puces, etc. pour comprendre comment créer le code machine et l'organiser. Vous ne viendriez pas à cela avec seulement une expérience linguistique de haut niveau et tout faire par vous-même avec un espoir de succès.

4) x86 est un horrible jeu d'instructions, si vous ne connaissez pas Assembly, je vous déconseille fortement de ne pas l'apprendre en premier. avoir un x86 est la pire excuse que j'ai entendue pour apprendre le x86 en premier. vous avez déjà mentionné dosbox, vous envisagez déjà d'émuler/simuler, alors utilisez un bon jeu d'instructions et simulez-le ou achetez ce matériel (moins de 50 $, même moins de 20 $ vous offrira une carte avec de bien meilleurs jeux d'instructions). Je recommande de simuler/émuler d'abord et en parallèle avec le matériel si vous choisissez d'en acheter. Si vous voulez vraiment une éducation, écrivez votre propre simulateur, ce n'est pas difficile du tout. Peut-être inventez votre propre jeu d'instructions.

5) rien de tout cela ne vous aidera à comprendre ce que fait un compilateur. Connaître le langage d'assemblage puis désassembler la sortie du compilateur est votre meilleur chemin vers cette connaissance, le code machine n'est pas impliqué, pas besoin d'exécuter réellement les programmes. Un compilateur passe du langage de niveau supérieur à un langage de niveau inférieur (C vers asm ou C++ vers asm par exemple). Ensuite, comprenez ce que fait un assembleur, il existe de nombreuses solutions différentes, à la fois en raison de l'historique et pour d'autres raisons. La solution typique aujourd'hui est un compilateur, un assembleur et un éditeur de liens séparés (votre compilateur appelle l'assembleur et l'éditeur de liens pour vous, sauf si vous le lui dites, les trois étapes sont masquées, en fait, le processus de compilation peut être plus d'un programme qui est exécuter pour terminer cette tâche). Les assembleurs qui sortent un binaire devront résoudre le programme entier, les assembleurs qui sortent vers un objet laisseront des trous dans le code machine pour que l'éditeur de liens se remplisse. Des choses comme la ramification ou l'appel d'éléments dans un autre objet qu'il ne peut pas encoder jusqu'à ce que l'éditeur de liens place les choses dans le binaire et connaît l'espacement/l'adressage. Accès également aux variables qui vivent dans d'autres objets.

Vous ne voyez probablement pas d'exemples réels sur l'édition hexadécimale d'un programme car tout d'abord c'est une question si vaste qu'il n'y a pas de réponse simple (quel fonctionnement, système, quels appels système ou créez-vous, quel format de fichier, quel éditeur hexadécimal, etc. ). De plus, comme il s'agit d'une question et d'un problème de haut niveau, les vraies questions sont: où puis-je apprendre l'assembly, où puis-je en savoir plus sur la relation entre l'assembly et le code machine, où puis-je en savoir plus sur les appels système (qui ne sont pas une question d'assembly, ils ne sont pas liés à l'apprentissage de asm, vous apprenez le langage d'assemblage lui-même, puis vous l'utilisez comme un outil pour effectuer des appels système si vous ne pouvez pas effectuer les appels système directement en utilisant un langage plus élevé), où puis-je en savoir plus sur les formats de fichiers exécutables comme .com, .exe, coff, elf, etc. Qu'est-ce qu'un bon ou facile ou un adjectif, un éditeur hexadécimal qui fonctionne sur le système d'exploitation ou l'environnement xyz. Posez ces questions séparément et vous trouverez les réponses et les exemples et une fois que vous aurez ces réponses, vous saurez comment créer un programme en utilisant un éditeur hexadécimal en tapant du code machine. Un exemple plus court est que vous voyez des exemples hexadécimaux de programmes complets lorsque vous voyez le désassemblage d'un programme publié sur SO, certains de ces programmes complets sont affichés en hexadécimal. et si vous connaissez le format de fichier, vous pouvez simplement taper ce genre de choses dans un éditeur hexadécimal.

9
old_timer

Je fais des binaires à la main, mais je pense que c'est plus facile dans Assembly lui-même qu'un éditeur hexadécimal pur, où mettre à jour n'importe quoi serait difficile.

  • Le plus simple est sûrement le format DOS COM, que vous pouvez même taper dans le bloc-notes , ou du moins, c'est très facile même pour un normal Hello World .

  • L'EXE (format non DOS) ne demande pas grand chose non plus voir ici .

  • Si vous essayez de faire un PE, vous pouvez faire un TinyPE .

La plupart des fichiers binaires doivent être disponibles sous la forme PE et EXE et COM .

5
Ange

Pas sur place, mais ce tutoriel devrait vous donner un meilleur aperçu de la façon dont Assembly mappe sur le code machinde (x86 ELF): http://timelessname.com/elfbin/ (surtout regardez la moitié inférieure de la page)

Cette page concerne mes [...] tentatives de création du plus petit binaire ELF x86 qui s'exécuterait en disant Hello World sur Ubuntu Linux Mes premières tentatives ont commencé avec C puis ont progressé vers l'assemblage x86 et enfin vers un hexeditor.

C'est génial d'analyser de très petits exécutables comme ceux-ci, car le mappage entre l'assembly et le code machine sera plus facile à repérer. Ceci est également un article très intéressant sur le sujet (pas exactement lié à votre question): http://www.phreedom.org/research/tinype/ (x86 PE)

4
Charlie Rudenstål

J'ai écrit un article sur la création de fichiers binaires DOS exécutables simplement en utilisant ECHO à l'invite de commandes. Aucun autre utilitaire HEX tiers ou IDE x86 requis!

La technique utilise une combinaison de clavier - ALT ASCII qui convertissent les OPCODES en un format binaire lisible directement sous MSDOS. La sortie est un fichier binaire * .com entièrement exécutable.

http://colinord.blogspot.co.uk/2015/02/extreme-programming-hand-coded.html

Extrait: Tapez les raccourcis clavier suivants à l'invite DOS en vous rappelant de maintenir ALT gauche.

c:\>Echo LALT-178 LALT-36 LALT-180 LALT-2 LALT-205 LALT-33 LALT-205 LALT-32 > $.com

Les codes ci-dessus sont en fait des valeurs d'opcode décrivant un programme d'assemblage X86 pour imprimer un signe dollar à l'écran.

Votre invite devrait ressembler à quelque chose de similaire ci-dessous lorsque vous avez terminé. Appuyez sur Entrée pour construire!

c:\>Echo ▓$┤☻═!═  > $.com

Exécutez le fichier '$ .com' et vous verrez un seul caractère dollar ($) affiché à l'écran.

c:\>$.com
$
c:\> 

Toutes nos félicitations! Vous venez de créer votre premier fichier exécutable codé appelé $ .com.

3
Colin Ord

vous pouvez faire un démontage et essayer de comprendre le code machine pour les opcodes que vous utilisez dans votre assembleur

par exemple

org 0x100
mov dx,msg
mov ah,0x09
int 0x21
ret
msg db 'hello$'

compilé avec nasm -fbin ./a.asm -o ./a.com a ndisasm a.com livrer le démontage suivant:

00000000  BA0801            mov dx,0x108
00000003  B409              mov ah,0x9
00000005  CD21              int 0x21
00000007  C3                ret
00000008  68656C            Push Word 0x6c65
0000000B  6C                insb
0000000C  6F                outsw
0000000D  24                db 0x24

00000000 to 00000007 are the instructions

afin que vous puissiez jouer avec le code machine ba0801, en utilisant un éditeur hexadécimal, essayez de le changer en ba0901, et seul 'Ello' sera imprimé, vous pouvez jouer avec votre éditeur hexadécimal et remplir les trucs avec NOP, qui est 0x90 dans la machine code, par exemple:

00000000:  ba 50 01 90 90 90 90 90  90 90 90 90 90 90 90 90  .@..............
00000010:  b4 09 90 90 90 90 90 90  90 90 90 90 90 90 90 90  ................
00000020:  cd 21 90 90 90 90 90 90  90 90 90 90 90 90 90 90  .!..............
00000030:  c3 90 90 90 90 90 90 90  90 90 90 90 90 90 90 90  ................
00000040:  71 77 65 72 74 79 75 69  61 73 64 66 67 68 6a 24  qwertyuiasdfghj$
00000050:  61 73 64 66 67 68 6a 6b  61 73 64 66 67 68 6a 24  asdfghjkasdfghj$
00000060:  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --  ----------------

si vous l'enregistrez avec l'extension .com, vous pouvez l'exécuter dans DosBox

3
Skullquake