Chrooter apache
Matériel
Ajout disque dur
Ajout carte
Audit des disques durs
Gestion des peripheriques
Disquette d'installation
Ajout d'un scanner
Graver en ligne de commande
Astuces
Ajout d'une imprimante
Réseau
Configuration reseau
Dns
Serveur cvs
Proxy squid 
Installation serveur ftp
Installation qmail 
Installation serveur courrier sous debian
Outil TCP/IP 
Le serveur samba
Connexion a distance securisee
Client/serveur vnc
Configurer apache
Dyndns
Sécurité
Chiffrer un fichier/dossier
Securiser son poste
Mur pare feu pas a pas
Authentification ht-access
Surveillance de serveur CACTI
Snort
Snort-inline
Securiser Apache avec mod_security
Filtrage squid/squidguard/dansguardian
Auditer son site web
Sécuriser son linux
Installer un Lamp avec ssl
Contrer les scans de ports
Traitement anti-spam
Installer/Utiliser tripwire
Faire des sauvegardes incrémentales
Divers
Elisa, le multimédia facile
Utilisation de lilo
Les commandes Linux
Le multi-tache
Le crontab
Exploration de la configuration
Quotas
Messagerie
Installer une application
Debugger ses applications
Le format RPM
Mise a jour du noyau
Qemu
Tour d'horizon des principaux p2p
Récupération du système
Bips d'un pc
Astuces windows
Table Ascii
Lamerland
Conversion de fichiers musicaux
Compiler ses rpms
Liens
hakin9
Secureroot.com
Hackerthreads.org
Defcon
Hackerlounge
Les derniers exploits
Tous les codes sources
Securite sous Linux
Les logiciels libres quotidiens
Ezine divers
Madchat
Textes divers
Archives
 
Traductions LG
Toutes les traductions
Traductions Phrack
Toutes les traductions

Il y a actuellement 9 visiteurs connectés sur le site !

Google
Les instructions assembleur
Les instructions assembleur

 

Correspondance Hexa Assembleur
Instruction Assembleur
Détails des Instructions
Les instructions conditionnelles
Les registres
Exemple

 

Correspondance Hexa Assembleur

Il faut savoir que chaque instruction est codée en Assembleur, il suffit donc de remplacer ce code par un autre. Encore faut-il connaitre ces codes, c'est ce dont on va parler dans ce chapitre. Tout d'abord, on va commencer par les quelques instructions souvent utilisée:

74 = je
75 = jne
EB = jmp
90 = nop
33 = Xor

Donc par exemple on veut changer un jne en un je, on va ouvrir le programme avec ollydbg et on recherche l'instruction que vous voulez changer. Une fois celle-ci trouvée, vous devriez avoir un truc du genre:JNE
Puisqu'on veut obtenir un je, on vas donc remplacer le 75 par un 74, assez simple non ?

Détails des instructions

La première instruction : MOV
Cette instruction vient de l'anglais "move" qui signifie déplacer mais attention, le sens de ce terme est modifié car l'instruction MOV ne déplace pas mais place tout simplement. Cette instruction nécessite deux opérandes (deux variables) qui sont la destination et la source. Ceux-ci peuvent être des registres généraux ou des emplacements mémoire. Cependant, les deux opérandes ne peuvent pas être toutes les deux des emplacements mémoire. De même, la destination ne peut pas être ce qu'on appelle une valeur immédiate (les nombres sont des valeurs immédiates, des valeurs dont on connait immédiatement le résultat) donc pas de MOV 10,AX. Ceci n'a pas de sens, comment pouvez-vous mettre dans le nombre 10, la valeur de AX ? 10 n'est pas un registre.
Une autre règle à respecter, les opérandes doivent être de la même taille donc pas de MOV AX,AL, cela me semble assez logique. On ne peut pas utiliser une valeur immédiate avec un registre de segment (MOV ES,5 = impossible mais MOV ES,AX = possible).
Quelques exemples :

MOV AL,CL (place le contenu de CL dans AL) donc si AL=5 et CL=10, nous aurons AL=10 et CL=10.

MOV CX,ES:[DI] (place dans CX, le contenu 16 bits de l'emplacement ES:[DI]). Donc si le word (le word est l'unité correspondant à 16 bits) ES:[DI]=34000, nous aurons CX=34000.

MOV CL,DS:[SI] (place dans CL, le contenu 8 bits (byte) de l'emplacement DS:[SI]). Donc si DS:[SI] (attention en 8 bits) = 12, CL vaudra 12.

Au sujet de ces emplacements mémoire, il faut que vous vous les représentiez comme des "cases" de 8 bits, comme le plus petit registre fait 8 bits, on ne peut pas diviser la mémoire en emplacements plus petits. On peut prendre directement 16 bits en mémoire (un word) ou carrément un dword (32 bits). Il est tres important de saisir cette notion. Un exemple concret : vous avez des livres sur une étagère, le livre se trouvant toute à gauche est le 1er de la liste, nous nous déplacons de gauche à droite. Un livre est un byte (8 bits), 2 livres sont un word (16 bits), 4 livres font un dword (32 bits). Si nous faisons MOV AX,ES:[DI], nous allons prendre 2 livres, en commencant par le livre se trouvant à l'emplacement DI et en prenant ensuite le livre se trouvant à l'emplacement DI+1 (l'emplacement suivant dans votre rangée de livre, 1 byte plus loin en mémoire).
Voici un autre exemple :
MOV EAX,ES:[DI] (place un dword depuis ES:[DI] dans EAX). C'est comme si on copiait 4 livres dans EAX.

Et quelques exemples incorrects :

MOV 1,10 (impossible et pas logique)

MOV ES:[DI],DS:[SI] (incodable malheureusement)

MOV ES,10 (incodable, il faut passer par un registre général donc MOV ES,AX ou MOV ES,CX mais pas de MOV ES,AL).

Ce qu'il faut retenir c'est que l'instruction MOV est comme le signe '=' MOV ES,CX c'est comme faire ES=CX.

Une autre instruction : JMP

JMP est une simplification pour exprimer le mot JUMP qui signifie sauter en anglais. JMP va servir dans le programme pour "passer" d'une opération à une autre, de sauter dans le programme à différents endroits pour effectuer d'autrest taches. Je ne vais pas m'attarder dans des explications sur le pointeur d'instruction mais sachez que chaque instruction est désignée par un emplacement en mémoire (défini par CS:[IP]). L'instruction JMP va donc modifier la valeur de IP et par conséquence changer d'instruction. On peut utiliser JMP avec des valeurs immédiates.
Exemples :
JMP 10 (il aura pour effet de passer, non pas à l'instruction qui se trouve à la ligne 10 , mais à l'emplacement mémoire 10. Une instruction n'est pas forcément de taille 1, certaines peuvent s'étaler sur plusieurs bytes.)

Il est plus simple d'utiliser des "étiquettes qu'on peut écrire sous la forme "ETIQUETTES:". Avec les étiquettes, il suffit d'écrire JMP ETIQUETTES pour arriver directement à l'instruction qui suit le étiquette. Un petit exemple de code:

DEBUT :
MOV AX,14
JMP DEBUT

Ce programme ne fait rien sinon placer continuellement 14 dans AX, on appelle cela une boucle. Nous verrons plus tard qu'il existe différents types de sauts.
Quelques instructions arithmétiques : ADD et SUB

ADD sert à additionner, et nécessite deux opérandes : une source et une destination. La destination prendra la valeur de source + destination. Les règles de combinaison sont les mêmes que pour MOV mais avec SUB et ADD, l'utilisation des registres de segment est impossible.
Exemples :
ADD AX,CX (si AX=10 et CX=20 alors nous aurons AX=30 et CX=20)

ADD EAX,EBX

ADD AX,-123 (l'assembleur autorise les nombres négatifs)

SUB DI,12

Quelques exemples impossibles :

ADD AX,CL (comme pour MOV, un 16 bits avec un 8 bits sont incompatibles)

SUB ES:[DI],DS:[SI]

ADD ES,13 (impossible car c'est un registre de segment)

À présent, nous abordons l'instruction PUSH qui signifie Pousser. Cette instruction permet de placer une valeur au sommet de la pile. PUSH doit être accompagné d'une valeur de 16 ou 32 bits (souvent un registre) ou d'une valeur immédiate.
Exemple 1:
PUSH AX
PUSH BX

En premier lieu, AX est placé en haut de la pile et ensuite BX est placé au sommet, AX est repoussé au deuxième rang.
Exemple 2:

PUSH 1230
PUSH AX

Nous plaçons dans la pile, la valeur 1230 (qui aurait pu être aussi un 32 bits) et ensuite AX, ce qui place 1230 au deuxième rang.
Passons maintenant à l'instruction de "récupération" qui se nomme POP (sortir-tirer). Cette instruction demande comme PUSH, une valeur de 16 ou 32 bits (seulement un registre). Elle prend la première valeur de la pile et la place dans le registre qui suit l'instruction.
Exemple 1:
Nous avions PUSH AX et PUSH BX et maintenant nous allons les sortir de la pile en utilisant
POP BX
POP AX

Nous retrouvons les valeurs initiales de AX et BX mais nous aurions eu aussi la possibilité de faire d'abord POP AX et POP BX, ce qui aurait placé dans AX, la valeur BX (1er dans la pile) et dans BX, la valeur AX (2ème).
Exemple 2:

La première partie était PUSH 1230 et PUSH AX. Nous allons placer dans CX, la valeur de AX (1er de pile) et dans DX, le nombre 1230 (2ème puisque "pilé" après)

POP CX
POP DX

Dans CX, nous avons la valeur de AX et dans DX, nous avons 1230.
La pile est très utile pour garder la valeur d'un registre que l'on va utiliser afin de le retrouver intact un peu plus loin. Souvent dans des routines, le programmeur doit utilise tout les registres mais leur nombre est limité (utilisation des registres au maximum = gain de vitesse). Le programmeur va donc utiliser les fonctions de la pile pour pouvoir utiliser les registres et garder leur valeur actuelle pour une utilisation ultérieure. Malheureusement les instructions de la pile ralentissent le programme, la pile étant de toute façon plus lente que les registres qui sont au coeur du CPU.

Instructions Assembleur

Cette liste non-exhaustive vient de Alligator27

********************************************************************************
                        | LES INSTRUCTIONS ASSEMBLEUR |
                        |              PAR            |
 			|          ALLIGATOR427	      |   09/96
*********************************************************************************

AAA	ajustement ascii de  apres une addition. Format BCD
AAD	ajustement ascii de  avant une division BCD
AAM	ajustement ascii de  apres une multiplication. Format BCD
AAS	ajustement ascii de  apres une soustraction.
ADC	addition avec retenue 
ADD	addition sans retenue
AND	operation logique ET
ARPL	ajuste le niveau du privilege (mode protégée)
BOUND	teste un nombre par rapport a des limites
BSF	cherche 1 bit de droite a gauche
BSR	"  "   "   "  "  gauche a droite
BSWAP	conversion d'un registre en un format INTEL
BT	charge 1 bit en CF
BTC	" "  "   "   "  "  et complement
BTR	" " " " "  " " " " puis le met a 0 dans la source
BTS	" " " " " " " " " " " " " " " " "1 " " " " "" "  "
CALL	appel de sous programme
CBW	convertit l'octet signé de  en un mot dans 
CDQ	convertit le mot signé de EAX en un quadruple mot dans 
CLC	mets l'indicateur a 0 dans CF
CLD	" " " " "  " " " " " " " " DF
CLI	" " " " " " " " "  " " " " IF
CLTS	mets a 0 l'indicateur de changement de contexte Task-Switch-Flag
	mode protégée.
CMC	complemente l'indicateur CF
CMP	comparaison logique
CMPS[b][w] compare des chaines de caracteres
CMPSD	compare des chaines de caractere 80386()
CMPXCHG	compare l'accumulateur avec AL, AX, ou EAX
CWD	convertit le contenu signe de AX en un double mots DX:AX
CWDE	"  " " " " "" " "" " " " " " " " "" " " " " " " "  dans EAX
DAA	ajustement decimal de AL apres une addition BCD
DAS	"  " " " " " " " " " " " " " " " " soustraction BCD
DEC	decrementation 
DIV	division non signee
ENTER	construit un cadre de pile pour une procedure de haut niveau.
ESC	acces pour le coprocesseur
HLT	arret du processeur en attente d'un evenement externe
IBTS 	insere une chaine de bits (mode protegee)
IDIV	division signée
IMUL	multiplication signée
IN	lit un octet ou mot sur un port peripherique
INC	incrementation
INS[b][w] lit une chaine sur un port
INT 	interruption logiciel
INTO	active l'interruption 4 si l'indicateur OF est armé
INBD	efface le contenu de la mem cache du 486
INVLPG	exploitation du 486 en mode virtuel. multiprocesseur 8088
IRET	retour d'interruption
IRETD	" " " " " " " " " "" depuis un segment de 32bits
JA	branchement si superieur
JAE	 "" "  " " "" "  " ""  " ou egal
JB	branchement si inferieur
JBE	" " " " " " " " " " " " " ou egal
JC	branchement si CF est a 1
JNC	 " " " " ""  " ""  " "" 0
JCXZ	 " " " " " " " CX " " " " 
JECXZ	branchement si le registre ECX est a 0
JE	branchement en cas d'egalité
JG	branchement si arithmetiquement superieur ou egale
JMP	branchement a l'adresse indiquée
JNA	branchement si non superieur
JNAE	branchement si non superieur ou egal
JNB	branchement si non inferieur
JNBE	 "" " " " "" "  " " "" " " " ou egal
JNE	branchement en cas de non egalité
JNG	branchement si arithmetiquement non superieur
JNGE	 " " " " "" " " "" " " "  " ""  " " ""  "" " ou egal
JNL	branchement si non inferieur arithmetiquement
JNLE	branchaement si arithmetiquement non inferieur ou egale
JNO	branchement si l'indicateur OF est a 0
JNP	branchement si parité impaire (indicateur PF a 0)
JNS	branchement si positif
JNZ	branchement si different
JO	branchement si OF est a 1
JP	branchement si parité pair. indicateur PF est a 1
JPE	" " " " " " " " " " " " " " " " " " " " " " " " " 
JPO	" " " "" " " " " "  " "impair. " " " " " "" " " 0
JS	branchement si negatif
JZ	branchement en cas d'egalité
LAHF	charge en AH la partie basse du registre des indicateurs
LAR	charge le drout d'acces (mode protegée)
LDS	charge une adresse physique en DS: registre
LEA 	" " " " " " "" "  "effective
LEAVE	libere le cadre de pile, installer par entrée
LES	charge une adresse physique en ES: registre
LFS	" " " "" "  "" " "  " "" " " " FS: " '" "
LGDT	charge le registre de la table des descripteurs globaux (mode protégée)
LGS	charge une adresse physique en GS: registre
LIDT	charge le registre de la table des descripteurs d'interruption (MODE P)
LLDT	charge le registre de la table des descripteurs locaux
LMSW	" " "  le mot d'etat de la machine (mode protégée)
LOCK	verrouille le bus
LODS[b][w] charge AL/AX avec le contenu de DS:SI
LODSD	charge EAX avec le contenu de DS:SI
LOOP	branchament tant que CX #0
LOOPE	" " " "" " "  " ""  " " " "et ZF =1
LOOPNZ	" "  " " " " ""  "" "  " "" "  ""=0
LOOPZ	" " " " " " " "  " " ""  "" " "  =1
LSL	charge une limite de segment (mode protegée)
LSS	charge une adresse physique en SS: registre
LTR	charge le registre de tache (mode protégée)
MOV	tranfere une donnée
MOVS	transfere une chaine de caractere octet par octet ou mot pour mot de 
	DS:SI en ES:DI
MOVSD	transfere une chaine de caracteres double mot par double mot
MOVSX	tranfert avec extension de signe
MOVZX	tranfert avec une extension de 0
MUL	multiplication non signée
NEG 	negation par complement de 2
NOP	pas d'operation, voir utilisation de samsom pour ex:
NOT	operation logique NON complement a 1
OR	operation logique OU inclusif
OUT	transmets un octet ou mot a un periph
OUTS[b][w] transmets une chaine a un port
OUTSD	transmets un double mot a un port
POP	depile un mot
POPA	depile les registres
POPAD	depile tous les registres 32 bits
POPF	depile un mot et le tranfere vers le registre des indicateurs
POPFD	 " """ " DOUBLE MOT "" " " " " "" " " "" " " " " "" " " "  "" "  "" "  
	sur 32bits
PUSH:	empile une valeur
PUSHA	empile tous les registres
PUSHAD	" " " " " ""  " " ""  "" 32 bits
PUSHF	empile le registre des indicateurs
PUSHFD	empile le registre des indicateurs a 32bits
RCL	rotation a gauche a travers CF
RCR	rotation a droite a travers CF
REP[z][nz] prefixes de repetition
REP[e][ne] pour traiter les chaines de caractere en association  avec CX et 
	les indicateurs
RET[n][f] retour de sous programme
ROL	rotation a gauche
ROR	rotation a droite
SAHF	copie AH dans la partie basse du registre des indicateurs.
SAL	decalage a gauche avec introduction de 0
SAR	" " " "  " droite avec signe
SBB	soustraction non signée avec prise en compte de CF
SCAS[b][w] compare une chaine octet par octet ou mot par mot avec le contenu de 
	AL/AX
SCASD	compare une chaine double mot par double mot avec le contenu EAX
SETA	initialisation a 1 si CF et ZF sont a 0, sinon initialisation a 0
SETAE	" " " " " " " " " "  "" est a 0, sinon init. a 0
SETB	" " " " " " " " " " " " " " " 1, " " " " " " " " 
SETBE	"  " " " " " " " " " " CF ou ZF est a 1, sinon initialisation a 0
SETE	" " " " " " " " " " "  ZF est a 1, sinon init. a 0
SETG	" " " " " " " " " " " " " " " " 0 et SF=OF, sinon init. a 0
SETGE	 " " " " " " " " " " " SF=OF, sinon init. a 0
SETL	" " " " " " " " " " "  SF#OF, sinon init. a 0
SETLE	" " " " " " " " " " "  ZF est a 1 et SF#OF, sino init a 0
SETNA	" " " " " " " " " " "  CF ou ZF est a 1, init a 0
SETNAE	" " " " " " " " " " "  CF est a 1, sinon init. a 0
SETNB	" " ""  " " ""  ""  "" CF est a 0, sinon init a 0
SETNBE	" " " " " " " ""  " " "CF et ZF sont a 0, sinon, init. a 0
SETNE	" " " " " " " " " " "  ZF est a 0, sino init a 0
SETNG	" " " " " " " " " " " " " " " " 1 ou SF#OF, sinon init. a 0
SETNGE	" " " " " " ""  " " " "SF#OF, sinon init. a 0
SETNL	" " " " " " " " " " " "SF et OF sont egaux, sinon init. a 0
SETNLE	" " " " " " " " " " " "ZF est a 0 et SF=OF, sinon init a 0
SETNO	" " " " " " " " " " "  OF est a 0, sinon init a 0
SETNP   " " " " " " " " " " " "PF est a 0, " " " "" " " " 
SETNS	" " " " " " ""  " "" " SF " " " " " " "" " " " "" 
SETNZ	" " "" " " " "" " " " "ZF " " " ""  " "" " "  " "
SETO	" " " " " " " " ""  "  OF est a 1, "" " "" " " "" 
SETP	" " " " " " " " " " "  PF  " " " " " " " " " "" " 
SETPE	" " " " "" " " " " " "  " " " " " " ""  "" "  "" " 
SETPO	" " " " " " " " " " " " " " " " 0, " " " " " " "" "
SETS	" " " " " " " " " " " " SF est a 1, sinon " " " " " 
SETZ	" " " " " " " " "" " "  ZF " " " " " " " " ""  ""  "
SGDT	sauvegarde le registre de la table des descripteurs globaux(mode prot.)
SHL	voir SAL
SHLD	decalage double a gauche
SHR	decalage a droite avec introduction de 0
SHRD	decalage double a droite
SIDT	sauvegarde le registre de la table des interruptions. (mode protégée)
SLDT	" " " " " " " " " " " " " " " " " " "" descripteurs locaux (mode P)
SMSW	sauvegarde le mot d'etat de la machine (mode P)
STC	mets a 1 l'indicateur CF
STD	" " " " ""  ""  " " " DF
STI	" " " " "  " " "" "  "IF
STIOS[b][w] transfert octet par octet, mot par mot le contenu de AL en ES:DI
STOSD	transfert double mot par double mot le contenu de EAX en ES:DI
STR	sauvegarde le registre de tache (mode Protégée)
SUB	soustraction non signée
TEST	test si un bit est a 1
VERR	test l'autorisation de lecture d'un segment (mode prot‚g‚e)
VERW	test l'autorisation d'ecriture dans un segment (mode prot‚g‚e)
XADD	addition signée
WAIT	attends que la ligne BUSY ne soit plus actif
XBINVD	efface le contenu de la memoire cache du 486
XBTS	prends une chaine de bits (mode protégée)
XCHG 	echange les contenus de 2 registres
XLAT	charge en AL l'octet de la table DS:BX+AL
XOR	operation logique ou exclusive


Les instructions conditionnelles

Nous abordons une partie qui est nécessaire lors de la création d'un programme. Souvent, le programme doit faire une action selon la valeur d'un résultat. Les instructions conditionnelles comme leur nom l'indique, sont des instructions qui font une action selon un résultat. Elles se basent sur les flags pour faire leur choix. Vous vous souvenez de l'instruction JMP, il s'agissait d'un simple saut vers une autre partie du programme. D'autres instructions comme JMP font des sauts mais selon certains critères, on les appelle des sauts conditionnels. Voici la liste des ces instructions avec la valeur de l'indicateur nécessaire à l'exécution.

JB - JNAE - JC
Below - Not Above or Equal - Carry
CF = 1

JAE - JNB - JNC
Above or Equal - Not Below - Not Carry
CF=0

JE - JZ
Equal - Zero
ZF=1

JNE - JNZ
Not Equal - Not Zero
ZF=0

JO - JNO
Overflow - Not Overflow
OF=1 - OF=0

JP - JPE
Parity - Parity Even
PF=1

JNP - JPO
No Parity - Parity Odd
PF=0

JS - JNS
Signed - Not Signed
SF=1 - SF=0

JA - JNBE
Above - Not Below or Equal
CF=0 et ZF=0

JBE - JNA
Below or Equal - Not Above
CF=1 ou ZF=1

JG - JNLE
Greater - Not Less or Equal
ZF=0 et SF=OF

JGE - JNL
Greater or Equal - Not Less
SF=OF

JL - JNGE
Less - Not Greater or Equal
SF (signé)=OF

JLE - JNG
Less or Equal - Not Greater
ZF=1 ou SF (signé)=OF

Pour tester tout cela, nous avons besoin d'une instruction, c'est CMP qui nous aidera à le faire.

L'instruction CMP

Cette instruction va nous servir à tester différentes valeurs et modifier les flags en fonction du résultat. CMP est un SUB qui ne change ni la source ni la destination, seulement les flags. Un CMP BX,CX sera comme un SUB BX,CX à l'excéption près que BX ne sera pas modifié. Si BX=CX alors BX-CX=0 donc le flag ZF sera égal à 1. Si nous voulons faire un saut avec "égal à" (JNE ou JZ qui demande ZF=1), nous avons ZF=1 et comme JZ demande que ZF=1 pour faire le saut, nous avons donc le saut. Souvenez-vous simplement que la plupart du temps, il s'agit de comparaisons du genre :

effectue le saut :
plus grand que (nombres non-signés) ---> JA 
plus petit que (nombres non-signés) ---> JB 
plus grand que (nombres signés) -------> JG
plus petit que (nombres signés) -------> JL
égal à (signé et non-signé) -----------> JE ou parfois JZ

il suffit de rajouter un 'n' après le 'j' pour avoir la même instruction mais exprimée de facon négative
ne saute pas si :
plus grand que (nombres non-signés) ---> JNA (jump if _not above_) ...et ainsi de suite.

Les registres

Vous vous souvenez de eax, c'est un des registres. Les registres sont des sortes de variables, mais au niveau du processeur, ils servent principalement à utiliser et à gérer la mémoire (ram ou rom). Les registres sont au nombre de 16, 8 registres généraux, 6 registres de segment, un registre IP et un registre de Flags. Chacun ayant une fonction particulière. Ils servent à manipuler des données, à transférer des paramètres lors de l'appel de fonctions et à stocker des résultats intermédiaires. Voici une petite doc tirée de "Résumer et Théorie sur l'Assembler par TeeJi - Release 24/07/99 - ":

Les Registres Généraux. Il y a 8 Registres Généraux. Chacun ayant une fonction particulière. Ils servent à manipuler des données, à transférer des paramètres lors de l'appel de fonctions Dos/Win et à stocker des résultats intermédiaires.

  
|      EAX      | 32 Bits   Accumulateur 
--------|  AX   | 16 Bits 
        | AH| AL|  8 Bits 
================= 
|      EBX      | 32 Bits   Base 
--------|  BX   | 16 Bits 
        | BH| BL|  8 Bits 
================= 
|      ECX      | 32 Bits   Compteur 
--------|  CX   | 16 Bits 
        | CH| CL|  8 Bits 
================= 
|      EDX      | 32 Bits   Données 
--------|  DX   | 16 Bits 
        | DH| DL|  8 Bits 
================= 
|      ESI      | 32 Bits   Index de Source 
--------|  SI   | 16 Bits 
================= 
|      EDI      | 32 Bits   Index de Destination 
--------|  DI   | 16 Bits 
================= 
|      ESP      | 32 Bits   Pointeur de Pile 
--------|  SP   | 16 Bits 
================= 
|      EBP      | 32 Bits   Pointeur de Base 
--------|  BP   | 16 Bits

Une petite explication s'impose, si nous prenons EAX, c'est un registre de 32 Bits (Extended AX). AX étant les 16 bits de poids faible et AX est lui même divisé en 2 partie, les 8 Bits de poids fort étant AH ( H pour High ) et les 8 Bits de poids faible AL ( L pour Low ). Si vous modifiez une partie de EAX ( AX ou AL ou AH ) EAX est modifié. Si vous modifiez une partie de AX ( AH ou AL ), AX est modifié et si vous modifiez AL, AH reste le même et inversément. Donc, seul AH et AL sont indépendant !

Les Registres de Segments

Ils sont utilisé pour stocker l'adresse de début d'un segment. Il peut s'agir de l'adresse du début des instructions d'un programme, du début des données ou du début de la pile.

CS : Segment de Code ( Code Segment ) Ce registre indique l'adresse du début des instructions
d'un programme ou d'une sous-routine.
DS : Segment de Donnée ( Data Segment ) Ce registre contient l'adresse du début des données de
vos programmes. Si votre programme utilise plusieurs segments de donnée, cette valeur devra
être modifiée durant son exécution.
ES : Extra Segment Ce registre est utilisé, par défaut, par certaines instructions de copie de
bloc. En dehors de ces instructions, le programmeur est libre de l'utiliser comme il
l'entend.
SS : Segment de Pile ( Stack Segment ) Il pointe sur une zone appelée la pile.
FS : Segment supplémentaire
GS : Segment supplémentaire Ces deux registres ont un rôle fort similaire à celui du segment ES.

Le Registre IP ( Instruction Pointer )
C'est ce registre qui contient le déplacement à effectuer par rapport au segment CS pour se positionner sur la prochaine instruction à éxécuter. Il ne faut jamais se soucier de ce registre ! Il est entièrement géré par le processeur. Remarque, la plupart ont été doté d'une extension à 32 Bits et sont donc précédé aujourd'hui d'un E ( AX --> EAX / IP --> EIP / etc.. )

Le Registre de Flag

Le registre de flag est un registre de 16 Bits, dont chacun des bits est un indicateur qui est positionné donc, soit sur 1 soit sur 0 ! Chaque Bits à un nom. Voici une liste en commencant par le bit de poids le plus faible :

CF : Carry Flag ( retenue )
PF : Parity Flag ( parité )
AF : Auxiliary Flag ( retenue auxiliaire )
ZF : Zero Flag ( zéro )
SF : Sign Flag ( signe )
TF : Trop Flag ( exécution pas à pas )
IF : Interrupt Flag ( interruption )
DF : Direction Flag ( direction )
OF : Overflow Flag ( débordement )
IOPL : Inpuut/Output Privilege Level ( il prend 2 bits ! )
NT : Nested Task Flag

0 NT IOPL OP DF IF TF SF ZF 0 AF 0 PF 1 CF

Les Flags d'état ( CF, PF, AF, ZF, SF et OF ) sont modifiés par les instructions arithmétiques, logique et des instructions de comparaison. Les instructions de Jump Conditionnel par exemple, testent l'état des ces Flags en vue d'effectuer ou non leur Jump. Les Flags de contrôle ( TF, IF, DF ) donnent des indications au processeur concernant l'exécution du programme. Ils peuvent être activés ou désactivés par le programme en cours.

Exemple

Voici à présent Code.exe : Programme très simple permettant d'apprendre à cracker. A la base, quand on tape 1, le programme écrit "Bon code" et pour tout le reste, il écrit "Mauvais code".
Amusons nous avec un debugger, dans cet exemple, j'utilise Turbo Debugger pour DOS. Je repère, assez rapidement dans le programme une comparaison :

  cs:005B 9A91028560     call   6085:0291
  cs:0060 803E520001     cmp    byte ptr [0052],01   /// ici, comparaison
  cs:0065 751E           jne    0085  ////ici, saut si faux
  cs:0067 BF5401         mov    di,0154
  cs:006A 1E             push   ds

Jne : cette instruction sert à aller à un emplacement quand la valeur est fausse, son code hexadécimal est 75
Je : cette instruction sert à aller à un emplacement quand la valeur est correcte, son code hexadécimal est 74.
Jmp : cette instruction est à aller à un emplacement dans tous les cas, son code hexadécimal est EB.

Il faut donc remplacer 75 (Jne) par 74(Je), ce qui donnera :

  cs:005B 9A91028560     call   6085:0291
  cs:0060 803E520001     cmp    byte ptr [0052],01
  cs:0065 741E           je    0085
  cs:0067 BF5401         mov    di,0154
  cs:006A 1E             push   ds

avec un éditeur hexadécimal, on cherchera donc :
80 3E 52 00 01 75 1E BF 54 01 et on remplace par
-- -- -- -- -- 74 -- -- -- --

Maintenant, quand on tape 2, le programme ‚écrira Bon code et quand on tape 1, le programme écrit : Mauvais code. Approfondissons un peu, le programme doit écrire "Bon code", que l'on tape 1 ou n'importe quel autre nombre.
Je vais vous montrer une erreur à éviter mais qui nous en apprend :
"Si on remplace jne 0085 par jmp 0085, comme ça, il saute tout de suite sur 0085"

  cs:005B 9A91028560     call   6085:0291
  cs:0060 803E520001     cmp    byte ptr [0052],01
  cs:0065 EB1E           jmp    0085   ////---- ici
  cs:0067 BF5401         mov    di,0154
  cs:006A 1E             push   ds
avec un éditeur hexadécimal, on cherchera donc :
80 3E 52 00 01 74 1E BF 54 01  et on remplace par
-- -- -- -- -- EB -- -- -- --

mais maintenant, tout est mauvais, quoi que l'on tape, eh ben, on réfléchit : "Si le code est faux (Jne), il va à l'emplacement 0085, ça veux dire que si il est juste, il ne lit pas cette instruction et continue à lire la suite du programme"
On dira alors au programme de sauter à l'instruction juste après : 0067

  cs:005B 9A91028560     call   6085:0291
  cs:0060 803E520001     cmp    byte ptr [0052],01
  cs:0065 EB00           jmp    0067
  cs:0067 BF5401         mov    di,0154
  cs:006A 1E             push   ds

avec un éditeur hexadécimal, on cherchera donc :
80 3E 52 00 01 EB 1E BF 54 01 et on remplace par
-- -- -- -- -- -- 00 -- -- --

Eh voilà le travail, maintenant, le programme écrit "Bon code", quoi qu'il arrive. Amusez vous bien.

Sources de l'article


 

Forum
Forum d'entraide
Blog
Le blog
News
Les news du site
Php/Mysql
Formulaire en php
Administrer un serveur Mysql
Session en php
Gerer ses bases mysql
Les bases php
Securiser ses scripts PHP
Controler ses programmes avec RATS
Convertir une base sql en utf8
Astuces php
Programmation
Python rapide
Tutorial Python
Tutorial Perl
Tutorial Perl complet
Tutoriel ruby
Tutoriel C
Introduction à gawk
Filtres et utilitaires
Find
Programmation Shell
Ecriture de scripts bash
Expressions regulieres
Vi
Introduction a Javascript
Compiler avec gcc
Astuces en Bash
Cracking
Tutoriel Assembleur
Guide du cracking pour débutant
Assembleur
Manual Unpacking
Techniques de Protection
Différentes failles Web
Arp spoofing dans un réseau switché
Les intrusions
Les attaques externes
Defacage
Defacage complet
Buffer overflow
Netcat
Injection sql
Injection sql(suite)
John the Ripper
Spoofer un email
Utiliser google
La faille system
Usurper une identité
Le rooting
Shellcode sous Unix
La faille race condition
La faille xss
La faille xss (2)
Attaques sur un routeur
P2P
Azureus pas-a-pas
News
Lire les news de Linux-pour-lesnuls.com au format RSS
Distros
Gestion des paquets debian
101 commandes debian
Graphisme
Effet neon dans GIMP
Effet vapeur dans GIMP
Cours fonctionnalités de GIMP
Humour
Ensemble
Divers