I] LE LANGUAGE ASSEMBLEUR

Introduction

Ollydbg va nous permettre de faire deux choses en même temps: dessassembler pour avoir le code 
du programme en language assembleur, et debuguer pour executer le programme pas à pas (les instructions
assembleurs les unes après les autres) pour mieux comprendre.
Dans les deux cas, le cracker novice doit avoir quelques notions de base en assembleur pour pouvoir cracker.

D'abord, un petit aperçu d'ollydbg:

ollydbg



On voit qu'il y a quatres fenetres principales dans ollydbg:

1) LES INSTRUCTIONS ASSEMBLEUR --> le code qu'on execute pas à pas. Chaque ligne de code
executée peut modifier les valeurs des registres, des adresses memoires, de la pile.

2) LES REGISTRES --> petits emplacements de memoire

3) LES ADRESSES MEMOIRE --> pour stocker des données ou conserver les valeurs des registres

4) LA PILE --> pour voir ce qui est transféré aux call (sous programmes)


la fenetre la plus importante est la fenetre des instructions assembleur, car c'est elle qui va nous permettre
de comprendre ce que fait le programme. Quand on ne précise pas la fenetre, il faut regarder la fenetre
principale avec le code assembleur

1) LES INSTRUCTIONS ASSEMBLEUR

* L'instruction MOV (copie)

Elle permet de copier le contenu d'un registre dans un autre, ou de copier un nombre dans un registre
(et non pas déplacer comme le terme anglais le suggère)

mov ax ,bx .......................copie le contenu de bx dans ax

mov bx, 4 ...............................met 4 dans bx

* L'intruction CMP (compare)

Elle compare des registres ou des emplacements de mémoire. Selon le résultat, elle va changer certains
indicateurs. Par exemple, si les deux opérandes sont égles, le zéro flag va être mis à un. On pourra gérer
ce résultat par un saut conditionnel. (si le zéro flag est à un, alors saute…)

cmp ax, bx........................compare ax à bx

je 12345.................................va à l'adresse 12345 si ax = bx



* Les instructions INC et DEC (incrémente, décrémente)

Ajoute 1 à la valeur d'un registre. L'instruction dec fait l'inverse

inc ax...............................ajoute 1 à ax

* L'instruction ADD (ajoute)

ajoute le contenu du second registre dans le premier registre

add ax,bx......................... ajoute à ax le contenu de bx

* L'instruction NOP (no operation)

Le processeur ne fait rien. Cette instruction est très utile en cracking pour remplacer certaines instructions gênantes.

* L'instruction XOR (ou exclusif)

En pratique, elle est souvent utilisée pour mettre à 0 un registre mais elle peut aussi servir pour crypter 
les mots de passe.

xor eax, eax .......................met eax à 0

* L'instruction TEST

Elle est à peu prés équivalente à l'instruction CMP. Elle modifie les indicateurs comme le zéro flag. 
En pratique, elle est souvent utilisée pour vérifier qu'un registre est à zéro.

test eax, eax.......................test sur eax

je 12345...................................va à l'adresse 12345 si eax=0


* L'instruction JMP

Elle effectue un saut à l'adresse spécifiée. Le programme continuera son exécution à l'adresse spécifiée.
Elle est l'équivalent de la commande goto en visual basic.

* L'instruction CALL

Elle appelle un sous programme à l'adresse spécifiée. Celui-ci doit se terminer par une instruction RET
qui dira au processeur de reprendre le programme après le CALL.

* Les sauts conditionnels JE JNE JZ JNZ

Ils testent les flags pour savoir si un saut doit avoir lieu ou non.
JE ou JZ : saute si le zéro flag est à 1
JNE ou JNZ : saute si le zéro flag est à 0

CMP ax ,bx................................met le zéro flag à 1 si ax=bx

JE 12345 .................................saute à l'adresse 12345 si ax=bx (Jump Equal)

CMP al, cl...................................compare al à cl

JNE 12345..................................saute à l'adresse 12345 si al <> cl (Jump Non Equal)

TEST eax, eax..........................met le zéro flag à 1 si eax=0

JZ 12345..................................saute à l'adresse 12345 si eax=0 (Jump Zero)


TEST eax, eax..........................teste la valeur de eax

JZ 12345..................................saute à l'adresse 12345 si eax<>0 (Jump Non Zero)


Il y a beaucoup d'autres sauts conditionnels

2) LES REGISTRES

Pour travailler, le processeur utilise des registres. Les registres sont de très petits emplacements
de mémoire situés dans le processeur, et que le programmeur peut manipuler à sa guise. 

* Les registres principaux

pour la signification du registre regardez la 2eme lettre

eax : l'accumulateur, il est souvent utilisé dans les opérations arithmétiques

ecx : le compteur, il est souvent utilisé pour réaliser des boucles

edx : le registre de "data"

ebx : registre de base

esp : indique la derniere valeur empilée sur la pile

ebp : inidique la base de la pile

esi : source index, il utilisé lors des opérations sur les chaînes de caractère

edi : destination index. Associé à esi lors d'opérations sur les chaînes de caractère.

remarque : la signification des registres n'est pas importante à connaître, ce qu'il faut simplement
retenir,c'est que les registres sont des sortes de variables ou on peut stocker des données
On peut se servir de eax, ecx, edx, esi, edi indifferement pour faire ce qu'on veut
(ebx, esp et ebp sont par contre un peu à part)

Les registres qu'on utilise dans les programmes actuels ont une contenance de 32 bits
(un bit = unité de mesure informatique désignant un chiffre du systeme binaire, 0 ou 1)
On peut utiliser une partie seulement de nos registres si on veux. Nos registres de 32 bits
peuvent se subdiviser en registres de 16 bits ou 8 bits

registres bits


On a vu qu'un registre peut être subdivisé. Prenons le cas de eax:

division eax

En assembleur, les unités de mesure qu'on va utiliser sont le byte, word, dword
eax = un dword --> les huits chiffres de EAX
ax= un word --> les quatres derniers chiffres de EAX
al = un byte --> les deux derniers chiffres de EAX

En assembleur, on manipule aussi bien eax, ax ou al, et la difference est importante
Ainsi dans notre exemple ou EAX = 00432010
aprés l'instruction mov eax, 0 --> EAX = 00000000 --> le dword est mis à zero
aprés l'instruction mov ax, 0   --> EAX = 00400000 ---> le word est mis à zero
aprés l'instruction mov al, 0    --> EAX = 00402000 --> le byte est mis à zero

Les autres registres fonctionnent comme eax. ECX (dword) peut ainsi etre decomposé en CX (word)
et CL (byte). Un dword va nous servir à manipuler des adresses, alors qu'un byte permet de manipuler 
les caracteres d'un serial par exemple.

* Le registre des flags

Ce registre est un ensemble d'indicateurs. Le plus utilisé est le zéro flag qui est égal à 0 ou à 1
Certaines instructions (CMP ou TEST) modifient ces flags pour permettre à un saut conditionnel de savoir
ce qu'il doit faire. Une methode rapide pour inverser un saut est de double cliquer sur le flag qui nous  interesse
(le plus souvent le zero flag).

loloko

3) LES ADRESSES MEMOIRE

Dans cette fenetre, aussi appelée fenetre de dump, on peux consulter le contenu des adresses memoire.
Pour travailler, le prog a besoin de conserver certaines valeurs. Voila le contenu de l'adresse 4DFED8

dump

A cette adresse, on a stocké le texte suivant "To help solve this problem.....". On peut ensuite afficher ce
message en se servant de cette adresse 4DFED8 et de la fonction MessageBoxA par exemple.
On peut stocker n'importe quoi dans la mêmoire, du texte, des variables, un faux sérial, le serial valide...

Pour continuer sur les bytes, word, dword, voila ce que font les instructions suivantes
sur la valeur suivante 004DFED8 = 54 6F 20 68 
MOV BYTE [4DFED8],0      --> 004DFED8 = 00 6F 20 68   
MOV WORD [4DFED8],0    -->004DFED8 = 00 00 20 68
MOV DWORD[4DFED8],0  -->004DFED8 = 00 00 00 00
Ellle modifient le contenu de l'adresse 4DFED8 (les crochets [ ] signifient contenu de)
en modifiant soit juste un byte, soit un word, ou encore un dword

4) LA PILE

La pile est une zone mémoire qui sert à stocker temporairement des données. Le fonctionnement est
different de la fenetre de dump. On ajoute une donnée  en l'empilant, et on la recupere en la dépilant.
On a vu tout à l'heure que CALL appelle un sous programme. Souvent, des donnés sont transmises au call
en utilisant push et récupérés par le call en utilisant pop, le tout par l'intermédiaire de la pile.
L'instruction d'empilage est push et l'instruction de désempilage est pop

mov eax, 04..................................eax=00000004

mov ecx, 01..................................ecx=00000001

push eax......................................met le contenu de eax dans la pile

push ecx......................................met le contenu de ex dans la pile

pop edx........................................enleve le dernier élément de la pile (ecx) et met le dans edx

pop ebx........................................enleve le dernier élément de la pile (eax) et met le dans ebx


Voila ce qu'il y a dans la pile juste aprés le push ecx:

pile apres push

à la fin on a donc edx=1 et ebx=4 et il n'y a plus aucune donnée dans la pile

pile apres pop


cours precedent                                                                                                                               cours suivant