Sujet : Introduction au Reversing


Intro:

Le cracking est disons l'art de faire sauter les sécurités d'un programme afin de pouvoir l'utiliser librement et gratuitement.
Tandis que le reversing est l'art de modifier un programme afin de lui ajouter des fonctions ou bien d'optimiser certaines routines ou encore de détourner un programme pour d'autres applications que celles pour lequel il a été conçu ou pourquoi pas encore de le customiser selon nos désirs.
Bref, si le cracking n'exige pas de grandes connaissances en programmation et en assembleur, le reversing lui en requiert quelques bonnes bases.
Je vous invite donc à consulter les cours d'Iczelion sur la programmation en W32asm qui sont tout simplement les meilleurs.( www.w32asm.fr ).
Une bonne connaissance des API ainsi que du fonctionnement de Windows est aussi nécessaire, pour ça le mieux étant de vous mettre à la programmation.

Thème :

Pour cette introduction on va commencer par simple et rapide, le programme que nous allons reverser est le Bloc-Note de Windows celui-ci étant une très bonne base pour s'entraîner. Nous allons tout simplement ajouté à celui-ci un message qui s'affichera au lancement du prog. pour nous souhaiter la bienvenue.

Outils nécessaire :
- W32Dasm9x
- Hiew 6.xx

Plan d'attaque :

Voici le schéma que nous allons suivre pour la réalisation de ce projet :

- 1/ Chercher un endroit libre dans l'exécutable et y insérer notre code
- 2/ Trouver l'Entry-Point du programme
- 3/ Mettre un jump à l'Entry-Point pour sauter directement vers notre code et relever les instructions que notre jump écrasera
- 4/ A la fin de notre code mettre les instructions que nous avons écrasés et mettre un jump qui retourne au programme normal (après notre jump a l'entry point)

Ainsi notre programme au lancement sautera directement vers nos instructions qui afficheront une MessageBox ensuite le programme reprendra sont cours normal.

1/ Chercher un endroit libre dans l'exécutable et y insérer notre code

A l'aide d'un éditeur Hexadécimal ouvrez notepad.exe.
Les emplacement vides sont repérer par des 00, donc on cherche une parcelle de 00 suffisamment grande pour contenir quelques lignes de codes.
Pour cet exemple je me suis placé à l'offset D954
A cette adresse on va inscrire notre message de bienvenue, on se place dans la partie ascii de notre editeur et on tape Bienvenue Netix.
On se placera ensuite à l'offset D970 pour y mettre les instructions. Pour cela on va se servir Hiew qui nous permet d'écrire directement les instructions en assembleur plutot que d'encoder avec des valeurs Hexadécimales.

- On ouvre Hiew
-
on repère l'exécutable
- F4 puis Décode
- F5 puis l'adresse de notre code ( image base + offset ) 400000 + D970 => .40D970 ( pas oublier le . avant l'adresse )

Nous voulons afficher une MessageBox qui contiendra notre texte "Bienvenue Netix". Voici le prototype de l'API MessageBox :

int MessageBox(
HWND hWnd,
// handle of owner window
LPCTSTR lpText,
// address of text in message box
LPCTSTR lpCaption, //
address of title of message box
UINT uType //
style of message box
);

int désigne un entier qui recevra une valeur de retour de cette fonction pour déterminer quel bouton à été pressé pour cette MessageBox , pour cette exemple nous ne nous en serviront pas.
hWnd désigne le propriétaire de cette fenêtre ici nous mettrons 0 pour aucun
lpText est un pointeur qui contiendra l'adresse de notre message ( l offset de Bienvenue Netix )
lpCaption est un pointeur qui contiendra l'adresse de notre titre pour la MessageBox ( on mettra le même pour notre message )
uType est un entier qui détermine le type de notre MessageBox ( l'icône, quel type de boutons, etc...) ici on va mettre 0 pour obtenir une boite simple

Ces 4 valeurs sont les arguments de la fonction MessageBox , en assembleur pour passer les argument a une fonction on les pousse dans l'odre dans la pile juste avant le call de la fonction

push 0
push 40D954 // notre texte
push 40D954 // le titre de la boite de message
push 0 // le type de boite 0 = simple
call MessageBox // appelle la fonction

Maintenant nous allons repéré dans le programme la syntaxe en Hexadecimal du call pour une messagebox.
A l'aide de W32Dasm on recherche dans les Imports User32.MessageBoxA puis on clique dessus plusieurs fois , remarquez tout les call pour cette fonction ont la même syntaxe en hexadécimal on la note donc.

de retour sous Hiew a l'offset de notre code (.40d970) on fait :

- F3 pour passer en mode édition
- F2 pour passer en mode assembleur
- on entre donc nos instructions :
- push 0 (puis touche Entrer pour chaque instructions)
- push 40D954
- push 40D954
- push 0
- Touche Echap pour quitter le mode assembleur
- on entre la suite Hexadécimal pour notre call : FF15A8644000
- il nous reste plus qu'a mettre un jmp pour sauter au début normal du programme.

2/ Trouver l'Entry-Point du programme

Rien de plus simple.
Dans le menu de W32dasm faite GOTO puis GOTO PROGRAM ENTRY POINT. Vous arriver directement a l'adresse de celui-ci que l'on note.
Ici 4010CC

L'Entry-Point est l'adresse de la première instruction qui va s'effectuer lors du lancement du prog.

 

3/ Mettre un jump à l'Entry-Point pour sauter directement vers notre code

Tout d'abord on note les instructions qui vont êtres écrasés par notre jump nous les replaceront a la fin de notre code ce qui nous evitera le plantage .

Sous Hiew on fait :

Goto (adresse de l'Entry-Point (.4010CC)) on passe en mode assembleur et on tape jmp D970

D970 étant l'offset de la première instruction de notre code repéré a l'aide d'un éditeur Hexa.

 

4/ A la fin de notre code mettre un jump qui retourne juste après l'Entry-Point

Avant de retourné vers l'Entry-point on replace les instructions que notre jump a écrasé soit en Hexa :

55
8BEC
83EC44
56

ensuite en mode assembleur on place notre jump

jmp 10D3

10D3 est l'offset ou le programme reprend sa partie normale juste après notre jump a l'entry-point vers notre code.


Ce qui au final donne ceci :

 

Listing Original

 

 //******************** Program Entry Point ********

:004010CC 55                        push ebp                   |  ß La on placera notre jump

:004010CD 8BEC                  mov ebp, esp             |    Ces 4 instructions seront copié a la fin de notre

:004010CF 83EC44               sub esp, 00000044    |                        code

:004010D2 56                        push esi                      |

:004010D3 FF15E0634000   Call dword ptr [004063E0]  ß notre code reviendra par un jump ici

:004010D9 8BF0                   mov esi, eax

 

 

Listing Modifié vu sous Hiew

 //******************** Program Entry Point ********

:004010CC E99FC80000    jmp .40D970  ß Notre jump

:004010D1 44                      inc esp     |

:004010D2 56                      push esi   |   ces 2 instructions sont apparues suite au changement créer        

                                                               par notre jump mais on s’en fiche pas mal puisque qu’elles

                                                               ne seront jamais exécuter car notre après notre code un jump

                                                               reviendra juste après celles-ci.

 

:004010D3 FF15E0634000   Call GetCommandLine ;USER32.dll ß C’est Ici le retour de notre code

:004010D9 8BF0                    mov esi, eax

........

........

//********************* Notre Code *************

.0040D970 6A00                  push 00                |

.0040D972 6854D94000      push 0040D954   |   Les 4 paramètres sur la pile pour la message box

.0040D977 6854D94000      push 0040D954   |

.0040D97C 6A00                  push 00               |

.0040D97E FF15A8644000  Call  MessageBoxA ; User32.dll  ß appelle la MessageBox

.0040D984  55                       push ebp                   |

.0040D985  8BEC                 mov ebp, esp             |  Les 4 Instructions qu’il y avait a l’entry point

.0040D987  83EC44              sub esp, 00000044    |

.0040D98A  56                       push esi                     |

.0040D98B  E94337FFFF      jmp .4010D3      ß  On retourne au déroulement normal du prog.                  

 

PS: N'essayer pas de trouver votre code sous W32dasm , il n'y figurera pas du fait que les sections n'ont pas été modifié suite au rajout de notre code mais ceci
fait partis d'un prochain tutorial sur les sections et le PE-header