True Warrior Tools

Rah, mon premier article. Il fallait un titre frappant :)

Que sont donc les True Warrior Tools ? En français, les outils du véritable guerrier. Pour être plus clair, je vais détailler ici les outils nécessaires à tout "véritable" développeur. Par véritable, je sous entends programmation (très) bas niveau (c natif, asm natif), et par "natif", j'entends : sans utiliser de librairies existantes, et sans utiliser d'API système, même s'il se peut que l'on ait recours aux fonctionnalités offertes par le bios

Vous l'aurez compris, nous allons faire un tour des outils existants pour parler directement à votre processeur sans passer par un OS. Plus précisément, les outils disponibles sous Windows. Je ne parlerai pas (ou peu) des outils utilisés sous Linux, puisqu'ils sont sûrement déjà installés et prêt à fonctionner.

Tout d'abord, il vous faudra un bon éditeur de texte (ça revient à chaque fois sur le tapis, mais on a toujours pas trouvé mieux). Personnellement, j'aime beaucoup la coloration syntaxique de Notepad++ (Npp) pour l'asm et le batch (oui oui nous allons faire du batch, aussi étrange que cela puisse paraître), mais pas pour le C. Si vous souhaitez le télécharger, http://sourceforge.net/projects/notepad-plus/files/

Ensuite, je vous conseille d'avoir une invite de commande intégrée dans votre explorateur, de sorte qu'un simple clic droit dans votre arborescence des dossiers ouvre une invite de commande déjà positionnée sur le dossier (ca vous évitera des cd dans tous les sens etc). Il va falloir tremper les mains dans le cambouis. Tout d'abord, Win+R / regedit. Rendez vous dans HKEY_CLASSES_ROOT (vache la liste !). Amateurs de sensations fortes, jetez un oeil au passage à la clef CLSID. Rendez vous dans la clef "Folder/Shell". Créez une clef nommée comme vous voulez (le nom ne sert pas). Puis modifiez la valeur de la REG_SZ par défaut. J'ai simplement mis "Invite de commande", mais mettez ce que vous voulez, c'est ce qui apparaîtra dans le menu contextuel. Puis créez une nouvelle clef "command" (pas d'erreur de frappe ici, sinon c'est le fail !) . Modifiez la REG_SZ par défaut de la nouvelle clef et donnez lui cette valeur :

C:\Windows\System32\cmd.exe /k cd "%1%"

. Voilà, pas besoin de reboot ni rien, c'est appliqué.

On est loin d'avoir fini la liste ;) Alors on continue avec une machine virtuelle / un émulateur. J'utilise Vmware Workstation 7 personnellement. Mais quitte à se lancer, autant partir sur du gratuit avec Virtual Box disponible ici : http://www.virtualbox.org/wiki/Downloads . On entend beaucoup parler de Bochs. Un peu moche à mon gout, mais ca a l'air efficace, et surtout léger à côté de Vmware =p Disponible ici : http://sourceforge.net/projects/bochs/files/. Si vous recompilez Bochs sous linux vous pouvez spécifier d'ajouter l'interface graphique du debugger (assez poussée). Il y a aussi QEMU bien sûr, téléchargeable pour Windows ici : http://lassauge.free.fr/qemu/

Attention, si vous avez choisi Vmware, je vous déconseille d'activer le full debugger. A la première interruption non gérée, j'ai eu le droit à un joli freeze de ma machine (réelle, pas virtuelle !), avec le debugger qui tournait en tâche de fond jusqu'à kill du process.

Outil suivant : le compilateur asm. Je ne vais pas vous laisser le choix pour celui-ci, nasm à tout prix ! masm et tasm vous généreront des syntaxes un peu particulières, et le gas utilise la syntaxe AT&T (moins vous la fréquenterez, mieux vous vous porterez =) ) . nasm est disponible ici : http://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D . Je vous conseille la dernière version non RC (attention elles ne sont pas toujours triées par numéro de version). Puis dans le sous répertoire win32 vous avez un joli installeur ou un joli zip. Une fois installé / décompressé, il va vous falloir ajouter le dossier bin de nasm au PATH. Pour cela allez dans les propriétés systèmes / paramètres avancés / variables d'environnement / système : PATH / Modifier. Ajoutez un ; et collez le chemin du dossier bin (inclus !)

Héhé, je gardais le meilleur pour la fin : le compilateur C. Je vous conseille le portage de GCC sous win32, MinGW. Disponible ici : http://sourceforge.net/projects/mingw/files/ . Personnellement, j'ai pris l'Automated MinGW Installer / MinGW x.xx / MinGWxxx.exe . Qui marche très bien. Une fois installé (ou autre), ajoutez le dossier bin de MinGW au PATH.

C'est bien joli tout ça, vous pouvez désormais compiler n'importe quel .c en ouvrant une cmd dans le dossier du .c en tapant "gcc fichier.c". Aussi simple que ça. Ah non j'oubliais, MinGW étant le portage Windows de GCC, vous aurez un joli .exe bourré d'entêtes PE spécifiques à Windows : autrement dit vous ne pourrez rien en faire en dehors de Windows. Pour remédier à cela, nous allons devoir nous détacher de l'OS en laissant tomber ses entêtes et ses librairies (nous allons compiler un fichier binaire plat, ou "flat binary executable" =o).

Pour cela, 3 étapes sont nécessaires (sous Windows du moins !) :

- Changer ses habitudes

- Demander à gcc de compiler et d'assembler, mais de ne PAS linker

- Demander à ld de linker proprement

- Demander à objcopy de ne récupérer que l'essentiel

Tout d'abord, changer ses habitudes, en quoi cela consiste-t-il ? Désormais le point d'entrée de vos applications NE s'appellera PAS main. Pourquoi ? Parce que c'est un cas particulier, et lors du linkage il est détecté et traité spécialement. C'est agaçant :p Tout ce qu'il vous faudra faire c'est choisir un autre nom, du style "monMain" (vache c'est moche !) ou "entry_point" (ca pète déjà un peu plus :) )

Deuxièmement, demander à gcc de faire du bon boulot :

gcc -c -ffreestanding -nostdinc -nostdlib -mno-stack-arg-probe -o #OUPUT#.o #INPUT#.c

#INPUT# et #OUTPUT# étant les noms de vos fichiers d'entrée et de sortie. Les options : -c demande de s'arrêter après l'assemblage, -ffreestanding demande de se passer du main et des librairies standards du c, -nostdinc -nostdlib demandent de ne pas inclure automatiquement les librairies standards, -mno-stack-arg-probe demande de ne pas utiliser l'instruction _alloca pour allouer la stack, et de simplement décrémenter le pointeur de pile à la place, et -o c'est juste pour choisir le nom =) GCC va vous générer un .o si vous compilez quelque chose avec cette commande

Troisième étape, le linker :

ld -i -e _#ENTRY POINT# -Ttext 0x0 -o #OUTPUT#.o #INPUT#.o

#INPUT# de ld = #OUTPUT# de gcc, attention #ENTRY POINT# correspond au nom de la fonction qui se substitue à l'habituel main (surtout ne pas oublier l'underscore devant le nom, sinon vous aurez une jolie erreur !). Les options : -o pour la sortie, comme avec gcc, -i pour pouvoir utiliser objcopy par la suite, -e pour spécifier le point d'entrée, -Ttext pour choisir l'adresse à laquelle doit être chargé le segement de code (0x0 pour être chargé au tout début =) ).

Enfin :

objcopy -R .note -R .comment -S -O binary #INPUT#.o #OUTPUT#

#INPUT# de objcopy = #OUTPUT# de ld. Les options : -R = enlève le segment spécifié, -O binary formatte la sortie en flat binary executable, et -S enlève les symboles et les informations écrites par -i de ld

Au final, vous avez un joli fichier sans extension. Pour le disséquer, rien de tel qu'un désassembleur ! J'imagine déjà "ah mince encore un soft à télécharger..." =) Point du tout, nasm apporte son propre désassembleur, qui se nomme ndisasm. Il suffit donc de faire "ndisasm #INPUT#" ou #INPUT# de ndisasm = #OUTPUT# de objcopy.

C'est bien joli tout ca mais je vais pas me retaper tout ça à chaque fois que je recompile ! C'est à ça que sert le batch. Créez un fichier .bat nommé comme vous le souhaitez, soit dans le dossier bin de nasm, soit dans le dossier bin de mingw (il faut qu'il soit facilement référencable par le PATH). Le contenu du fichier :

@echo off
gcc -c -ffreestanding -nostdinc -nostdlib -mno-stack-arg-probe -o %1.o %1.c
ld -i -e _%2 -Ttext 0x0 -o tmp.o %1.o
objcopy -R .note -R .comment -S -O binary tmp.o %1

ndisasm %1
del tmp.o
del %1.o

Voilà. Les del servent simplement à nettoyer un peu le dossier. La syntaxe d'appel de votre batch : "#BATCH# #FICHIER# #ENTRY POINT#", #BATCH# = nom du batch, #ENTRY POINT# = nom du main SANS l'underscore devant (ajoutée automatiquement dans le script), #FICHIER# = le nom du fichier à compiler SANS l'extension .c

Voilà, ce premier article est fini =p Si vous avez des outils à me suggérer, des critiques, des remarques, n'hésitez pas =)

Il y aura sûrement (beaucoup) d'autres articles dans cette catégorie =p

Aucun commentaire.

Ajoutez votre commentaire