Life Guard version 3.7
La méthode et la protection sont identiques à celles d'ACDSee 3.0
Voyons si elle va confirmer le " How to Proceed... "
Après les modifications d'usages des caractéristiques, le Symbol Loader break sur l'Entry Point.
:004A4002 E872050000 CALL 004A4579 :004A4007 EB33 JMP 004A403C
Pour trouver rapidement le dernier passage de relais vers Life Guard, le plus simple, cette fois ci, va être
de chercher la signature du POPAD :
S 00400000 L 00500000 61 75 08
Comme précédemment, cette partie n'est pas compressée et donc lisible dès l'Entry Point
:
:004A44F3 61 POPAD :004A44F4 7508 JNZ 004A44FE :004A44F6 B801000000 MOV EAX,00000001 :004A44FB C20C00 RET 000C :004A44FE 6800000000 PUSH 00000000 -> va devenir PUSH 00462270 :004A4503 C3 RET
Un BPX 004A4503 va nous faire breaker à l'adresse qui nous permettra de réaliser notre Dump.
Au passage, vous penserez à relever l'adresse qu'ASPack aura Patché en 004A44FE -> 00462270
Réalisation du DUMP :
Ouverture de ProcDump
Sélection dans la fenêtre de la tache " Lifeguard "
Clic Droit sur Lifguard et " Dump Full "
Sauvegarde du Dump obtenu
Kill de LifeGuard
Sélection du bouton " PE Editor "
Ouverture du Dump
Modification de l'Entry Point
That's all
Le Dump fonctionne sans problème, et Wdasm le désassemble sans frémir.
Passons à l'étape suivante : le débuggage
Dans sa version Shareware, LifeGuard est équipé d'un écran d'accueil avec un Timer (géré
par GetTickCount) de 30 secondes.
C'est long trente secondes avant d'avoir le droit d'entrer un Password (champ unique) ou de pouvoir cliquer sur
" continuer évaluation ".
Comme il est hors de question de cracker ce programme (c'est POA Ben !), on va simplement en faciliter un peu la
découverte dans le plus pur esprit du respect Shareware :
Comme le nag de départ est orné d'un très joli UNREGISTERED VERSION,
il m'a semblé qu'il pourrait être intéressant de commencer par en rechercher la String Data
:
* Possible StringData Ref from Code 0bj ->"Unregistered version." I :00454394 mov edx, 004543E8 :00454399 cal1 0043A7FO
en remontant à la racine de ce call, vous aurez trois adresses d'appels :
* Referenced by a CALL at Addresses: |:0045357E , :00453E1C , :004575F7 I :00454334 mov eax, dword ptr [00464AD4] :00454339 cal1 00454064
Celle qui nous intéresse pour le moment est le branchement fait en 004575F7
:004575D2 mov eax, dword ptr [00464B10] :004575D7 call 00402CBO :004575DC test bl, bl :004575DE je 004575EC :004575EO mov eax, dword ptr [00463D48] :004575E5 mov eax, dword ptr [eax] :004575E7 call 0045413C * Referenced by a (U)nconditional or (C)onditiona1 Jump at Address: |:004575DE(C) I :004575EC test bl, bl :004575EE jne 004575FC :004575FO mov eax, dword ptr [00463D48] :004575F5 mov eax, dword ptr [eax] :004575F7 call 00454334 ; vers Unregistered
Deux sauts conditionnels se trouvent juste au-dessus, en 004575DC et 004575EE.
Celui qui va éviter l'affichage du nag est le second, mais si vous posez un BPX sur le premier, vous verrez
que c'est celui qui va déterminer l'état de BL, qui lui-même provoquera, ou non, le saut évitant
le call déplaisant.
La procédure en 00402CB0 est appelée par 221 Calls et deux sauts conditionnels. Inutile de perdre
du temps à chercher quoi modifier dans cette procédure. Evidement il serait intéressant de
comprendre pourquoi BL reste à 00 après l'avoir traversé, mais les valeurs poussées
juste avant son appel ne donnent rien de significatif. La vérité est plus en amont dans le listing...
Par contre, bien que BL n'en soit pas affecté, il y a le call 0045413C suivant :
* Referenced by a CALL at Addresses: |:004534DA , :00453FCA , :004575E7 I :0045413C 55 push ebp :0045413D 8BEC mov ebp, esp
3 appels sur celui ci. Nous en connaissons un, mais les deux autres ?
Le premier va servir à l'affichage de la boite " ABOUT "
:004534C3 mov eax, dword ptr [00463D24] :004534C8 mov eax, dword ptr [eax] :004534CA call 00402CBO :004534CF test b1, bl :004534D1 je 004534DF :004534D3 mov eax, dword ptr [00463D48] :004534D8 mov eax, dword ptr [eax] :004534DA call 0045413C * Referenced by a (U)nconditional or (C)onditiona1 Jump at Address: |:004534D1(C) I :004534DF test b1, bl :004534E1 jne 004534EA
et le suivant :
* Possible StringData Ref from Code 0bj ->"Thank you for registering!"
Amusant, non ?
D'autant plus que l'on retrouve le même schéma pour le nag et pour l'écran ABOUT :
:004575D7 call 00402CBO :004575DC test bl, bl :004575DE je 004575EC :004575EO mov eax, dword ptr [00463D48] ; hélas, rien de significatif là non plus :004575E5 mov eax, dword ptr [eax] :004575E7 call 0045413C :004575EC test bl, bl :004575EE jne 004575FC
Qu'arriverait il si le test BL,BL devenait un Mov Bl,01 codé sur un même nombre d'octets ?
Et bien le JE envoi directement en 004575E7, et évite les call Nag_Screen (ou le Unregistered_Version de
la boite About).
En fait, plus rien ne s'affiche à la place du UNREGISTERED dans l'écran ABOUT. En inversant le JE,
vous y gagnerez le " Registered to : " qui fait déjà plus clean.
Modifier la version Packée :
Nous avons donc, au minimum et à défaut d'avoir mieux pour le moment, à modifier deux test
bl,bl en mov bl,01 (en 004575DC et 004534CF) et un 74 en 75 à l'adresse 004534D1.
Pour trouver de la place, la méthode d'ACDSee va encore fonctionner : en partant de la fin de la section
.aspack, et en cherchant les premiers ADD [EAX],AL vous allez avoir de la place disponible en 004A59E0 :
Le patch
:004A59E0 66C705DC754500B301 MOV WORD PTR [004575DC],01B3 :004A59E9 C705CF344500B301750CMOV DWORD PTR [004534CF],0C7501B3 :004A59F3 6870224600 PUSH 00462270 :004A59F8 C3 RET :004A59F9 0000 ADD [EAX],AL
004A59E0... : modification sur un WORD (2 octets) de 84DB(test BL,BL) qui devient B301 (mov Bl,01). Vous remarquerez
que les octets à modifier s'écrivent " à l'envers "
004A59E9... : modification sur un DWORD (4 octets) de 84DB740C (test BL,BL JE 004534DF) qui devient B301750C (mov
BL,01 JNE 004534DF)
004A59F3... : on pousse l'adresse de l'Entry Point de LifeGuard
004A59F8... : et on simule la fin d'un call.
Petit rappel :
A la fin d'un call, le RET va amener le processeur à récupérer au sommet de la pile la valeur
de retour qui y a été placé lors de la commande CALL (EIP + 5 octets pour la call + 1 octet
pour l'OpCode suivant).
Si on pousse une valeur sur la pile juste avant un RET, c'est cette valeur qui va être utilisée comme
adresse de retour.
La dernière chose à faire va être de détourner ASPack vers notre Patch, avant qu'il
ne passe la main à LifeGuard :
:004A44F3 POPAD :004A44F4 JMP 004A59E0
Et ce juste après le POPAD qui rétabli les valeurs sauvegardées par le PUSHAD, et avant l'adresse ou ASPack va se patcher lui même pour créer le PUSH EntryPoint à la place du PUSH 00000000 (sinon votre " aiguillage " sera écrasé...)