Introduction à l'assembleur x86 ( ASM )
Un peut d'histoire... :
John Von Neuman, tout repose sur cette personne. Considéré comme le plus grand génie de ce siècle (certains de ses amis et proches pensaient même que s'était un extra-terrestre qui avait pris une apparence humaine). Il est le père de l'informatique moderne, c'est de lui que le cyber est né. A la base il voulait concevoir une machine capable de penser, il atteindra son but en 1946 en concevant un ordinateur digne de se nom, programmable et pouvant prendre certaines initiatives basique. Mais à l'époque ce n'était qu'un balbutiment, il continua ses travaux chez IBM qui lui doit beaucoup, c'est dans cette période qu'est adopter le "bit" comme unité de mesure de mémoire pour ordinateurs. Il fut aussi à l'origine de la finalisation de travaux mathématique sur la géneration aléatoire de nombres et autres systemes de probabilitées d'une complexité extrême, encore mal saisie de nos jours par les plus grands mathématiciens. Il s'eteind à Washington en février 1957 à l'âge de 53 ans.
J.VN ayant inventé le bit, tous les ordinateurs se programmaient bit par bit en binaire. Il fallait donc faire de fastidieuses convertions pour réussir à faire des instructions correctes. C'est par cette difficulté à former un programme que des ingenieurs des laboratoires Bell (à qui l'on doit aussi le C le C++ quand à lui à été crée par Bjarné Stroustrup) ont crée l'assembleur. Ce language permettrai d'assembler differentes instructions avec des mots clés basiques pour former un programme en programmant la machine directement mais de façon plus lisible et compréhensible pour pouvoir developper un programme et de le mettre plus facilement à jour. L'assembleur etait né...
Dans ce cours qui s'etendra sur plusieurs numéros, nous allond étudier l'assembleur, appelé courament asm.
Résumé sur l'asm :
L'assembleur est un language de très bas niveau, très proche de la machine, on appelle ca un language machine tout simplement. C'est le language de plus bas niveau qui existe. C'est pour cette raison qu'il presente plusieurs avantages :
Hardware :
Comme nous l'avons vu, l'assembleur est un language machine pour savoir s'en servir il faut connaitre un minimum sont anatomie, à la machine... :
Il existe 8 registres courant :
A l'origine, les registres courant étaient AX,BX,SP, etc... mais avant l'étendue à 32 bits. On ajoute donc E devant pour dire Extended, soit EAX = Accumulateur étendu.
Comme on peut le voir, les quatres registre AX, BX, CX et DX peuvent être divisés en deux sous-registres de 8 bits, l'octect de poids fort étant indiqué par la lettre H (Hight) et celui de poid faible par la lettre L (Low). De cette menière on peut manipuler juste un morceau de registre mais le restant ne sera pas indépendant, par exmple si l'on touche à AL, les registres EAX et AX s'en veront aussi modifier mais AH et AX resteront indépendants.
Passons au code source :
Tout d'abord je tiens à remercier vivement Kheo pour m'avoir aider à terminer ce patcheur!
Je remerci aussi Neo BerSerKeR pour l'ASCII :)
Dans ce sode source vous ne comprendrez pas grand chose (si cous êtes debutant) mais il sera commenté dans les endroits clefs.
Voilà le source, pour le compiler vous aurez besoin du Tasm; de ses fichier Tasm.exe et Tlink.exe. Le fichier de compilation est fourni ici avec le code source. Comme d' habitude tout ce qui est en rouge peut être modifier sans problemes :
----------------------------------------[ Début ]----------------------------------------
;code source Alpha et finalisations: Static REvenge ; moteur du patch revus et corrigé par Kheo
.MODEL TINY .CODE .486 ORG 100h ;Déclaration de fichier com ;Ici ORG 100h définit l'adresse ou la 1ere instruction du programme va se placer ;Par conséquent qi vous débugger ce prog, la première instruction sera en XXXX:0100 start: jmp main ;------------------------[Zone à modifier]------------------------------* Nick equ " Kheo & Static REvenge " ; Ton nick (respecte l'espace entre chaque guillement) Nom_du_prog equ " Progdemerde v1.0 " ; Le nom du prog cracké Type_de_patch equ " Full !! " ; Met ici ce que fait ton patch filename db "Progz.exe",0 ; Nom du fichier à patcher nb_blocs equ 3 ; Nombre de blocs à changer, ici 2 patch_ptr0 equ 0487Eh ,488Eh ,4880h ; Offset des octets à patcher new_val0 equ 0FFh,0FFh ,0FFh ,033h,033h,033h,033h ; Nouvelles valeurs a patcher. Toujours mettre un 0 avant la valeur sinon sa plante avec les caratères alpha. Exemple => ne pas mettre EBh mais 0EBh. PS: le mieux et quand même de toujours mettre 0 pour + le clareté long_bloc0 equ 2 ,1 ,4 ; Longueur le chaque chaîne, MAX = 65535 taille equ 458752 ; Ecrire ici la taille exacte du fichier à patcher (en octets)! texte db " ²",0dh,0ah db " ²²Û",0dh,0ah db " ²²²Û",0dh,0ah db " ²²²²²²² ²²²²Û ²²²²²²²",0dh,0ah db " ²²²²²²²Û ²²²²²Û ²²²²²²²Û",0dh,0ah db " ²²²²ÛÛÛÛ ²²²²²²²Û ÛÛ²²²²Û",0dh,0ah db " ²²²²Û ²²²²²²²²Û ²²²²Û",0dh,0ah db " ²²²²Û ²²²²²²²²²Û ²²²²²²²²²²²² ²²²²Û",0dh,0ah db " ²²²²Û ²²²²²²²²²²²²²² ²²²²²²²²²²²²Û ²²²²Û°°°°° Û°°°°°°°°°°° Û°°°°°°°°°",0dh,0ah db " ²²²²Û ²²²²²²²²²²²²²²²Û²²²²²ÛÛÛÛÛÛÛÛ ²²²²Û°°°°°° Û°°°°°°°°°°°° Û°°°°°°°°°°",0dh,0ah db " ²²²²²²² ÛÛÛÛÛ²²²²²²²²²Û²²²²²Û ²²²²²²²Û ÛÛ°°°° Û°°ÛÛÛÛÛÛÛ°°° Û°°°°ÛÛÛÛ°°",0dh,0ah db " ²²²²²²²Û ²²²²²²²²ÛÛ²²²²²Û ²²²²²²²Û Û°°°° Û°°°°°°°°°°°° Û°°°°°°°°°°",0dh,0ah db " ÛÛÛÛÛÛÛ ²²²²²²²ÛÛ ²²²²²Û ÛÛÛÛÛÛÛ Û°°°° Û°°°°°°°°°°ÛÛ Û°°°°°°°°°Û",0dh,0ah db " ²²²²²²ÛÛ ²²²²²Û Û°°°° Û°°°° Û°°° Û°°°°Û Û°°°°°ÛÛÛÛ",0dh,0ah db " ²²²²²ÛÛ ²²²²²²²²²²²² Û°°°°°°°°°°°°° Û°°° Û°°°° Û°°°°",0dh,0ah db " ²²²²ÛÛ ²²²²²²²²²²²²Û Û°°°°°°°°°°°°° Û°°° Û°°°° Û°°°°",0dh,0ah db " ²²²ÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛÛ N.B",0dh,0ah db " ²²ÛÛ",0dh,0ah db " ²ÛÛ",0dh,0ah db " Û",0dh,0ah ;-----------------------------------------------------------------------* db " Crack for : ",Nom_du_prog,"",0dh,0ah db " Crack type : ",Type_de_patch,"",0dh,0ah db " Cracked by : ",Nick,"",0dh,0ah,"$" done db "CraCk SuccSessFuL!",0dh,0ah,"$" error db "An error as appear!",0dh,0ah,"$" Error1 db 0dh,0ah,"Erreur : le fichier a patcher ne fait pas la bonne taille !",0dh,0ah,"$" Error2 db 0dh,0ah,"Erreur : le fichier a patcher est introuvable !",0dh,0ah,"$" ;-------------------------[NE PAS MODIFIER A LA SUITE!]----------------------------* handle dw 0 patch_ptr dd patch_ptr0 new_val db new_val0 long_bloc dw long_bloc0 cmpt db 0 ptr_val dw 0 ptr_patch dw 0 ptr_long dw 0 ;-----------------------------------------------------------------------* main: mov ah, 9 lea dx, texte int 21h ; affichage d'une chaine de caractère. call openfile call patch call closefile mov ax, 4C00h int 21h ; le programme se fini ici si tout c'est bien passé ! openfile: ; Cette procédure permet d'ouvrir le fichier et de retourner le handle de celui ci dans [handle] ; Si le fichier ne peut etre ouvert alors elle envoie un message d'erreur et termine le programme ; enfin elle teste la taille du fichier de manière à pas se tromper . mov ax, 4300h lea dx, filename int 21h jc erreur2 ; lecture des attribut du fichier. Permet de savoir s'il existe ... ;OUT: ; ecx contient ces attribut ; si erreur alors CF = 1 mov ah, 3Dh mov al, 11000010b lea dx, filename int 21h jc erreur ; Ouvre un fichier ;IN: ; AL mode d'acces ;OUT: ; CF = 1 -> error ; CF=0 -> AX= handle du fichier mov [handle],ax mov ah, 42h mov al, 02h mov bx, [handle] xor cx, cx xor dx, dx int 21h ; ici j'appelle la fonction pour deplacer le pointeur dans le fichier. ; al=2 -> je me refère par rapport à la fin du file et je met 0 0 cx, dx ; de cette manière l'int 2 va positionner le ptr à la fin du fichier et ; me renvoyer ca taille dans dx,ax xor bx, bx mov bx, dx imul ebx, 010000h mov bx, ax ; ici je recupère la taille et je la passe sur un registre 32 bits ; pour pouvoir la comparer avec la variable taille cmp ebx, taille jnz erreur1 ; Si ca n'est pas egal alors erreur ! ret closefile: mov ax, 3E00h mov bx, [handle] Int 21h ; ferme le fichier et libère le handle jc erreur ret ;-------------------------- Gestion des erreurs ------------------------* erreur2: lea dx, error2 jmp er erreur1: lea dx, error1 jmp er erreur: lea dx, error jmp er er: mov ah, 9 int 21h ; affiche un message d'erreur mov ax, 4C01h int 21h ; termine le prog avec le code d'erreur 1 ;-------------------- Routine d'ecriture du patch ----------------------* patch: mov ptr_val, offset new_val mov ptr_patch, offset patch_ptr mov ptr_long, offset long_bloc ; recupère les adresse des variables, de manière à pouvoir les incrémenter pour pointer plus loin bc: mov ah, 42h xor al, al mov bx, [handle] mov si, ptr_patch mov dx, [si] add si, 2 mov cx, [si] int 21h ; deplace le pointeur dans le fichier ;IN: ; cx = poid fort & dx = poid faible ;OUT: ; ax = poid faible & dx = poid fort ; attention en mémoire on lis de gauche à droite, donc le poid faible se lit en premier ! mov si, ptr_patch cmp ax, [si] jnz erreur add si, 2 cmp dx, [si] jnz erreur ; vérifie si la position dans le fichier est celle voulue ? mov ah, 40h mov bx, [handle] mov si, ptr_long mov cx, [si] mov si, ptr_val mov dx, si int 21h ; ici j'écris dans le fichier représenté par le handle [handle] à l'adresse on l'on vient de positionner le ptr ; cx contenant la longueur, le nb de byte à ecrire et ds:dx le ptr sur les byte à ecrire inc [cmpt] cmp [cmpt],nb_blocs jz wrt_ok ; permet de savoir si tout les bytes on été modifié grace à nb_blocs ; etant donné que l'ecriture dans le ficher se fait par blocs de X byte alors il ; faut comparer mon compteur cmpt et nb_bloc add ptr_val,cx add ptr_patch,4 add ptr_long,2 ; cette partie de code permet de modifier les ptr de manière à ce que la boucle ; modifie les prochains bytes jmp bc wrt_ok: mov ah, 9 lea dx, done int 21h ; affiche le message nous informant que le crack a fonctionné . ret end start
----------------------------------------[ Fin ]-----------------------------------------
C'est bon, avec ce programme vous pourrez créer des patchs portables, compatibles Windows et vous pourrez mettre de supers ASCII :)
Bien sur, l'assembleur peut parraître fastidieux mais avec un peut de temps et de pratique on se rend vite compte que c'est un language assez simple à mettre en oeuvre pour faire de petits programmes.
Si vous voulez en savoir plus je vais vous conseillez quelques bouquins et liens :
L'assembleur, Théorie, pratique et exercices." de Bernard Fabrot aux éditions Marabout, toujours à 50 balles. Et oui, je l'ai deja conseiller dans le Memento 1 mais ce bouquin est vraiment très bien fait.
L'assembleur, Une découverte pas à pas." de Phillipe Mercier aux éditions Marabout (décidement :) aussi à 50 bourzoufs. Ce bouquin contrairement à son nom n'est pas tellement bien fait pour debuter mais se revelera utile pour ceux qui ont quelques bases.
Et comme sites web bien fait et traitent du sujet, en vrac : www.win32asm.org http://www.multimania.com/w32asm/ http://assembly.citeweb.net/ et www.madchat.org pour les tutz portant qur le sujet.
See ÿA!