Stats

  • Total des pages vues: 4755
  • Pages vues aujourd'hui: 262
  • Visiteurs connectés: 1
  • Nombre de visiteurs: 2720

Contourner les protections anti-désassembleurs

Written by aaSSfxxx - 04 december 2011

Dans le monde du reverse-engineering, c'est-à-dire l'art d'analyser le fonctionnement d'un binaire dans notre cas, on peut trouver des protections différentes, allant du chiffrage du programme (ou de sa compression) à la détection de débuggeurs (outils servant à contrôler le flux d'exécution d'un programme, l'arrêter à certains endroits). Une autre technique, qui sera celle montrée ici est le fait de rendre les désassembleurs incapables de retrouver le code assembleur d'un binaire.

Nous allons donc voir ici comment analyser ce genre de programmes, et comment contourner cette protection à travers un exemple simple pour commencer.

Prérequis:

Savoir manier un éditeur hexadécimal, connaître les instructions assembleur de base, avoir quelques notions en cracking/reverse-engineering.

Premier contact avec le crackme

Tout d'abord, vous pouvez télécharger le crackme à cette adresse: http://repos.aassfxxx.infos.sr/misc/crackme/demo . Une fois ceci fait, nous allons prendre notre désassembleur favori (IDA Pro dans mon cas, mais objdump fait aussi l'affaire). Lorsqu'on essaie de l'exécuter, le crackme nous accueille avec un gentil message "Essaie encore :þ", ce qui montre que le crackme fonctionne. Un "file" sur le crackme nous indique qu'il est stripped, c'est-à-dire que tous les symboles de débuggage ont été retirés du binaire. Ainsi, le désassembleur va nous diriger sur _start (le "vrai" point d'entrée du programme, et non main, appelé par _start).

On désassemble donc notre programme, comme on ferait pour n'importe quel autre crackme. Il va donc falloir retrouver notre "main", étant donné que le désassembleur n'a pas pu le localiser. On s'aperçoit qu'il y a un "push offset sub_8048495" avant un "call __libc_start_main", ce qui nous indique que notre "main" est à l'adresse 0x08048495. Lorsqu'on désassemble ce "main", on s'aperçoit qu'il y a plein de code qui n'a a priori aucun sens (ou pire dans le cas d'IDA, une suite de dwords incompréhensibles lorsqu'on est en "Text View"). Nous allons donc voir ici comment pallier ce problème.

Analyse statique du binaire

On va ici se servir du désassembleur pour comprendre comment le processeur arrive à exécuter cette bouillie d'instructions sans broncher. Tout d'abord, on commence par trouver le "main" (dans notre cas à 0x08048495). Si vous ne trouvez rien à cette adresse (mais que les chiffres à la fin sont proches), c'est qu'il y a déjà des protections contre le désassemblage (et une analyse dynamique conviendra mieux pour ce cas). Ce n'est pas le cas dans ce crackme. On va donc analyser les premières instructions du programme:

Code ASM :
  1. push    ebp
  2. mov     ebp, esp
  3. mov     eax, offset dword_80484A4
  4. mov     edx, 2
  5. jmp     short loc_8048516

On aperçoit ici le prologue habituel ("push ebp" et "mov ebp,esp"), l'initialisation de deux registres puis un saut vers 0x8048516. Regardons donc cette fonction:

Code ASM :
  1. add     eax, edx
  2. xor     edx, edx
  3. mov     edx, eax
  4. sub     edx, offset dword_80484A4
  5. add     eax, edx
  6. jmp     eax

La première chose qui nous frappe, c'est ce "jmp eax" : on sait que notre programme va aller sauter à la valeur contenue dans eax. Or, eax est initialisé avec "0x080484A4" qui ressemble curieusement à une adresse de fonction et qu'on retrouve dans notre désassemblage (là où le code est devenu incohérent).

Le programme ajoute aussi edx à la valeur d'eax, or edx vaut 2. On a donc, eax = 0x080484A4 + 2. Ensuite, on met eax dans edx, puis on retranche la valeur de la "fonction" à edx, qui est du coup égal à 2. On ajoute encore edx (donc 2) à eax, avant de jmp à la valeur contenue dans eax. On a donc 4 octets de décalage entre la fonction annoncée et la fonction "réelle" qui contient n'importe quoi, ce qui embrouille le désassembleur. On va donc nopper ces 4 octets afin de redonner du sens à notre code (je supposerai ici que vous savez localiser et éditer des octets dans un binaire). Sous IDA, il suffira juste de se placer 4 octets après "0x080484A4" et de presser "C", ce qui demandera à IDA d'analyser le code.

Nous avons affaire à une deuxième protection anti-désassembleur un peu plus loin dans le code, que je vous laisserai éliminer (le code est plus basique). Une fois ceci fait, on remarque que le bon serial est "T4pZN355" (avec un peu d'habitude :þ).

Conclusion

Nous avons vu ici comment contourner une protection "basique", et le programme analysé est bien évidemment élémentaire. Cependant, ce genre de procédés est aussi couplé avec d'autres techniques telles que les anti-débuggeurs ou la compression du code, ce qui rend l'analyse plus difficile.

J'espère malgré tout que cet article vous aura ouvert de nouvelles possibilités, et qui sait, trouver une méthode pour résoudre un problème plus délicat.

That's all folks !

Classified in : Hacking & Programming - Tags : none

tuesday 21 february 2012 @ 22:43 Fou1nard said : #1

Avatar GravatarMerci beaucoup pour cet article aaSSfxxx. Quelque chose me dit que, comme moi, c'est un CrackMe Zenkien qui t'as poussé à t'intéresser à ce problème.

wednesday 22 february 2012 @ 13:00 aaSSfxxx said : #2

Avatar Gravatar@Fou1nard : Non, c'est plus un crackme sur root-me qui m'a fait pensé à ça :þ (la protection pour le crackme zenkien est assez "élémentaire")

thursday 01 march 2012 @ 22:59 Fou1nard said : #3

Avatar GravatarHa d'accord.

Va falloir que tu m'expliques un peu cette protection pour le CrackMe Zenkien.

Comments are closed.