Cours n°6 - Introduction aux packers

 

  Ce dont vous avez besoin : Olly, PEID, LordPE, ImpREC et le crackme  : UnPackMe1

  

  Avant de commencer l'analyse du logiciel, je vais tenter de vous expliquer brièvement ce que sont les packers.

  Ce sont des logiciels qui permettent de modifier un exécutable donné afin de le compresser et/ou le protéger contre le débugguage, le dump,... Ce n'est en fait qu'une protection rajoutée sur le programme originel. En gros, le principe est une sorte d'encapsulation: le programme en mémoire est exactement pareil qu'auparavant, il n'y a que la routine de "décryptage" (le loader) qui est ajouté au démarrage. Ce qui veut dire que dans la plupart des cas (il n'y a pas de standard en la matière), une fois que l'on a trouvé l'OEP (original entry point, le point d'entée du programme avant qu'il ne soit packé), le programme est tel qu'à son origine.

 C'est là qu'arrive le dump. Cela consiste à faire une copie du programme en mémoire dans un fichier.

 Mais le fichier ainsi obtenu n'est toujours pas fonctionnel, pour pouvoir le rendre fonctionnel, il faut reconstruire l'IAT. Sans rentrer dans les détails (ma connaissance n'est pas assez poussée et de toute façon ce n'est pas le but ici), l'IAT comporte 2 tableaux dans lesquels sont repris les dll utilisées ainsi que les adresses en mémoire des fonctions (APIs) quelles proposent. L' IAT de l'exécutable sur le disque n'est pas le même qu'en mémoire. Sur le disque, un des 2 tableaux contient le nom des fonctions, lorsque le loader du système d'exploitation charge le programme en mémoire, il remplace ces noms par les adresses en mémoire des fonctions correspondantes. Donc l'IAT recopié tel quel de la mémoire n'est plus valide. Il faut donc le reconstruire.

  Mais ne vous tracassez pas de tout ce bla bla,  c'est beaucoup plus simple que ça en a l'air ;).

  Je ne vais pas ici analyser le packer, je vais seulement décrire les étapes pour arriver à obtenir un programme décompressé et fonctionnel à partir d'un programme compressé avec UPX.

     

 

Analyse du logiciel

  PEID nous indique "UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo". UPX n'est pas, à proprement parler, une réelle protection, c'est un packer qui permet de compresser notre programme. Il est toutefois très simple à unpacker et convient donc bien pour une introduction aux packers.

 

Observation

  Vous remarquerez qu'en exécutant le logiciel normalement vous ne voyez aucune différence par rapport à un programme "normal".

   Le but de ce cours n'étant pas de cracker ce logiciel, on ne se tracassera pas d'observer ce que fait le programme.

 

Analyse du code

     La plupart des packers (comme des compilateurs d'ailleurs), ont une signature, c'est à dire une suite d'instructions/octets, une particularité,... qui permet de les distinguer.

  Celle d'UPX se caractérise par des sections se nommant UPX1, UPX2,... et un pushad, popad de part et d'autre du loader (la routine qui va "décrypter/décompresser" le programme) :

Recherche de l'OEP

  Le packer ne doit rien modifier, le programme original doit retrouver les registres dans l'état tel qu'ils étaient au démarrage du loader. C'est à ca que sert pushad et popad. PUSHAD pousse tous les registres dans la pile et POPAD les restaure tous.

  Après avoir décrypté/décompressé, le loader doit donner la main au programme originel pour qu'il s'exécute comme il l'aurait fait auparavant.

  Ici c'est le JMP 401120 (retenez cette valeur) juste en dessous du POPAD qui fait cela.

  La méthode générale pour trouver l'OEP d'un programme (avec des protections de bas niveau) est de regarder l'EOP d'un programme non protégé puis de protéger ce même programme par le packer que l'on souhaite analyser. Ensuite, on exécute le programme en pas à pas et on regarde quand on arrive à l'OEP qu'on avait retenu les étapes que l'on vient de passer. L'OEP revient souvent après les mêmes instructions pour un certain packer et il suffit de retrouver ces instructions dans un autre programme protégé par le même packer pour arriver à trouver l'OEP de cet autre programme.

  Pour UPX c'est très simple, c'est :

  POPAD

  JMP OEP

DUMP

  Maintenant que l'on a trouvé notre OEP, il faut dumper le programme décompressé en mémoire dans un fichier.

  Je vous rappelle que le packer doit être invisible pour l'exécutable, donc une fois arrivé à l'OEP, le programme est sensé être comme il l'était avant d'être compressé.

  Nous allons donc poser un BP sur le JMP OEP (en 41769F dans notre exemple). Une fois ceci fait, appuyez sur F9. Lorsqu' Olly breakera, le programme sera décompressé.

  Laissez bien le programme en pause et prenez LordPE.

  Dans la liste des processus actifs, cherchez l'UnPackMe. Une fois que vous l'aurez trouvé, faites un clic droit dessus et sélectionnez "Dump full...", enregistrez maintenant votre programme dumpé.

  Si vous tentez de l'exécuter, vous aurez un beau message d'erreur. Et oui, l'IAT dont je vous ai parlé tantôt n'est toujours pas reconstruite.

  Avant de lancer ImpRec pour reconstruire l'IAT, on va changer l'EP de notre exécutable dumpé. En effet, l'EP pointe sur le début du loader mais vu que notre programme est décompressé, nous n'avons plus besoin du loader.

  Dans LordPE, cliquez sur "PE Editor" et sélectionnez le fichier dumpé. Dans la case "Entry point", remplacez la valeur existante

  par celle que je vous ai di de retenir ici plus haut (l'OEP, à savoir 401120 - ImageBase => 1120). Cliquez ensuite sur Save, puis OK et fermez LordPE.

 

Reconstruction de l'IAT

  Attaquons-nous maintenant à la reconstruction de l'IAT.

  Pour cela, prenez ImpREC. Si vous n'avez pas fermé l'UnPackMe depuis tantôt il n'y a pas de problèmes, sinon relancez-le. Attention, il doit être décompressé sinon ça ne fonctionne pas.

  1) Dans la liste des processus actifs, sélectionnez l'UnPackMe.

  2) Changez la valeur de l'Entry Point par l'OEP (1120)

  3) Cliquez sur "IAT autosearch", logiquement une messagebox s'affiche pour vous indiquer quelle a trouvé quelque chose.

  4) Cliquez sur Get Imports. La liste va se remplir avec les APIs utilisées par le programme.

  5) Cliquez sur "Fix Dump", sélectionnez le fichier dumpé et logiquement si vous ne vous êtes pas trompé et que j'ai bien expliqué, vous avez un bel exécutable "PackerFree". L'exécutable n'est pas à 100% égal au fichier original mais le code est exactement pareil.

    L'avantage de dumper un fichier est que lorsque vous le chargez dans Olly, vous voyez directement le code de l'exécutable et non le loader et , de plus, si vous patcher le fichier, vous pourrez enregistrer les modifications sans problèmes.

   Seulement, si vous essayez de charger votre exécutable dumpé dans Olly, il va se lancer sans breaker sur l'EP. Ceci est du au fait que les sections ne sont plus alignées.

  Pour corriger ce problème, relancez LordPE, cliquez sur PE Editor et sélectionnez votre exécutable dumpé.

  Cliquez sur "sections" et regardez par rapport au VOffset dans quelle section doit se trouver l'EP.

  L'EP se trouve donc dans la section UPX0 (qui correspondait probablement au .text avant d'être compressée par UPX) puisque sa valeur est 1120 et que la section UPX0 va de [1000 à F000[

  Fermez cette fenêtre et dans le fenêtre précédente, remplacez la valeur de BaseOfCode par le VOffset du début de la section dans laquelle se trouve l'EP, donc 1000.

  Cliquez sur Save puis quittez LordPE.

  Maintenant votre exécutable est pleinement fonctionnel.

  Pour vous entraîner, vous pouvez vous amuser à essayer de trouver un serial valide pour votre nom ;). Envoyez-moi vos réponses.

 

Bon crack,                  

Crisanar         

[ << Cours n°5 ] [ Cours n°7 >> ]

 

Dernière mise à jour le 21/10/2004 20:46