Adaptation des cours de "Deamon" à Ollydbg par "ga"

 

Cours n°1 

L'hexadécimal et les types de sauts



 

Comprendre l'hexadécimal 

Tout d'abord ouvrez un programme avec Ollydbg (si vous ne savez pas l'utiliser allez voir le cours précédent). Vous devez apercevoir des lignes semblables à celle-ci : 


Exemple : 

:0040100E

E839000000

Call 0040104C

:00401013

83F807

cmp eax, 00000007

:00401016

EB1A

jmp 00401032

:00401018

6A40

push 00000040


Le numéro en bleu est l'adresse de la ligne pour Ollydbg. 
Le nombre en blanc est l'instruction en hexadécimal correspondant aux instructions rouges. 
Les mots et nombres en rouge sont les instructions en assembleur du programme désassemblé. C'est en fait la "traduction" de l'instruction en hexadécimal en blanc. 
 


En décimal vous comptez comme ça (ou du moins je l'espère...) : 

    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ... 

Et bien en hexadécimal il y a non pas 10 chiffres mais 16 (les 10 du décimal + les 6 lettres A,B,C,D,E,F) on compte donc de cette manière : 

    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, ... 

Donc par exemple 15 en décimal s'écrira F en hexa, 16 => 10, 17 => 11, 26 => 1A, etc... 

Les adresses d'Ollydbg sont en hexadécimal et dans l'ordre croissant, mais il ne les met pas toutes comme on peut le voir dans l'exemple ci-dessus. C'est tout simplement car l'adresse correspond en fait non pas à l'instruction mais au premier octet de l'instruction (un octet est composé de 2 chiffres hexadécimal) donc par exemple à l'adresse 401016 "EB1A" comporte 2 octets ainsi l'instruction "6A40" aura pour adresse 401016+2 soit 401018. 



Qu'est-ce qu'un saut ? 

   Je vais en premier lieu vous montrer le schéma d'une protection utilisée la plupart du temps. Une fois le code rentré il le compare avec le bon code, si ce n’est pas le même il saute pour arriver vers le mauvais message sinon il affiche le bon message et continue sa route vers de nouvelles aventures en passant au dessus du mauvais message.

 

JNE est un saut conditionnel. Il saute si le code est faux dans ce cas là (saut si inégal)
 ou continue sa route si le code est bon. 
JMP ( = Jump = Saut) est aussi un saut mais inconditionnel puisqu'il saute obligatoirement, même au bord d'un précipice il sautera quand même :-P ...
 

Et ça donne à peu près ça en assembleur (les adresses sont fictives et je n'ai pas mis l'intégralité de ce passage comme notamment les instructions pour afficher les messages pour ne garder que le nécessaire) :
 

:00401001

####

Teste si le code est bon

:00401002

75##

JNE 00401032


Le JNE saute uniquement si le code n'est pas bon.

00401018  |> \# ###         PUSH 10                                  ; /Type = MB_OK|MB_ICONHAND|MB_DEFBUTTON1|MB_APPLMODAL

0040101A  |.  68 ########   PUSH OFFSET 00402298                     ; |Caption = "Bravo"

0040101F  |.  68 ########   PUSH OFFSET 004021C8                     ; |Text = "Le code est bon" 

00401024  |.  6A ##         PUSH 0                                   ; |hOwner = NULL

00401026  |.  E8 ########   CALL <JMP.&USER32.MessageBoxA>           ; \USER32.MessageBoxA

Ollydbg indique que
 "Le code est bon" est le message d'une boîte de dialogue. 

:00401004

EB##

JMP 00401045


Le JMP est un saut. Le numéro à sa droite est l'adresse où il va sauter.
 



En vous positionnant sur le  signe « > » 
une petite flèche apparait vous indiquant l’origine du saut.

00401032  |> \# ###         PUSH 10                                  ; /Type = MB_OK|MB_ICONHAND|MB_DEFBUTTON1|MB_APPLMODAL

00401034  |.  68 ########   PUSH OFFSET 0040228C                    ; |Caption = "Et non"

00401039  |.  68 ########   PUSH OFFSET 0040211E                     ; |Text = "Le code n’est pas bon" 

0040103E  |.  6A ##         PUSH 0                                   ; |hOwner = NULL

00401040  |.  E8 ########   CALL <JMP.&USER32.MessageBoxA>           ; \USER32.MessageBoxA


Après ces schémas, vous avez donc compris (du moins je l'espère) que c'est le
 JNE qu'il faut changer. Mais vous allez me dire : 


Comment change-t-on un saut conditionnel ? 

   Regardez le schéma en assembleur et plus précisément la ligne
 00401002 avec le JNE. Dans le code hexa, on voit 75##. Et bien le 75 c'est notre JNE. Tout comme le JMP qui correspond à EB. 

Voici une petite liste de sauts conditionnels que vous pourrez trouver le plus souvent :
 

Instruction

Valeur hexa

Description

JNE

75 ou 0F85

Saut si inégal

JE

74 ou 0F84

Saut si égal

JMP

EB ou E9

Saut

NOP

90

Pas d'opération


   Pour modifier un saut, il suffira donc de rechercher sa valeur et de la modifier avec l'éditeur hexadécimal. Par exemple pour le schéma ci-dessus on mettra un
 JE (il sautera à "Le code est bon" si le code est mauvais) ou NOP (il ne sautera pas du tout et ira donc directement vers "Le code est bon") à la place de JNE.

   Pour information les 75, 74, EB sont des sauts courts et 0F85, 0F84, E9 des sauts longs. Après les sauts courts on a le nombre (en hexa) d'octets sautés (un octet est un nombre de 2 chiffres qui va donc en hexa de 00 à FF comme peut l'être 75 ou 90) et donc pour les sauts de plus de FF (soit 255 en décimal) octets on utilise des sauts longs à la suite desquelles on met l'adresse de destination. Par exemple EB02 représente un saut (JMP) de 2 octets.

__________   ___   __________

 

Après la théorie place à la pratique, dans le cours n°2 nous essaierons de cracker un crack-me. 

 

<<< Retour au cours précédent
[Cours n°0 ]

 

Passer au cours suivant >>>
[ Cracker un crackme ]

 

Juin 2013