PROCDUMP: mode d'emploi Les Packed/Crypted: généralités
Comment Obliger Shrinker 3.3 à rendre les armes :
La méthode employée ici est valable pour de nombreuses applications compressées par des crypteur ( crypteur est différent de packer, certains programmes ne font que crypter les données, et d'autres les compressent. Ceci est la différence entre Packer & Crypteur. A mon avis, ASPack, Shrinker, etc.. sont des Packer ! PECrypt, etc.. sont plutôt des crypteurs.. bien qu'il existe des programmes qui font les 2 ! ) comme AsPack, Néolite, et les différentes versions de Shrinker. A vous ensuite de savoir adapter la technique au différents cas de figure que vous rencontrerez.
Au moment ou vous voudrez utiliser Wdasm, les programme cryptées ( ou compressés ) donnent souvent droit à un écran comme celui ci. Dans le meilleur des cas, vous aurez un listing sans références, dans le pire, vous n’obtiendrez rien du tout. Partant de principe qu’il y a probablement une protection de type cryptage/compression, vous pourrez identifier l’empêcheur de cracker tranquille de plusieurs façons :
PE SNIFFER
Détection du mode de protection :
Son usage est des plus simple, il suffit de lui indiquer le répertoire du programme soupçonné d'être crypté ou compressé, et de cliquer ensuite sur le nom des différents Packer les plus courants.
Vous avez également une option Compiler, qui vous permettra, au moins, de savoir si l'exécutable est compressé, à défaut d'en reconnaître le format bien que dans certain cas, ce format n'est pas reconnu, or l'exécutable n'est ni crypté, ni compressé ! .
Une fois que vous saurez à quel Saint vous vouer, vous serez prêt à utiliser un deuxième outil :
PROCDUMP
2- Création d'un Dump de l'exécutable crypté:
Après avoir lancé Procdump, vous aurez une boite de Dialogue vous proposant plusieurs options (Unpack, rebuild PE…), et la liste des taches actives de votre système.
![]()
(Le Tableau de bord de ProcDump)
What ProcDump can do :
What ProcDump can do :
þ Dump any 32 bits running process/module by using the CodeShot engine.
þ Phoenix engine can restore the Import table & PE header.
þ Phoenix engine can reoptimize a PE file and Dump made with CodeShot.
þ Shiva engine can start & unpack a given PE file (at least it tries !!). With the help of script anguage, u can unpack in a few secs well-known packers and learn to ProcDump how to unpack the others.
þ Alter a given file PE header, kill some object physically.
þ Bhrama server can wait a client send a PID to dump : Client tell to ProcDump when it is good to dump ;).
Cliquez sur UNPACK et une seconde boite vous proposera de choisir l’une de ces protections. A défaut, vous pouvez opter pour UNKNOW, mais les résultats sont beaucoup plus aléatoire.
ProcDump va lancer l’application/cible, et en réaliser une copie-mémoire décompressée. L’écran qui s’affiche pendant ce temps va permettre d’avoir certains premiers éléments, dont l’adresse de l’Entry point de la cible, et l’adresse où il aura trouvé les octets qui lui permettront d’identifier la protection. (Cf Script.ini)Immédiatement vous obtiendrez cet écran, qui donne d’autes indications:
Entry point de la cible: 0x007C83DA
Identification de l’entrée de la protection: 0x007C84D6
L’entry Point 007C83DA sera confirmé par le listing du désassemblage de la version compressée :
+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
********************** Start of Code in Object .load **************
Program Entry Point = 007C83DA (homesite4.exe File Offset:003CD9DA)
A la fin de l’opération, ProcDump, avant de vous proposez de sauvegarder votre nouvel exécutable décompressé, va vous donnez une information supplémentaire :
L’adresse d’où Shrinker se branchera sur l’entry point de la version décryptée.
![]()
Cet appel se fera bien souvent sous la forme d’un Jmp EAX, d’un Call Eax, ou de la simulation d’un Call/Return, sous la forme d’un Push Eax / Ret. Pour reprendre une explication de Psyché :
" le processeur, lorsqu’il arrive à une instruction RET, va chercher sur la pile (Stack = la zone mémoire sur laquelle on push et on pop à longueur de temps; le registre ESP pointant vers le haut du Stack) l’adresse de retour sur laquelle va se brancher le programme, bref, il colle le dernier dword de la pile dans EIP.
Bilan de l’histoire, si on push un dword avant un RET, le programme se rebranchera sur l’adresse équivalente à ce dword (p.ex. : push 401234 RET, après le RET, vous serez en 401234, pigé ?) ".
Bien, désormais, vous disposez d’un bel exécutable bien clean que vous allez pouvoir désassembler avec Wdasm, utiliser avec softIce, et déplomber comme si de rien n’était.
Pourtant, dans cet essai, nous allons continuer à travailler sur la version Shrinkée, et regarder comment réussir à Patcher le programme sans avoir à le décompresser.
3- La structure du Programme :C’est dans cette partie que je me sens, le moins à l’aise, et où il me reste encore beaucoup à apprendre. Bien que je ne m’attende à rien en particulier, il serait intéressant qu’un Pygmalion désintéressé accepte de bien vouloir venir corriger, et compléter, ce qui va suivre. L’appel étant lancé, continuons :
En cliquant sur le bouton PE EDITOR de Proc Dump, vous allez continuer à obtenir des informations sur le Soft compressé :
L'image base qui semble toujours être 400000 et un Entry point à 00240E98.Soit 400000+240E98 = 640E98. Voici l’Entry Point de HomeSite dans sa version décompressé, comme Wdasm (après ProcDump) vous le confirmera :
+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
********************** Start of Code in Object CODE **************
Program Entry Point = 00640E98 (homesite0.exe File Offset:00240498)
En cliquant sur le bouton " Sections ", vous obtiendrez le tableau suivant :
(avant décompactage)
(après décompactage)
Vous aurez, bien sur, remarqué qu’il n’y a plus d’allusions à Shrink. (remarquez les C0000040)
Dans le cas des programmes compressés, C0000040 semble être une constante ( c'est les caractéristiques des section, et c'est une constante, car il faut que la section soit Readable, Writable et Data ! ainsi, le programme peut lire le code compressé, et le décompresser dans la même section sans provoquer d'erreur fatale dans Windows). Il suffit de changer le 0xC0000040 par 0xC0000020 pour qu'il devienne lisible par wdasm ET POUR QUE LE LOADER de SOFTICE FASSE UN BREAK sur L'ENTRY POINT au lancement du Soft.. Par contre cet attribut est parfois vérifié par le système de protection (c’est la cas d’AsPack) qui affiche le message "this file has been modified.."
Pour plus d'explications: voir la section PE Header
Pour en finir avec ProcDump
ProcDump est un programme qui peut être actualisé à partir de son script. Dans le fichier Script.ini vous allez retrouver les protections les plus courantes, et vous pourriez également le compléter pour y ajouter les éléments de nouvelles protections. ( voir le cours de TaMaMBoLo: Drapeau Noir n°3 )
Voici ce qu’il y a d’écrit pour Shrinker 3.3 :
[Shrinker 3.3] L1=LOOK FF,75,10,FF,75,0C,FF,75,08,FF,55 > chaîne que ProcDump va rechercher L2=BP > pose d'un breakpoint L3=STEP > trace pas à pas, le new EP est celui qui commence ici ! OPTL1=00000000 OPTL2=01010001 OPTL3=01010001 OPTL4=00010000OPTL5=00000000
C'est à partir de la chaîne FF7510FF750C7508FF55 que ProcDump va reconnaître Shrinker 3.3 et pouvoir commencer son Job.
Pour nous, cette information peut être très utile, dans la mesure ou ces codes se trouvent dans la partie clean de l'exécutable, à moins qu'il y ait eu sur-compression avec un autre Packer…
Et donc facile à trouver avec un éditeur hexadécimal ou dans le listing donné par Wdasm ::007C84AC 8B35B8A17B00 mov esi, dword ptr [007BA1B8] :007C84B2 85F6 test esi, esi :007C84B4 7431 je 007C84E7 :007C84B6 833DBCA17B0000 cmp dword ptr [007BA1BC], 00000000 :007C84BD 7528 jne 007C84E7 :007C84BF 833D845E7C0000 cmp dword ptr [007C5E84], 00000000 :007C84C6 741F je 007C84E7 :007C84C8 A1845E7C00 mov eax, dword ptr [007C5E84] :007C84CD 0305985F7C00 add eax, dword ptr [007C5F98] :007C84D3 8945E0 mov dword ptr [ebp-20], eax >le fameux eax :007C84D6 FF7510 push [ebp+10] > codes repérés dans Script.ini :007C84D9 FF750C push [ebp+0C] :007C84DC FF7508 push [ebp+08] :007C84DF FF55E0 call [ebp-20] > lancement du prog décompacté :007C84E2 8945E4 mov dword ptr [ebp-1C], eaxD’une version à l’autre de Shrinker 3.3, vous retrouverez à l’identique ces lignes et ces adresses.
Une interrogation du registre EAX, va vous donner la valeur 00640E98, soir l’Entry Point de HomeSite, tel que nousl’avons déjà vu.SoftIce :
Bien que l’on connaisse l’Entry Pont du programme Shrinké, SoftIce ne rendant pas la main en lançant le programme cible via le Symbol Loader, vous ne pourrez pas poser un breakpoint sur celui ci , mais vous pouvez utiliser différentes astuces pour lui forcer la main :
La méthode de TeeJi :
" On peut mettre un BreakPoint sur GetProcAddress qui est exécuté un max de fois au lancement de chaque programme. Donc vous allez dans softice, vous faite bpx GetProcAddress puis [F5]. Vous lancer le fichier compressé et normalement, vous arrivez dans softice. Vous faites alors [F11] comme un fou jusqu'à ce que vous soyez dans le code de la cible ( vous devez voir son nom marqué sur la bar en dessous de la partie code dans Softice ). Vous le faite une bonne trentaine de fois ( j'ai pas compté ;) Et quand vous y êtes, vous virez le BreakPoint ( BC* ) et vous faite [F12] pour sortir du call "
Mais ma préférence va à la méthode de Psyché :
Psyché propose de forcer le programme à s’arrêter à l’endroit désiré en utilisant l’interruption 3 :
Le principe consiste à remplacer un octet de la cible shrinkée soit à l’Entry Point, soit à un autre endroit de votre choix. Les codes à ce niveau étant clean, vous trouverez votre bonheur en utilisant un éditeur hexadécimal (Hiew m’a paru le plus intéressant pour ce genre d’intervention…)
:007C84D6 CC > vous placez un CC (INT 3) à l’adresse qui correspond aux codes donnés par procDump, et à l’aide d’un BPINT 3 (point d’arrêt sur interruption 3) entré sur la ligne de commande de SoftIce, vous obtiendrez un break en lançant l’application. Remettez les octets en place (PUSH DWORD PTR [EBP+10]) si vous ne voulez pas faire planter le système.
Vous êtes prêt à passer à l’étape suivante :
Trouver de la place
Il faut trouver un espace suffisant pour pouvoir y placer les codes du patch à écrire, et dans une zone qui ne sera pas écrasée lors de la décompression, ni qui pourra être utilisée par Shrinker. Recherchez des zones contenant suffisamment de 00 pour pouvoir accueillir votre Patch, et contrôler à l’aide d’un BPR que le programme ne va rien y écrire . Vous trouverez (presque) toujours quelques octets inutilisés à la fin du fichier (ou en fin de section). Ce sont des octets nuls (0000) :
00000000000000000000 BYTE 10 DUP(0)
00000000000000000000 BYTE 10 DUP(0)
00000000000000000000 BYTE 10 DUP(0)
00000000000000000000 BYTE 10 DUP(0)
(A lire: "ASPack - le compresseur décompressé" par Psyché)Voici une autre méthode proposée par TeeJi:
|
Dans le projet sur les PE Packed, il est parfois impossible d'insérer notre procédure de modification. Il faut alors rajouter du code ou, en d'autre terme, augmenter la grandeur d'une section, voir rajouter une section. Nous commencerons par augmenter une section de 0x1000 bytes ( assez pour écrire notre patch je crois hein !? :) et nous terminerons par le rajout manuel d'une section à la fin du fichier. Je voudrais remercier Christal qui m'accompagne pleinement dans ce projet. Augmenter la taille de la dernière section Pour cet essai, je vais augmenter la derniere section ( il est preferable de modifier la derniere section car sinon de nombreux problèmes d'adresse vont apparaître) de NotePad. Jettons d'abord un oeil aux différentes caractéristiques des sections de NotePad : Disassembly of File: Notepad.exe Number of Objects = 0005 (dec), Imagebase = 00400000h Object01: .text RVA: 01000 VSize: 03E9C RawOffset: 01000 RawSize: 04000 Flags: 60000020 Object02: .data RVA: 05000 VSize: 0084C RawOffset: 05000 RawSize: 01000 Flags: C0000040 Object03: .idata RVA: 06000 VSize: 00DE8 RawOffset: 06000 RawSize: 01000 Flags: 40000040 Object04: .rsrc RVA: 07000 VSize: 06000 RawOffset: 07000 RawSize: 06000 Flags: 40000040 Object05: .reloc RVA: 0D000 VSize: 00A9C RawOffset: 0D000 RawSize: 01000 Flags: 42000040 l'Offset de chaque section doit être un multiple
de l'Offset du Code. Ici : 00001000. Now the file-header, which will start at byte 0x44 and is 0x14 bytes long: Machine 4C 01 ; i386 NumberOfSections 02 00 ; code and data TimeDateStamp 00 00 00 00 ; who cares? PointerToSymbolTable 00 00 00 00 ; unused NumberOfSymbols 00 00 00 00 ; unused SizeOfOptionalHeader E0 00 ; constant Characteristics 02 01 ; executable on 32-bit-machine PointerToSymbolTable : 00000000
Now we set up the data directories, beginning at byte
0xb8 and being 0x80 bytes long: 00 60 00 00 8C 00
00 00 ; IMAGE_DIRECTORY_ENTRY_IMPORT (1) dans NotePad Il n'y aura donc rien a modifier au valeur des addresses des Directories car la derniere section commence en 0000D000. Rem : Je n'ai aucune idée si il faudra parfois modifier ces valeurs ! Sous HView, la dernière ligne de code de NotePad est celle-ci : .0040DFF0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 Nous devons tous faire pour que cette dernière ligne soit après modification : .0040EFF0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 Nous allons donc insérer 0x1000 bytes a la fin du fichier.. pour ce faire, aller sous HexWorkShop et ouvrez Notepad.exe. Situé votre curseur tout à la fin du fichier, cliquez avec le bouton droit de votre souris et selectionner Insérrer. Mettez 1000 et cochez Hexa. Faite OK et le code est à présent rajouté. Sauvez et faite un Backup de Notepad.exe. Si vous exécutez à présent le Notepad modifié, il n'y a aucuns problème. Nous allons maintenant, à l'aide de ProcDump modifier les différentes caractéristiques de la dernière sections. Rappelons d'abord les différentes infos de cette section : Object05: .reloc RVA: 0000D000 VSize: 00000A9C RawOffset: 0000D000 RawSize: 00001000 Flags: 42000040 Lancez ProcDump, clickez PE Editor et selectionner le NotPad.exe modifié. Clickez sur Section, puis Right-click sur .reloc et faite modifier, mettez PSize et VSize à 2000. Ok Ok Ok. Maintenant, la dernière section à une grandeur de 0x2000 sur disque et en mémoire et possède 0x1000 bytes vierge à utiliser à notre convenance. Pour vérifier, nous allons dévier les premières instruction vers notre espace vierge. Avec HView allez à l'entry-point et on voit : .004010CC: 55 push ebp .004010CD: 8BEC mov ebp,esp .004010CF: 83EC44 sub esp,044 ;"D" .004010D2: 56 push esi .004010D3: FF15E0634000 call GetCommandLineA ;KERNEL32.dll allez maintenant en .0040E518 ( addresse en plein milieu de l'espace fraichement rajouté ) et recopiez-y toutes ces instructions. Il n'y aura pas de problème car c'est un CALL et un CALL ne dépend pas de son addresse. et mettez un JMP .0040E518 en .004010CC:. Rajoutez aussi un JMP 004010D9 a la fin du code recopié en 0040E518. Donc après modification, ca doit donner quelque chose comme cela : .004010CC: E947D40000 jmp .00040E518 -------- (1) ... .0040E518: 55 push ebp .0040E519: 8BEC mov ebp,esp .0040E51B: 83EC44 sub esp,044 ;"D" .0040E51E: 56 push esi .0040E51F: FF15E0634000 call GetCommandLineA ;KERNEL32.dll .0040E525: E9AF2BFFFF jmp .0004010D9 -------- (1) .0040E52A: 0000 add [eax],al Sauvez et relancez NotePad pour voir si nos modifications fonctionnent, et il n'y a pas de problème. Nous venons donc de rajouter 0x1000 bytes à un programme avec Succès, BRAVO ! Rajout manuel d'une section
Rajouter une section va donc modifier plusieurs chose, nous allons d'abord modifier différentes infos se trouvant dans le File Header et l'Optional Header, puis rajouter le code dans Section Header qui décrira notre nouvelle section et finalement nous rajouterons du code à la fin du fichier. Je ne sais pas si d'autres étapes seront nécessaires.
FILE HEADER NumberOfSections 02 00 ; ici 2 sections OPTIONAL HEADER SizeOfImage c0 00 00 00 ; la somme de la grandeur de toutes les sections Regardons maintenant la structure du Section Header : Name 2E 63 6F 64 65 00 00 00 ; ".code" VirtualSize 00 00 00 00 VirtualAddress A0 01 00 00 SizeOfRawData 20 00 00 00 PointerToRawData A0 01 00 00 PointerToRelocations 00 00 00 00 PointerToLinenumbers 00 00 00 00 NumberOfRelocations 00 00 NumberOfLinenumbers 00 00 Characteristics 20 00 00 60 Donc une Section Header prend 40 Bytes soit 0x28 Bytes. Après la déclaration des Sections, on rajoute des 00 pour rester aligné et ensuite ce sont les sections proprement dites.
Name 2E 54 65 65 4A 69 00 00 ; ".TeeJi" VirtualSize 00 10 00 00 ; VirtualSize = RawSize = 0x1000 VirtualAddress ?? ?? ?? ?? ; nous ne savons pas encore SizeOfRawData 00 10 00 00 ; VirtualSize = RawSize = 0x1000 PointerToRawData ?? ?? ?? ?? ; nous ne savons pas encore PointerToRelocations 00 00 00 00 ; inutilisé PointerToLinenumbers 00 00 00 00 ; inutilisé NumberOfRelocations 00 00 ; inutilisé NumberOfLinenumbers 00 00 ; inutilisé Characteristics 20 00 00 60 ; code, exécutable, readable :) Nous devons maintenant définir la valeur de VirtualAddress et PointerToRawData. Pour cela, nous devons tenir compte des autres section dont voici les informations : Code Offset = 00001000, Code Size = 00004000 Object01: .text RVA: 1000 VSize: 3E9C RawOffset: 1000 RawSize: 04000 Flags: 60000020 Object02: .data RVA: 5000 VSize: 084C RawOffset: 5000 RawSize: 01000 Flags: C0000040 Object03: .idata RVA: 6000 VSize: 0DE8 RawOffset: 6000 RawSize: 01000 Flags: 40000040 Object04: .rsrc RVA: 7000 VSize: 6000 RawOffset: 7000 RawSize: 06000 Flags: 40000040 Object05: .reloc RVA: D000 VSize: 0A9C RawOffset: D000 RawSize: 01000 Flags: 42000040 La dernière section nous intéresse tout particulièrement. RVA : 0000D000 et VSize : 00000A9C donc cette section s'étend de 0000D000 à 0000DA9C nous mettrons donc notre section avec RVA : 0000E000 et VSize : 00001000. notre section s'étendra donc de 0000E000 à 0000F000 ! Maintenant, pour le RawOffset ( = PointerToRawData ) il doit être un multiple du Code Offset ( ici, il vaut 00001000 ) et ne doit pas empiéter sur la section précédente, donc pour .reloc : RawOffset : 0000D000 et RawSize : 00001000 donc nous pouvons mettre le RawOffset de notre section à 0000E000. Maintenant les infos de notre section sont : Name 2E 54 65 65 4A 69 00 00 ; ".TeeJi" VirtualSize 00 10 00 00 ; VirtualSize = RawSize = 0x1000 VirtualAddress 00 E0 00 00 ; RVA = 0x0000E000 SizeOfRawData 00 10 00 00 ; VirtualSize = RawSize = 0x1000 PointerToRawData 00 E0 00 00 ; RawOffset = 0x0000E000 PointerToRelocations 00 00 00 00 ; inutilisé PointerToLinenumbers 00 00 00 00 ; inutilisé NumberOfRelocations 00 00 ; inutilisé NumberOfLinenumbers 00 00 ; inutilisé Characteristics 20 00 00 60 ; code, exécutable, readable :) Allons maintenant sous Hview et rajoutons le code de notre Section Header juste après celui de .reloc : 00000210: 00 00 00 00-40 00 00 40-2E 72 65 6C-6F 63 00 00 @ @.reloc 00000220: 9C 0A 00 00-00 D0 00 00-00 10 00 00-00 D0 00 00 £ ð ð 00000230: 00 00 00 00-00 00 00 00-00 00 00 00-40 00 00 42 @ B 00000240: 2E 54 65 65-4A 69 00 00-00 10 00 00-00 E0 00 00 .TeeJi Ó 00000250: 00 10 00 00-00 E0 00 00-00 00 00 00-00 00 00 00 Ó 00000260: 00 00 00 00-20 00 00 60-00 00 00 00-00 00 00 00 ` Maintenant que cela est fait, nous allons modifier les infos NumberOfSection du FileHeader et SizeOfImage du OptionalHeader. Grace à ProcDump vous pouvez modifier l'ImageSize facilement, vous lui rajoutez 0x1000 donc 0000E000 devient 0000F000 et vous sauvez. Pour NumberOfSection, si vous ne voulez pas rechercher ( il est à 6 bytes de la signature PE ) vous pouvez utiliser eXeScope et regarder quel est son offset. Avec HView : 00000080: 50 45 00 00-4C 01 05
00-65 91 46 35-00 00 00 00 PE L eæF5 ; 05 sections Vous remplacez 05 par 06 ( car on a rajouté une section :). Maintenant nous allons rajouter le code de la section ( soit 0x1000 bytes ) à la fin du fichier. Pour cela vous utilisez HexWorkShop, vous ouvrez NotePad.exe, vous vous placez à la fin du fichier, vous Right-Clickez et sélectionnez Insérer. Vous mettez 1000 et cochez Hexa. Ok. Vous sauvez ! Vous lancez NotePad et tout fonctionne correctement ! :) Vous pouvez vérifier avec ProcDump que tout est correct, et vous pouvez faire la même manipulation que tout à l'heure pour vérifier que tout fonctionne vraiment bien ( déviation du code à l'Entry-Point ). Disassembly of File: Notepad.exe Code Offset = 00001000, Code Size = 00004000 Data Offset = 00005000, Data Size = 00001000 Number of Objects = 0006 (dec), Imagebase = 00400000h Object01: .text RVA: 00001000 Offset: 00001000 Size: 00004000 Flags: 60000020 Object02: .data RVA: 00005000 Offset: 00005000 Size: 00001000 Flags: C0000040 Object03: .idata RVA: 00006000 Offset: 00006000 Size: 00001000 Flags: 40000040 Object04: .rsrc RVA: 00007000 Offset: 00007000 Size: 00006000 Flags: 40000040 Object05: .reloc RVA: 0000D000 Offset: 0000D000 Size: 00001000 Flags: 42000040 Object06: .TeeJi RVA: 0000E000 Offset: 0000E000 Size: 00001000 Flags: 60000020 Dernière Note Maintenant, nous pouvons patcher tous les programme packed sans problème, à condition qu'ils ne vérifient pas le nombre de sections ou d'autres choses dans le style. Cette contribution va me permettre aussi d'aborder petit à petit le Reverse Engineering et le rajout de fonctions. J'aimerais encore une fois remercier Christal pour tout ce qu'il fait, et faire part de ma désapprobation à ceux qui trouvaient l'idée de ce cours stupide. Enfin je vous laisse seul juge ! Amicalement, |
L'illustration par l'exemple, le cas : Apis32 de Vitaly Evseenko by TeeJi
Implanter votre Patch
Dans le cas de HomeSite 4.0, voici la solution que j’avais retenue :
A la sortie du deuxième break sur un BPX getLocalTime, en traçant avec F10, vous arriverez ici:
* Reference To: kernel32.GetLocalTime, Ord:0000h > saisie de la date réelle | :0040A390 E827CAFFFF Call 00406DBC :0040A395 668B4C240E mov cx, word ptr [esp+0E] jour = 30 :0040A39A 668B54240A mov dx, word ptr [esp+0A] mois = 08 :0040A39F 668B442408 mov ax, word ptr [esp+08] an = 1999 :0040A3A4 E81FFEFFFF call 0040A1C8 :0040A3A9 DD1C24 fstp qword ptr [esp] :0040A3AC 9B wait :0040A3AD DD0424 fld qword ptr [esp] :0040A3B0 83C418 add esp, 00000018 :0040A3B3 C3 retIl peut y avoir différentes manières de contourner le contrôle du temps qui passe, mais ce qui m’a semblé le plus simple, était de placer la date d'installation à la place de la date réelle saisie par GetLocalTime. Ainsi, HomeSite se croira toujours au 1er jour de la période d'essai, et ceci Ad Vitam Eternam.
Voici l'allure que ça va prendre:* Reference To: kernel32.GetLocalTime, Ord:0000h | :0040A390 E827CAFFFF Call 00406DBC :0040A395 66B91E00 mov cx, 001E 30 :0040A399 90 nop :0040A39A 668BA0800 mov dx, 0008 août :0040A39E 90 nop :0040A39F 668BCF07 mov ax, 07CF 1999 :0040A3A3E 90 nop :0040A3A4 E81FFEFFFF call 0040A1C8Il faut maintenant écrire un Patch qui ira écraser les codes de HomeSite, après que la décompression ait eu lieu, et avant que Shrinker ne se branche sur l’entry point du programme d’origine :
Le Patch :
Petit rappel : une inscription en mémoires supérieure à 8 bits se fait " à l’envers ", d’ou par exemple un B001 (mov bl,01) s’écrirai 01B0. Psyché
:007C9D1A FF257C637C00 jmp dword ptr [007C637C] :007C9D20 FF2580637C00 jmp dword ptr [007C6380] > fin de Shrinker * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:007C84DC(U) > jump qu'il faudra provoquer pour aller lire ce Patch | :007C9D26 C70595A3400066B91800 mov dword ptr [0040A395], 0018B966 Jour :007C9D30 C60599A3400090 mov byte ptr [0040A399], 90 Nop :007C9D37 C7059AA3400066BA0800 mov dword ptr [0040A39A], 0008BA66 Mois :007C9D41 C6059EA3400090 mov byte ptr [0040A39E], 90 Nop :007C9D48 C7059FA3400066B8CF07 mov dword ptr [0040A39F], 07CFB866 An :007C9D52 C605A3A3400090 mov byte ptr [0040A3A3], 90 Nop :007C9D59 FF7508 push [ebp+08] > restore les octets écrasés :007C9D5C FF55E0 call [ebp-20] > par le jump, et c'est parti ! :007C9D5F 00000000000000000000 BYTE 10 DUP(0) :007C9D69 00000000000000000000 BYTE 10 DUP(0)Faites ces modifications une première fois en mémoire, puis utilisez un éditeur hexadécimal pour les rendre définitive, puis vérifiez à l’aide de SoftIce (et du BPINT 3) que ces octets ne sont pas modifiés au moment de la décompression. Sinon, il faudra trouver une autre place (éventuellement en prenant la place de l’icône du programme…)
L’Adressage :
Votre Patch n'a pas bougé ?
Vous pouvez passer au saut qui va s'y rendre.
Ce saut doit être placé après la décompression, et avant que Shrinker ne passe la main à HomeSite :
Et donc je vous propose de remplacer ::007C84D6 FF7510 push [ebp+10] > codes repérés dans Script.ini :007C84D9 FF750C push [ebp+0C] :007C84DC FF7508 push [ebp+08] :007C84DF FF55E0 call [ebp-20] > lancement du prog décompacté :007C84E2 8945E4 mov dword ptr [ebp-1C], eaxPar ceci :
:007C84D6 FF7510 push [ebp+10] :007C84D9 FF750C push [ebp+0C] :007C84DC E945180000 jmp 007C9D26 > saut vers le Patch :007C84E1 90 nop :007C84E2 8945E4 mov dword ptr [ebp-1C], eaxEncore une fois, testez, en mémoire, le bon fonctionnement de votre saut et de votre Patch, et si tout c'est bien passé, finalisez tout ça avec votre hexéditeur.
Vous voilà avec une version shrinké, patché, et fonctionnel…avec les commentaires de TeeJi
Création d’un DUMP
Dans certain cas, ProDump n'est pas en mesure de reconnaître la protection utilisée, souvent parce qu'il ne la connait pas... Nous allons changer un peu de méthode, et créer un Dump d’Explor2000, programme protégé par Néolite
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 " choisissez l'option " Edit section " . Dans la case " Section characteristics " , ProcDump vous indique : 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. Au break, passez en mode assemblage, et changez le jmp eax par un jmp eip. Ainsi, vous obligerez le programme à boucler sur lui même.
Rouvrez 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.
A lire: création d'un Dump pour un programme Tri-ASPacké: Advanced Redistry Tracer by aRTex