| Protection | Néolite et shrinker | Les Protections Renforcées | ||
| Outils | ProcDump SoftIce Wdasm | |||
| Cible | Explor 2000 |
By Christal |
EXPLORER 2000 Version 1.08 (protégée par Shrinker 3.3) Version 1.41.1 (protégée par Néolite 1.4) Infection :
Avant propos :
L’objectif de ce texte n’est pas tant de trouver comment cracker un shareware (c’est
mal !), mais plutôt de tester une méthode face à des programmes packed. Si vous le souhaitez,
vous trouverez plus d’explications dans " Les programme Cryptés : HomeSite 4.0 Part II ". Si vous avez l’intention de jouer avec votre horloge, prenez la précaution
de sauvegarder au préalable la clé [HKEY_CURRENT_USER8Software\Cmaufroy] dans la base de registre. Les boites d’enregistrement sont souvent le point faible des Sharewares. Vous verrez
que Christian Maufroy, l’auteur de ce soft, n’a pas commis cette " erreur " dans la version
1.41.1. Commencez par entrer votre nom et un sérial quelconque dans les champs de
la DialogBox. Vous hériterez d’un message d’erreur " The unlock Code was wrong ". Fidèle à mes habitudes, j’ai attaqué la recherche du call faisant
apparaître cette MessageBox, en posant un Bpx hmemcpy dans SoftIce. Après 7 appuis sur la touche [F12],
je suis sortie derrière un call 0043F7614. En traçant avec [F10], le premier call provoquant l’affichage
du message d’erreur est en 004F75FF. Pas de test immédiatement au dessus. J’ai posé un point d’arrêt sur ce call, et au passage suivant j’ai
enchaîné la combinaison [F8] pour entrer dans le call et [F10] pour trouver le call suivant, affichant
le nag screen, et je suis arrivé là : Avec un peu d’habitude, on repère de suite la solution. Je vous laisse y
réfléchir, nous y reviendrons. Sachez cependant qu’une simple manipulation en mémoire peut faire de vous
un utilisateur définitivement enregistré : Explor2000 modifiant la base de registres, en y mettant
un flag. Mais si on peut faire très simple, pourquoi ne pas faire compliqué ?… Vous avez pu voir que le code que vous avez entré est poussé dans
Edx. Le call qui suit est, potentiellement, une routine de contrôle. En la " visitant ",
vous n’aurez pas à chercher longtemps : Dans le call qui suit la mise dans Eax et Edx des 2 sérials (le bon, et le
votre), vous aurez un ensemble de comparaisons, par groupe de 4 caractères, avec un cmp ecx,ebx en 004040B9. Par contre, mais je n’ai pas approfondi, si vous entrez le sérial trouvé,
le programme " n’accusera pas réception ", et vous aurez toujours Unregistered Version
dans la boite About, mais plus de nag screen au lancement d’Explor2000, ni de problème avec la Time Limit
(à son sujet, si vous venez à reculer votre horloge, vous hériterez d’un message " Move
back ", et bien évidemment le Soft vous " dénoncera " à la base
de registre, et se fermera aussi sec…). Si vous modifiez le JZ en JMP en 004AF3DB (vous aviez trouvé ?), à
l’entrée d’un sérial dans la boite d’enregistrement, vous aurez un message " "The
program has been registered ", la boite About indique " Licenced to votre_nom ",
bref le Soft à meilleur mine qu’avec l’entrée du sérial trouvé. C’est donc ce branchement
que j’ai choisi de modifier. Passons maintenant au test de la " méthode " pour modifier
les programme packed :
(Il est à noter que Wdasm 6 a planté au désassemblage, mais
que les versions 8.5 et 8.93 ont pu donner un listing, mais sans les String Datas References, et autres ressources). Ce listing va déjà donner quelques informations sur l’Entry Point
du Shareware, que ProcDump va confirmer : Entry Point : 0063E3DA Identification de la signature de Shrinker : 0063E4DF Dans Wdasm, faites un goto 0063E4DF : Et vous retrouverez la signature de Shrinker, tel que vous aurez pu le voir dans
le Script.ini de ProcDump. Le call [ebp-20] passe le relais à l’application d’origine (décompressée),
et EAX en contient l’entry point.
Une méthode qui semble être la meilleure, consiste à modifier
les caractéristiques de la section dont le virtual offset est supérieur à la valeur de l'entry
point ( - l'image base) : Passons à une autre méthode : BPX GetProcAddress La Méthode 3, ma préférée : A l’aide d’un éditeur hexadécimal, faites une recherche sur la signature
de Shrinker (FF5510FF75…), et remplacez le premier FF par CC (opcode de Int 03, cf : " les programmes
cryptés "). Avec un BPINT 3, vous allez forcer un break sur l’interruption 3, et vous vous retrouvez
dans le programme exactement là ou vous le souhaitiez (pensez à rétablir le FF en lieu et
place du CC)
Rechercher un espace où insérer notre patcher ( tiré en partie d’un Tut de CyberBobJr ) Pour rappel, tout programme
est divisé en sections,
et chaque section possède une entrée dans le PE Header, cela veut dire que notre loader possède une section dans le PE Header, ProcDump
nous permet de connaître les détails de cette section ( la section est la section contenant l'entry
point, pour savoir comment la trouver, allez voir plus haut ): Par exemple : (.data étant la section qui comprend l'EntryPoint
et donc le Loader ) La Virtual size de la section est 00002000, ce qui veut dire que la mémoire
qui sera allouée pour cette section sera de 00002000 bytes. ( Cette valeur est toujours un multiple du Virtual
Offset de la section CODE. ) Le Virtual Offset de la section, et donc du code du loader, est de 000DF000, additionné
à l'Image base qui vaut 00400000, ca nous donne une adresse virtuelle de 004DF000.
Rem : Vu que la taille doit
être un multiple, cela veut dire que le compilateur rajoute des 00 pour que la section aie la bonne taille. Généralement, après les informations de versions, il
y a beaucoup de 00 que vous pouvez modifier. Mais, et oui, il y a un mais, il faut faire attention à 1 choses
quand vous faites cela : Il faut bien vérifier que l'adresse où vous allez écrire le code
de votre patcher fait toujours partie de la section que vous voulez modifier. Rem : Il vaut mieux écrire
notre code à la place de 00 que sur du code, même si celui-ci semble inutile au premier coup d'œil. Si nous trouvons plein de 00 ici en 004DFBB7 et que cette adresse fait partie
de la section .data en exemple un peu plus haut) :
Indormation complémentaires :
Pour calculer l'offset sur le disque à partir de l'adresse virtuelle : d. vous utilisez une méthode comme celle de Psyché (A lire : Advanced Registry Tracer) e. vous utilisez un espace facile à trouver et qui ne vous réservera
pas de mauvaise surprise : l’icône de l’application (voir en seconde partie de cet essai). 4- Le Relais:
Il ne reste plus qu’à écrire le patch : 0063EF6A : on remplace le 74 (JZ) par EB (JMP) en 004AF3DB 6- Le contrôle
La Version 1.41.1 Mon objectif, cette fois ci encore, n’était pas de trouver comment cracker
le programme, mais de continuer à tester une méthode pour patcher les Soft Packed. 2- Le crack
Trouver le call qui appel cet écran n’est pas très compliqué,
juste un peu laborieux : en marquant par un bpx (F9) chaque call rencontré lors d’un tracing F10 et
provoquant l’affichage du nag screen, vous finirez par mettre la main sur celui ci en 0053BF66 En forçant le branchement en 0053BF6B, vous allez vous débarrasser
et du Nag Screen, et de la Time Limit. Une pierre, deux coups; les deux procédures sont dans le même
call… Reste à modifier le 74 en EB à l’offset 0053B5E. Faites une recherche sur cette chaîne avec un éditeur hexadécimal
(je n’en connais pas beaucoup, mais Hiew est très bien pour ce genre de recherche, car il pourra vous donner
l’adresse de la chaîne trouvée). Vous aurez ceci : Pour pouvoir provoquer un break dans SoftIce, remplacez le FF en 00676424 par un
CC pour obtenir un point d’arrêt sur l’interruption 3 (pensez à poser un BPINT 3 dans Sice…). Quand vous aurez la main, remettez le jmp eax en état, et interrogez eax
pour connaître l’entry point du Soft décompressé : 0053BF5E. Pour commencer, lancez ProcDump et cliquez sur " PE Editor "
.Sélectionnez ensuite l’exécutable, et cliquez sur " Sections " pour que ProcDump
vous affiche toutes les sections du Soft. . Faites un click droit sur la section " CODE " et
choisissez l'option " Edit section " . Dans la case " Section characteristics "
, vous verrez : C0000080 . Remplacez cette valeur par E0000020 et pour enregistrer votre modification, quittez
" PE Editor " . Lancez ensuite Explorer2000 via le Symbol loader de Softice . De cette façon
SoftIce pourra prendre la main. Wdasm vous donnera également un listing avec des Strings Data Références Posez un bpx 00676424 sur le jmp eax, et faites [F5] pour relancer Explor2000. Vous
pouvez auusi appuyez une fois sur F10 (dès que SoftIce vous passera la main), et vous serez en 0064670F.
Au break en 00676424, passez en mode assemblage, et changez le jmp eax par un jmp eip. Ainsi, vous obligerez le
programme à boucler sur lui même. Ouvrez de nouveau ProcDump, et cliquez sur " Options " pour
choisir " Rebuilt Import Table ", puis sélectionnez Explor2000 dans la liste des taches
actives de la fenêtre de ProcDump. Après quelques instants, vous pourrez sauvez un joli dump du nouvel
exécutable. Des 983 ko d’origine, vous avez maintenant un programme de 2325 ko (efficace Néolite !),
prêt a être patché si l’envie vous en prend, en remplaçant le 0043BF5E 740B JZ 0053BF6B
par un 0043BF5E EB0B JMP 0053BF6B… Si vous n’avez pas envie de grossir les applications stockées sur votre DD,
vous pouvez aussi essayer de réaliser un patch dur de l’exécutable " Néolite ". Hélas, ce n’est pas moi qui vous montrerais comment faire, et vous allez
voir pourquoi : Choisissez une suite de caractères significatives, et faites en la recherche
dans votre hexéditeur (type Hiew, qui vous retournera l’adresse où vous pourrez Jumper). Pour ma part, j’ai décidé de m’installer en 005A5A07. Sachant que
le patch que je souhaite faire sera très discret, l’icône n’en sera qu’à peine altérée. Par précaution, avant de me lancer, j’ai posé un bpm 005A5A07 W(rite)
pour m’assurer qu’il n’y aurait aucune autres écritures que les miennes à cette adresse (mais je
ne courrais pas beaucoup de risques…). F10 pour aller à l'adresse du patch Et un contrôle pour vérifier que j’ai 74 en 0053BF59, et donc que la
zone est bien décompressée. Pas de problème. F10 Crash ! ! Là, y a un problème, et de taille… Impossible d’écrire en 0053BF59. Rien à faire. Cette section étant
dans la même que celle que j’avais modifiée pour retrouver la main sous SoftIce, je ne comprend toujours
pas pourquoi, je peux écrire ce que je veux à cet endroit, mais sans moyen d’accéder par un
mov en 0053BF5E. J'ai eu beau modifier une à une, puis ensemble toutes les caracteristiques, rien à
faire. (Pour connaître le nom de la section à modifier, posez un bpx 0053BF59
et regardez ce qu’il y a d’indiqué entre la fenêtre des commandes et celle des codes, ou faites 53BF59-400000(image
base) = 13BF5E, et utilisez le PE Editor de ProcDump pour savoir dans quelle section se trouve cette adresse). Est ce que le programme écrit dans un fichier tempaoraire? apparement pas.
Alors... En fait, Néolite protège en écriture la mémoire utilisée
par le programme d'origine, et Windows refuse donc toute modification du code. Pour pouvoir dépasser la restriction dûe au Packer, soit il faudrait
importer une fonction utilisant WriteProcessMemory (voir le texte de TaMaMBoLo sur la version 1.34), et dans ce cas autant utiliser R!SC,
soit il faut trouver quelle API est utilisée pour empêcher l'écriture dans les codes d'Explor
2000. L'API en question s'appelle VirtualProtect. Il s'agit de voir, maintenant, quand
elle est sollicitée... Bpx VirtualProtec Le premier appel à cette API est faite en 00676B8A par un call [EBP+6E].
Les trois suivant, respectivement, en 00676B30, 00676C19 et 00676D13, toujours par des call [EBP+6E ]. Noppez les
trois derniers sans hésitations, mais ne touchez pas au premier. A chaque programme protégé
par Néolite, cela semble être une constante: pas touche au premier call! Modifiez Explor 2000 avec un éditeur hexadécimal (FF5576 à
remplacer par des Nop aux BONNES adresses), et refaites les manipulations vues au début du chapître
5. Cette fois ci ça marche! Il ne vous reste plus qu'à patcher définitivement l'exécutable
avec votre hexéditeur. (source TeeJi)
R!SC est un memory patcher qui utilise un script pour créer un fichier exécutable
de 8 ko, et qui permettra de lancer le soft sans le modifier " physiquement " (et sans avoir
à s’inquiéter de Néolite), mais qui interviendra quand le programme sera décompressé
en mémoire (et faisant appel à la fonction WriteProcessMemory): Voici le script qu’il serait possible d’écrire : A l’aide de ce script, R!SC va générer un Loader qui, une fois lancé,
va faire démarrer l’application / cible exactement comme si vous aviez modifié physiquement l’exécutable
décompressé par ProcDump. Gain de place et efficacité garantie !
Comment contourner la protection de la version 1.08
0177:004AF3C6 807B2C00 CMP BYTE PTR [EBX+2C],00
0177:004AF3CA 7454 JZ 004AF420
0177:004AF3CC 8B55FC MOV EDX,[EBP-04] > notre code
0177:004AF3CF 8BC3 MOV EAX,EBX
0177:004AF3D1 E8FA010000 CALL 004AF5D0
0177:004AF3D6 2DC8000000 SUB EAX,000000C8
0177:004AF3DB 7408 JZ 004AF3E5
0177:004AF3DD 48 DEC EAX
0177:004AF3DE 7421 JZ 004AF401 > Jump
0177:004AF3E0 48 DEC EAX
0177:004AF3E1 742B JZ 004AF40E
0177:004AF3E3 EB34 JMP 004AF419
0177:004AF3E5 8D4338 LEA EAX,[EBX+38]
0177:004AF3E8 8B55FC MOV EDX,[EBP-04]
0177:004AF3EB E86449F5FF CALL 00403D54
0177:004AF3F0 C6437401 MOV BYTE PTR [EBX+74],01
0177:004AF3F4 8BC3 MOV EAX,EBX
0177:004AF3F6 E8F5140000 CALL 004B08F0
0177:004AF3FB C6435803 MOV BYTE PTR [EBX+58],03
0177:004AF3FF EB18 JMP 004AF419
0177:004AF401 C6437400 MOV BYTE PTR [EBX+74],00
0177:004AF405 8BC3 MOV EAX,EBX
0177:004AF407 E830140000 CALL 004B083C > nag screen
0177:004AF40C EB0B JMP 004AF419
0177:004AF68D 8BCE MOV ECX,ESI
0177:004AF68F E87CDEFFFF CALL 004AD510
0177:004AF694 8B45F8 MOV EAX,[EBP-08] > un code
0177:004AF697 8B55FC MOV EDX,[EBP-04] > notre code
0177:004AF69A E8ED49F5FF CALL 0040408C
0177:004AF69F 754B JNZ 004AF6EC
En utilisant Softice, j’avais pu voir que j’avais affaire à Shrinker (d’après le nom des sections).
Une tentative de désassemblage donnant " This PE file is not standard " ne peut qu’inciter
à utiliser PE Sniffer pour en savoir plus : Explor2000 est protégé avec Shrinker 3.3
:0063E4D3 8945E0 mov dword ptr [ebp-20], eax
:0063E4D6 FF7510 push [ebp+10]
:0063E4D9 FF750C push [ebp+0C]
:0063E4DC FF7508 push [ebp+08]
:0063E4DF FF55E0 call [ebp-20]
:0063E4E2 8945E4 mov dword ptr [ebp-1C], eax
:0063E4E5 EB07 jmp 0063E4EE
SoftIce ne donnant pas la main au lancement d'Explor2000, il va falloir l'aider un peu.
En cliquant sur le bouton [PE Editor] de ProcDump vous obtiendrez un entry point égale à 0023E3DA,
et une image base de 400000. Additionnez les deux (00400000 + 0023E3DA), et vous retrouverez le 0063E3DA que nous
avons déjà identifié.
Cliquez sur " Sections ", et en cherchant dans la colonne Virtual Offset, vous verrez que ce point d'entrée
se situe dans .load, qui commence en 23D000 et fini en 240000 pour laisser la place à .reloc.
Modifiez les caractéristiques de la section .load en remplaçant celle que vous trouverez par E0000020
(les explications détaillées peuvent être lues dans " Les programmes Cryptés ").
Théoriquement, vous êtes désormais en mesure de provoquer un break dans SoftIce sur l'entry
point, et de désassembler " normalement " l'exécutable.
Pas de chance, dans ce cas précis, pas de résultat probant…
Par contre, en remplaçant les caractéristiques (80000A82) de la première section .shrink,
j'ai pu obtenir, enfin, un break dans SoftIce.
Vous allez pouvoir vous retrouver dans SoftIce, mais vous aurez à tracer tous les codes avec F10 pour arriver
en 0063E4DF, adresse où Shrinker aura fini de décompresser Explor2000.
C'est long et fastidieux, mais ça marche…
Vous avez 3 ou 4 cas de figure pour trouver de la place :
Virtual size Virtual Offset Raw size Raw Offset
.data 00002000 000DF000 00001400 00050A00
La taille sur disque (Raw Size) est de 00001400, ce qui veut dire que
le code n'utilise que 00001400 bytes dans le fichier .exe. L'offset sur disque (Raw Offset) est de 00050A00, autrement
dit le code s'étale sur le disque de l'offset 0050A00 jusqu'a 0050A00+1400 = 00051E00.
Offset sur le disque = (000DFBB7 - Virtual Offset) + Raw Offset
soit (00DFBB7 - 00DF000 ) + 00050A00 = 000515B
La première méthode se révèle suffisante, et j’opte pour
m’installer ici ::0063EF5D 000000 BYTE 3 DUP(0)
:0063EF60 C8030000 enter 0003, 00
:0063EF64 48 dec eax
:0063EF65 06 push es
:0063EF66 00000000000000000000 BYTE 10 DUP(0)
:0063EF70 00000000000000000000 BYTE 10 DUP(0)
:0063EF7A 00000000000000000000 BYTE 10 DUP(0)
:0063EF84 00000000000000000000 BYTE 10 DUP(0)
:0063EF8E 00000000000000000000 BYTE 10 DUP(0)
:0063EF98 00000000000000000000 BYTE 10 DUP(0)
:0063EFA2 00000000000000000000 BYTE 10 DUP(0)
:0063EFAC 0000000000000000 BYTE 8 DUP(0)
:0063EFB4 BEF86300 DWORD 0063F8BE
:0063EFB8 54F96300 DWORD 0063F954
Maintenant, il va falloir obliger le Loader à se rendre à la zone repérée avant de
passer le relais à l'application fraîchement décompressée ::0063E4D6 FF7510 push [ebp+10]
:0063E4D9 FF750C push [ebp+0C]
:0063E4DC E9DEXXXXXX JMP 0063EF6A
5- Le Patch
:0063EF68 0000 ADD [EAX], AL
:0063EF6A C605DBF34A00EB MOV BYTE PTR [004AF3DB],EB > modif du 74
:0063EF71 FF7508 PUSH DWORD PTR [EBP+08]
:0063EF74 FF55E CALL [EBP-20]
:0063EF77 0000 ADD [EAX], AL
:0063EF79 0000 ADD [EAX], AL
:0063EF7B 0000 ADD [EAX], AL
0063EF71 : on rétablie le push écrasé par le jmp 0063EF6A, en 0063E4DC
0063EF74 : et zou !
Une fois que vous vous êtes assuré que votre patch fonctionnait en mémoire, modifiez Explor2000
avec Hiew, de préférence. Si vous n’avez pas de crash en relançant le programme, via l’explorateur
de Windows, c’est que la place que vous aviez choisie faisait l’affaire…
Il n’est pas aussi fréquent que cela qu’un auteur de Shareware " révise " son
schéma de protection d’un version à l’autre. Pourtant, dans le cas d’Explor2000, Shrinker a laissé
la place à Néolite, et la boite d’enregistrement a été supprimée pour une solution
beaucoup plus subtile : le sérial à entrer doit être placé dans le ClipBoard de
Windows, et Explo2000 se chargera lui même d’aller le récupérer, au clic sur le bouton [Register]
de l’écran Shareware, avant de placer son Flag " Utilisateur Enregistré " dans
la base de registres.
Pour faire simple, j’ai donc décidé de me contenter de supprimer le nag screen, et la Time Limit.0177:0053BF51 8B45F8 MOV EAX,[EBP-08]
0177:0053BF54 BA98BF5300 MOV EDX,0053BF98
0177:0053BF59 E83682ECFF CALL 00404194
0177:0053BF5E 740B JZ 0053BF6B > saut intéressant
0177:0053BF60 8B55FC MOV EDX,[EBP-04]
0177:0053BF63 8B45FC MOV EAX,[EBP-04]
0177:0053BF66 E8E5F40000 CALL 0054B450 > nag screen
0177:0053BF6B 33C0 XOR EAX,EAX
En utilisant le script.ini de Procdump, vous allez obtenir la signature de Néolite : FFE0803D.
0177:0067640F 8B442404 MOV EAX, [ESP+04]
0177:00676413 230575636700 AND EAX,[00676375]
0177:00676419 E871030000 CALL 0067678F
0177:0067641E FE050E646700 INC BYTE PTR [0067640E]
0177:00676424 FFE0 JMP EAX > zou !
0177:00676426 803D0E64670000 CMP BYTE PTR [0067640E], 00
0177:0067642D 7513 JNZ 00676442
0177:0067642F 90 NOP
On va changer un peu de méthode, et créer un Dump d’Explor2000.
La première chose à faire, est de trouver un espace disponible pour y écrire un patch. Comme
il n’est pas toujours facile de trouver un tel espace (après tout, le propre d’un compresseur et de supprimer
tous les espaces inutiles…), vous pouvez squatter un petit coin de l’icône de l’application. A l’aide d’un
éditeur de ressources, trouvez la chaîne hexadécimale qui correspond à l’icône
en cliquant deux fois sur MAINICON, à supposer que vous utilisiez les Borland Workshop Ressources.
Puis j’ai changé, en mémoire pour commencer, le jmp eax en jmp 005A5A07 :
0177:00676419 E871030000 CALL 0067678F
0177:0067641E FE050E646700 INC BYTE PTR [0067640E]
0177:00676424 E9DEF5F2FF JMP 005A5A07 > envoi vers patch
0177:00676429 64670000 ADD FS:[BX+SI],AL
0177:0067642D 7513 JNZ 00676442
Petite modification :0177:005A5A07 C6055EBF5300EB MOV BYTE PTR [0053BF5E] ,EB > modif
0177:005A5A0E FFE0 JMP EAX > et zou !
Et à défaut, vous pouvez vous rabattre sur R!SC’s Process Patcher, pour modifier en mémoire Explor2000.
T=2000: ; temps accordé pour trouver les bytes à modifier
F=explor2000.exe: ; nom du programme à patcher
O=boum.exe: ; nom du fichier exe que vous allez créer
P=53BF5E/74/EB : ; modifications à apporter en 0053BF5E
$ ; ordre de fin de script
Bonne journée