Protection   UPX   Les Protections Renforcées
Outils   ProcDump Wdasm SoftIce    
Cible   NotePad  

By TeeJi

Ultimate Packer eXecutable

Outils Utilisés

    Pour mon étude, j'ai utilisé

  • UPX 0.84
  • Notepad.exe et Calc.exe fournis en standard avec Windows. ( Version fournie avec Windows 95 OSR 2. )
  • ProcDump v1.5 build 0
  • Hview 6.15
  • et Windows ( vous allez bientôt comprendre pourquoi )

Première et unique approche.

    Ma première approche fut de comparer les PE Header ( et donc les différentes sections ) avant et après avoir compressé avec UPX. Je compresse donc une copie ( comme cela je garde toujours une version PROPRE de Notepad.exe ) de Notepad.exe et voilà les différentes informations que WDasm nous fourni : 

Disassembly of File: Notepad.exe 
Code Offset = 00000400, Code Size = 00003A00 
Data Offset = 00003E00, Data Size = 00000400
Number of Objects = 0006 (dec), Imagebase = 00400000h
Object01: .text    RVA: 00001000 Offset: 00000400 Size: 00003A00 Flags: 60000020 
Object02: .bss     RVA: 00005000 Offset: 00000000 Size: 00000000 Flags: C0000080 
Object03: .data    RVA: 00006000 Offset: 00003E00 Size: 00000400 Flags: C0000040 
Object04: .idata   RVA: 00007000 Offset: 00004200 Size: 00000E00 Flags: 40000040 
Object05: .rsrc    RVA: 00008000 Offset: 00005000 Size: 00003200 Flags: 40000040 
Object06: .reloc   RVA: 0000C000 Offset: 00008200 Size: 00000A00 Flags: 42000040


Et voici maintenant les détails après le passage de UPX :  

Disassembly of File: notepad.exe 
Code Offset = 00000200, Code Size = 00000000 
Data Offset = 00000200, Data Size = 00000000
Number of Objects = 0003 (dec), Imagebase = 00400000h
Object01: UPX0  RVA:00001000 Offset:00000200 Size:00000000 Flags:E0000080 VSize:00009000 
Object02: UPX1  RVA:0000A000 Offset:00000200 Size:00003400 Flags:E0000040 VSize:00004000 
Object03: .rsrc RVA:0000E000 Offset:00003600 Size:00001000 Flags:C0000040 VSize:00001000

    Là, on voit directement ce qui à changé, toutes les sections sont rassemblées dans 2 sections nommées .UPX0 et .UPX1 à part la section .rsrc qui n'a subit qu'une simple compression.
 
 

Avant compression

Après compression

Entry Point

00001000

0000D130

Image Base

00400000

00400000

    Je regarde maintenant ce que WDasm veut bien me donner et on s'apercois alors qu'il n'y a pas de protection anti-disasm ou de modification des flags des sections pour pouvoir voir le dead-listing du loader. Je jette un rapide petit coups d'oeil à la recherche de choses intéressantes et je vois ceci, comme dernière instruction de la section :  

:0040D2AC 61                      popad 
:0040D2AD E94E3DFFFF              jmp 00401000 
:0040D2B2 00000000000000000000    BYTE 10 DUP(0) 
... 
:0040D3FC 0000000000000000DE95    BYTE 10 DUP(0)

    Je me suis donc dis que je rêvais, et après m'être frappé et m'être fait très mal, j'ai du me rendre à l'évidence, il y a un jump ou plutot LE jump vers notre EP du programme d'origine écris en clair et net à la fin de la section contenant le loader !! Juste après cette instruction on aperçois une floppée de 00 qui nous servira dans le meilleurs des cas à inscrire notre patch. Mais j'ai pu remarqué qu'il y avait un FF qui venait se mettre directement apres le jump. Il faudra donc rajouter notre patch un petit peu après le jump, pas juste après !

    Je vérifie les données que j'ai pu récupérer en compressant Calc.exe ( le calc.exe original à son EP = 0040534E ): 

:004130CC 61                      popad 
:004130CD E97C22FFFF              jmp 0040534E 
:004130D2 00000000000000000000    BYTE 10 DUP(0) 
... 
:004131FE 00000000000068C16A01    BYTE 10 DUP(0)

    Donc c'est fort semblable, et nous avons dès maintenant tous ce qui nous faut pour faire notre patch.

    Afin de vérifier tout ce que j'ai dit, j'ai fait un patch pour notepad qui enlève l'acces à l'aide. Ceci n'a rien
d'extraordinaire, j'ai juste noppé le call WinHelpA. J'ai inséré mon patch en 0040D2B6 et modifié le jmp 401000 en 40D294
pour qu'il jump sur mon patch en 0040D2B2 et j'ai rajouter un jmp 401000 à la fin de mon patch. Voici la preuve en image :  

.0040D2AC: 61                           popad 
.0040D2AD: EB07                         jmps     .00040D2B6 
.0040D2AF: 3DFFFF0000                   cmp       eax,00000FFFF 
.0040D2B4: 0000                         add       [eax],al 
.0040D2B6: C7052C12400090909090         mov       d,[00040122C],090909090 
.0040D2C0: 66C705301240009090           mov       w,[000401230],09090 
.0040D2C9: E9323DFFFF                   jmp       0FFFF7200 
.0040D2CE: 0000                         add       [eax],al  

  Rem : Pour connaître le code hexa à mettre pour les instructions jump, il vaut mieux le faire sous Softice avec la command A, puis noter les codes hexa qu'il donne et ensuite le modifier sous hviw car ce dernier a beaucoups de mal avec les jumps dès qu'il saute un peu loin !
 

Résumé et conclusions

    Résumons-nous maintenant :

  • Pour détecter que la compression est UPX, il suffit de regarder le nom des deux premières sections nommées UPX0 et UPX1.
  • Pour insérer notre patch, nous avons généralement de la place en fin de la section .UPX1. Généralement vous y trouverez plusieurs centaines de bytes libre.


   Conclusions :
 

  • Dommage que ce soit si simple :) 

Amicalement,
TeeJi
teejee@hotmail.com