Les fichiers compactés : (suite et fin, pour l'instant...)

 

Résumé :

Le cours dernier nous avons vue comment utiliser les outils de bases et avont commencer à deplomber PE-Compact 1.40b1 ensemble, des nouvelles versions de ce progs sont sorti mais ce n'est q'un exemple, du plus il est inclus avec ce numéro de MemenTo ici.

Rappel sur ProcDump:

ProcDump est un programme qui affiche la liste des processus en mémoire et qui peut les sauvegardés. Il est possible aussi de les manipuler pour toutes sortes d'operations.

Suite du tutoriel :

Voilà, nous savons maintenant enlever un string de base, ici c'etait "Unregistered!". Maintenant nous allons attaquer les API. Les applications font appels à des fonctions API pour réaliser des tâches, comme créer, détruire des fenêtres, etc... ; accéder aux services du système, tel que l'affichage, clavier, souris, les messages entre Windows et les applications et beaucoup d'autres fonctions. Les fonctions API se trouvent dans différents fichiers, le plus souvent dans les Dynamic Link Libraries (DLL). Ici on va voir des API simple a choper.

Pour ce faire on va utiliser SoftIce (ok, tant pis pour ceux qui sont sous WinMe (pourri) et NT c'est pas trop fait pour craquer) et on va poser un point d'arret sur GetLocalTime, de cette façon on va cibler la limite de temps quand à la compression d'un fichier puisque le prog fait appel à l'horloge windows (avencer et reculer l'horloge d'un ans pour voir ;).

Un fois ce point posé on demarre le prog et on clique sur Compress. Là Sice va stopper sur l'API que l'on a bloquer et nouc renvoyer à ce code lorsque l'on appuis sur F12 pour passer le Kernel.

:0040526C 	66813D83A24000D007 		cmp word ptr [0040A283], 07D0
:00405275		750A 				jne 00405281
:00405277		66833D85A2400007 			cmp word ptr [0040A285], 0007
:0040527F 	761C 				jbe 0040529D
:00405281 	6A10 				push 00000010
:00405283 	6808B24000 			push 0040B208
:00405288 	6878A94000 			push 0040A978
:0040528D 	FF351CB94000 			push dword ptr [0040B91C]
:00405293 	E8ECF0FFFF 			call 00404384
:00405298 	E9B3010000 			jmp 00405450

Pour mieux faire le rapprochement on va ouvrir WinDasm et lancer une recherche sur 0040526C, là on va tomber ici :

:0040526C 	66813D83A24000D007 		cmp word ptr [0040A283], 07D0
:00405275 	750A 				jne 00405281 << Saute en pleins sur le push 0040B208
:00405277 	66833D85A2400007 			cmp word ptr [0040A285], 0007
:0040527F 	761C 				jbe 0040529D << Saute par dessus la boite de message

* Referenced by a (U)nconditional or (C)onditional Jump at Address: 
|:00405275(C)
|
:00405281 	6A10 				push 00000010 << Boite de limitation de temps

* Possible StringData Ref from Code Obj ->"PECompact v1.40b1, "
|
:00405283 	6808B24000 			push 0040B208	

* Possible StringData Ref from Code Obj ->"This unregistered version of PECompact "
->"has expired! Please see the about "
->"box for places to obtain a new "
->"version."
|
:00405288 	6878A94000 			push 0040A978
:0040528D 	FF351CB94000 			push dword ptr [0040B91C]
:00405293 	E8ECF0FFFF 			call 00404384
:00405298 	E9B3010000 			jmp 00405450 << Fin de la boite et suite du programme...
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040527F(C)
|
:0040529D 	833DA1B9400001           		cmp dword ptr [0040B9A1], 00000001
:004052A4 	0F84A6010000            		je 00405450
:004052AA 	68FF000000              		push 000000FF
:004052AF 	6832B44000              		push 0040B432
:004052B4 	684C040000              		push 0000044C
:004052B9 	FF351CB94000            		push dword ptr [0040B91C]
:004052BF 	E85B280000              		call 00407B1F

Ce qui est dejà plus lisible pour un début. Là vous l'aurez bien vue, il faut faire sauter le 750A jne 00405281 pour que le prog passe par 761C jbe 0040529D et saute la limite de temps. On va donc rajouter une petite ligne dans le script de Rpp, voici la ligne : p=0405275/75,0a/75,00: .
Nous allons replacer 750A par 7500 ce qui reviens au même que de le nopper puisqu'il ne va sauter nulpart! :)

Maintenant on va s'occuper du nag qui viens alléatoirement. Il faut savoir que ce genre de nag fait appel la plupart du temps à une base de temps pour s'identifier à la fenêtre sur le retour d'un entier(c'est de la prog). On va donc poser un bpx SetTimer sous Sice pour bloquer le prog pour voir si il fait appel à une telle fonction. On le lance et hop! c'est le cas (bon, c'etait un peu fait expret ;p), le prog va affichier un nag et dès qu'on le quitte il fait appel à SetTimer à la ligne 405498. Comme cette API utilise un rtour d'information la source du probleme à de grande chance de se trouver un peu plus haut. Voici le listing d'enssemble :

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404E8C(C)
|
:0040546F 	E8F5240000 	call 00407969
:00405474 	33D2 		xor edx, edx
:00405476 	D1E9 		shr ecx, 1
:00405478 	720D 		jb 00405487 << Devinez à quoi il sert ;)
:0040547A 	68429C0000 	push 00009C42
:0040547F 	FF7508 		push [ebp+08]
:00405482 	E8F70D0000 	call 0040627E << Appel la fenêtre About, erk...

:00405487 	6A00 		push 00000000
:00405489 	68F4010000 	push 000001F4
:0040548E 	6A00 		push 00000000
:00405490 	FF7508 		push [ebp+08]
:00405493 	E80F260000 	call 00407AA7
:00405498 	6880000000 	push 00000080 << Sice bloque ici (bpx SetTimer)
:0040549D 	FF3518B94000 	push dword ptr [0040B918]
:004054A3 	E847260000 	call 00407AEF
:004054A8 	50 		push eax
:004054A9 	50 		push eax
:004054AA 	6A00 		push 00000000
:004054AC 	6880000000 	push 00000080
:004054B1 	FF351CB94000 	push dword ptr [0040B91C]
:004054B7 	E809260000 	call 00407AC5
:004054BC 	58 

Ici pas de probleme, il faut juste remplacer 720D par EB0D. Pour ce faire fates comme d'habitude avec le script ajouter une ligne, dans ce cas c'est celle-ci : p=0405478/72,0d/eb,0d:

Et voilà! Le prog est déplombé mais on va paufiner la chose. Deja pour virrer la phrase "Licensed for 14-days..." qui se trouve dans About il faut s'y prendre de la même façon que pour le "Unregistered" (cours MemenTo 3).
Mais ce n'est pas tout, maintenant pour que tout soit clean il faut retirrer le "PLEASE REGISTER!" qui clignote en gros et qu iest du plus mauvais effet.
Pour cela, rappellez-vous du fameux 00 qu'il fallait mettre dans certains cas pour supprimmer une phrase, et bien là c'est le même principe à peu de chose près que cette phrase clignote, et c'est justement ça qui va nous aider à la reperrée. Sous ProcDump faittent un dump complet (Dump Full) en ayant activer l'option header au prealable dans le panneau d'options (sisi je vous assures!):

image crade mais bon, c'est lisible!

Puis dumpez tout ça et ouvrez l'exe sous WinDasm. Bon ok il n'y à rien mais en traient sur le listing comme une épave on peut tomber là dessus :

:0040FA82 	800050 add byte ptr [eax], 50
:0040FA85 	007200 add byte ptr [edx+00], dh
:0040FA88 	6F outsd
:0040FA89 	006700 add byte ptr [edi+00], ah << +00, ok pas de pbs
:0040FA8C 	7200 jb 0040FA8E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA8C(C)
|
:0040FA8E 	65007300 add byte ptr gs:[ebx+00], dh << encore +00...
:0040FA92 	7300 jnb 0040FA94

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FA92(C)
|
:0040FA94 	00000000000000000000 BYTE 10 DUP(0)
:0040FA9E 	00000000 BYTE 4 DUP(0)


:0040FAA2 	025009 add dl, byte ptr [eax+09] << Belle addition ;)
:0040FAA5 	005200 add byte ptr [edx+00], dl
:0040FAA8 	7400 je 0040FAAA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FAA8(C)
|
:0040FAAA 	0A00 or al, byte ptr [eax]
:0040FAAC 	620400 bound eax, dword ptr [eax+eax]
:0040FAAF 	00FF add bh, bh
:0040FAB1 	FF820050004C inc dword ptr [edx+4C005000]
:0040FAB7 	004500 add byte ptr [ebp+00], al
:0040FABA 	41 inc ecx
:0040FABB 	005300 add byte ptr [ebx+00], dl
:0040FABE 	45 inc ebp
:0040FABF 	0020 add byte ptr [eax], ah
:0040FAC1 	005200 add byte ptr [edx+00], dl
:0040FAC4 	45 inc ebp
:0040FAC5 	004700 add byte ptr [edi+00], al
:0040FAC8 	49 dec ecx
:0040FAC9 	005300 add byte ptr [ebx+00], dl
:0040FACC 	54 push esp
:0040FACD 	004500 add byte ptr [ebp+00], al
:0040FAD0 	52 push edx
:0040FAD1 	0021 add byte ptr [ecx], ah
:0040FAD3 	00000000000000000000 BYTE 10 DUP(0)
:0040FADD 	000000 BYTE 3 DUP(0)

Ce code se base sur le même principe que la gestion d'un curseur de boite de texte. On peut voir ce le curseur est synchroniser en 1/2 par rapport au label "PLEASE REGISTER!". La ligne 025009 add dl, byte ptr [eax+09] est interressent puisqu'elle va reactiver à chaque fois cette opperation (le clignotement). En mettant le resulta à 00 rien ne pourra suivre à ce niveau là dans le cose et l'on va l'annuler.

Pour ce faire il faut ajouter cette ligne dans le script : p=40faa2/02,50,09/00,00,09:

Le script donnera au final :

O=Pe140bcrk.exe:
F=PECompact.exe:
p=0405478/72,0d/eb,0d:
p=0405275/75,0a/75,00:
p=404dd7/68,34,04,00,00/68,34,00,00,00:
p=40faa2/02,50,09/00,00,09:
$

Voilà, ce coup-ci le prog est completement deplombé mais il reste un lourd probleme...
Comme je l'ai deja dis, les loaders ne sont pas fiables à 100% mais plutot à 80%. Les 20% restant peuvent rendres votre machine instable, etc...
C'est pour ça que l'on va voir comment patcher directement le prog, mon etape preferee =)

 

Si Hiew n'existait pas il faudrait l'inventer!!

Et oui, nous allons une fois de plus utiliser mon prog prefere, Hiew 6.x :)

Alors voilà, pour patcher un prog compacter il exsite plusieurs façons mais celle que je pratique (la plus sure) est d'inscire son code asm à la fin d'un fichier et de resauter sur son point d'entrer pour le rendre actif. Et oui car comme les progs compactés se décompactes entierement en mémoire, il y à forcement un retour d'instruction sur le point d'entrée quand le decompactage se termine et que le prog fait sin premier démarrage. Là on attaque la prog en asm.

Deja pour incorporrer son code asm il faut un registre, prenons eax. Ensuite il faut le pousser, etc.. l'algorythme de base est :

Pousse eax
Deplace l'addresse cible dans eax
Deplace le nouvel octet dans eax
On met le eax à 0
On vide eax
On indique le point de passage de notre code
On recupere les données
On saute sur l'entrée du fichier pour les appliquées

En assembleur ça donne :

push eax
mov eax xxxxxx
mov eax xx
xor eax
pop eax
push xxxxxx
ret
jmp point d'entrée du programme

Pour le point d'entrée il suffit juste de ce placer comme ca :

Et de recuperrer l'addresse d'entrée qui est ici 00401000.

Voilà, alors comme c'est (peut être) le primer prog que vos patchez de la sorte de vais me passer de commentaire et vous filer un screenshot, ça serat plus explicite (octet a placer à la fin d'un fichier, là où se trouve pas mal de 000000... qui ne servent à rien) :

Maintenant c'est bon, vous pouvez executer le programme. Alors, qu'est ce qui se passe? Rien du tout! :)
Et oui, nous avons mis notre code mais nous n'avaos pas fait en sorte que le programme en tienne compte, ici le push 417000.

Alors, reprennons notre fichier "header" que nous avons fait avec ProcDump et redesassemblons-le avec Windasm. Maintenant on va chercher l'occurence LoadLibraryA; cette API sert à plusieurs chose mais principalement ici a créer un processus de l'image du fichier exe en memoire, cette fonction peut aussi se retrouver dans une dll.
Une fois trouvé il faut chercher le push qui se trouve juste au dessus car ce push correspond à l'entrée du programme (verifiable sous Sice > 004231B0 ENTER). Le principe est donc tout simple, on chope ce passage pour l'orrienter vers notre patch et on retourne sur l'entrée du fichier ce qui reviens exactement au même en deffinitive. Voilà donc la modif' à faire :

En

car c'est à l'addresse 4231B0 qui se trouve notre code, et rappellez vous, le saut qu'y sy trouve à la fin va sauter sur l'entée du programme.

Maintenant redemarrez PeCompact 1.40 b1 et voilà! Le tour est joué, out à été fait pour contourner la limitation dans le temps, les nags et autres :)

A present vous êtes prêt pour vous lancer dans le patchage de fichiers compressés (évitez quand même ceux qui sont cryptés dans un premier temps).
Je rappel aussi qu'un tutoriel est le reçis d'une experience, il ne doit pas favoriser certaines pratiques (je suis mal placé pour dire ca mais c'est surtout le coté asm qui me plait).

Ah oui je rappel que ce n'est qu'un exemple et que d'autres programmes n'auront pas la même protection mais le principe d'approche reste casiment identique.