NotePad
Défi FCF 2000
By Christal
Avant Propos :
Le 11 AVRIL 1999, le Site de La Main Rouge proposait son cinquième défi, sur l'initiative de Xose :
" Le boulot : Tout simplement modifier notepad. En effet, vous savez que les documents ouverts par défaut sont de type *.txt, ce qui est plus qu'ennuyant... En fait, ça serait *.asm, ça serait mieux pour nous, non ? Ou bien choisir *.asm, *.bat, *.* etc...Donc le défi c'est de modifier notepad pour le rendre plus convivial, pour finir le travail bâclé des programmeurs de M$.
L'idée de ce défi me vient après avoir lu l'excellent article de +Mammon à ce sujet. Il contient des éléments très intéressants, et un début de solution (ce n'est qu'un début...). Si les réponses pouvaient être claires pour les newbies (expliquer comment marche une API, etc...) ce serait cool !. Allez donc faire un tour chez notre maître +Mammon ".
A cette époque, je ne savais même pas ce que le mot Cracking aurait bien pu vouloir dire...
S'il y a des +crackers, j'étais un -Newbie.
Depuis j'ai pris du galon...
j'ai enlevé le - !
En Avril 2000, soit 1 an plus tard, le site de FCF 2000 proposait de refaire le même défi que celui de la Main Rouge qui n'avait pas eu d'écho :
" - 2éme partie il s'agit ici d'apporter quelques améliorations au notepad :-) il s'agit de rajouter du code dans le notepad : ici la création est libre de s'exprimer : on peut ajouter des Anti-Si pour améliorer la protection on peut rajouter un nag au démarrage du notepad ou encore modifier l'apparence en rajoutant un menu ou en modifiant les menus existants .... (Bien évidemment tout les tools existant peuvent être utilisés)
je vous conseille cependant de garder un petit moment pour protéger votre petit bijoux et ses améliorations car si quelqu'un arrive a enlever vos modifications vous aurez perdu "
Au départ, mon idée était tout simplement de traduire le texte de +Mammon, mais 40 pages à traduire, même dans un anglais parfaitement compréhensible (le privilège des non anglo-saxons ?)...
Je me suis donc dis que je pourrais m'inspirer de ce texte, en limitant le plagiat au maximum, mais en gardant les grandes lignes du tutoriel de +Mammon.
Il y a une partie que je n'ai pas abordée, c'est la limitation du Bloc-Notes à des fichiers de 32ko, et pour plusieurs raisons :
- NotePad.exe n'est pas limité par une forme de protection du genre " SI > 32 Ko alors WORDPAD ", mais l'est tout simplement par la fonction EDIT qu'il utilise, contrairement à la fonction RICHEDIT utilisée par WordPad.exe
- Les explications de +Mammon sont amplement suffisantes et compréhensibles
- Le NotePad relooké de +Mammon a malgré tout de sérieux problèmes à fonctionner de façon systématique (testé sur trois PC, deux Win95 avec des versions différentes et Win98).
- Pour finir, je suis incapable d'arriver à un résultat similaire par un autre moyen, et ce n'est pas faute d'avoir essayé ! Le mieux de ce que j'ai pu obtenir et d'ouvrir un fichier quelle que soit sa taille, mais tronqué au-delà des 32 ko fatidiques.
|
Au programme :
le "&" précise que le caractère suivant sera souligné
et accessible par une combinaison clavier ALT+Caractère. 6300 2D00 6E00 6F00 7400 6500 7300 0000 s. .d.u. .B.l.o. 9000 2600 4E00 6500 7700 2000 4F00 7000 ..&.N.e.w. .O.p. 7400 6900 6F00 6E00 0000 0000 1400 2600 t.i.o.n.......&. 5300 6800 6F00 7700 2000 5400 6800 6500 S.h.o.w. .T.h.e. 6D00 0000 8100 1500 2600 4400 E900 7400 m.......&.D...t. 6500 6300 7400 6900 6F00 6E00 0000 0000 e.c.t.i.o.n..... Si on regarde au niveau de l'Item &Détection, on trouve ses caractéristiques
(Grayed = 81) et son Identificateur (15h = 20d). .text RVA: 00001000 Offset: 00001000 Size: 00004000 Flags: 60000020 .data RVA: 00005000 Offset: 00005000 Size: 00001000 Flags: C0000040 .idata RVA: 00006000 Offset: 00006000 Size: 00001000 Flags: 40000040 .reloc RVA: 00007000 Offset: 00007000 Size: 00001000 Flags: 42000040 .rsrc RVA: 00008000 Offset: 00008000 Size: 00006000 Flags: 40000040 Vous remarquerez une première chose, les RVA (Relative Virtuel Address)
et les Offsets sont identiques pour chaque section. Voilà qui va simplifier le passage entre SoftIce et
un éditeur hexadécimale, les sections sont alignées. Code Offset = 00001000, Code Size = 00004000 Data Offset = 00005000, Data Size = 00001000 La taille du Code étant de 00001000, la taille de chaque section sera un
multiple de 1000h. .text 3E9C .data 084C .idata 0DE8 .reloc 0A9C .rscr 6000 Par exemple la section .idata à une taille réelle de 0x0DE8 pour
une Raw Size de 0x1000 soit une différence de 0x1000 - 0x0DE8 = 0x0218 ou encore 536 octets. 00006DC0 6743 7265 6174 654B 6579 4100 9400 5265 gCreateKeyA...Re 00006DD0 674F 7065 6E4B 6579 4100 4144 5641 5049 gOpenKeyA.ADVAPI 00006DE0 3332 2E64 6C6C 0000 0000 0000 0000 0000 32.dll.......... 00006DF0 0000 0000 0000 0000 0000 0000 0000 0000 ................ A la suite de ces petits calculs, on se rend vite compte qu'il y a largement de
quoi faire, et que la place ne manque pas. Vous verrez un peu plus tard qu'il y aussi de la place "disponible"
directement en réécrivant sur le code lui même... MENUITEM "&Couper\tCtrl+X", 768, GRAYED MENUITEM "Co&pier\tCtrl+C", 769, GRAYED MENUITEM "C&oller\tCtrl+V", 770, GRAYED MENUITEM "&Supprimer\tDel", 771, GRAYED les valeurs semblant significatives, ou du moins plus évidentes à
localiser que les 1, 2, 3 ... 21 des autres Items: :0040125E 83FE20 cmp esi, 00000020
:00401261 8BC6 mov eax, esi
:00401263 7F1A jg 0040127F
:00401265 0F84F9040000 je 00401764
:0040126B 48 dec eax
:0040126C 83F81B cmp eax, 0000001B
:0040126F 773F ja 0040112B
:00401271 0FB688FB184000 movzx ecx, byte ptr [eax+004018FB]
:00401278 FF248DBB184000 jmp dword ptr [4*ecx+004018BB]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401263(C)
|
:0040127F 83F825 cmp eax, 00000025
:00401282 0F846B030000 je 004015F3
* Possible Ref to Menu: MenuID_0001, Item: "Couper Ctrl+X"
|
:00401288 3D00030000 cmp eax, 00000300
:0040128D 7C21 jl 004012B0
Un Bpx sur 0040127F va donner un break si, et seulement si, une action Ctrl+X est
commandée. Donc c'est plus haut que la gestion des autres événements commencent. :00401271 0FB688FB184000 movzx ecx, byte ptr [eax+004018FB] :00401278 FF248DBB184000 jmp dword ptr [4*ecx+004018BB] Que tout ce décide!
Par exemple notre Item Show me a un ID = 14h. 00001900 0F04 0506 0708 090F 0A0B 0F0F 0F0F 0F0F ................ 00001910 0F0F 0F0C 0F0D 0E56 5733 F656 E825 0100 .......VW3.V.%.. Petit contrôle à l'adresse dans la table susceptible de recevoir un
Dword. Pas de problème, elle est squattable sans flanquer la pagaille. (cf +Mammon qui indique dans son
tut qu'entre 14d et 21d, il est possible de trouver une place dans cette table). :00401265 0F84F9040000 je 00401764 :0040126B 48 dec eax :0040126C E93C400000 jmp 004052AD Où on commence par restaurer les octets écrasés par le jmp: cmp eax, 0000001B ja 004012B0 Puis on passe au traitement des événements liés à nos nouveaux menus: :004052AD 3DB1000000 CMP EAX,000000B1 :004052B2 0F87F8BFFFFF JA 004012B0 :004052B8 3D13000000 CMP EAX,00000014 -> Item "show me" :004052BD 740C JZ 004052CB -> Ok ? -> saute :004052BF 3D14000000 CMP EAX,00000014 -> Item "détection" :004052C4 740C JZ 004052D2 -> Ok ? -> saute :004052C6 E9A6BFFFFF JMP 00401271 -> retour au programme "normal" :004052CB B8F06D4000 MOV EAX,00406DF0 -> vers patch 2 :004052D0 FFE0 JMP EAX :004052D2 B80D6E4000 MOV EAX,00406E0D -> vers patch 3 :004052D7 FFE0 JMP EAX Le traitement des sauts vers les Patchs auraient pu être plus direct (jmp
Patch) au lieu d'un premier saut conditionnel, puis d'un mov adresse_patch, jmp patch, mais dans la mesure où
le cadre du défi suggérait un renforcement de la protection, j'ai préféré des
jump eax qui ne permettront pas de retrouver facilement les lignes ci dessus à partir des indications de
Wdasm. MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box );
6A00 Push 00 > bouton OK -> MB_OK (style of message box) 68B0D54000 Push 0040D5B0 > adresse du titre de la MessageBox 6810D64000 Push 0040D610 > adresse du message 6A00 Push 00 > Handle de la fenêtre (si 00, pas de fenêtre attribuée) E82BD3B4BF Call messageBoxA > appel de l'API B813000000 Mov Eax, 13 > remise à 13h de EAX E9644FFFF Jmp 00401271 > retour à la normale. Le paramètre à la sortie de l'API MessageBox influant sur EAX, il
faut que la valeur de ce registre soit restaurée au risque, sinon, de vous retrouvez dans la nature à
cause du jmp dword ptr [4*ecx+004018BB], l'adresse de la table en 004018BC ne correspondant à rien. :00406E0D 6A00 PUSH 00 > MB_OK :00406E0F 68B0D54000 PUSH 0040D5B0 > titre MessageBox :00406E14 803D5ED5400004 CMP BYTE PTR [0040D55E],04 > Détection activée ? :00406E1B 750E JNZ 00406E2B > non -> saute :00406E1D 6890D64000 PUSH 0040D690 > oui -> "désactivation" :00406E22 C6055ED5400003 MOV BYTE PTR [0040D55E],03 > Flag " SI non détectable " :00406E29 EB0C JMP 00406E37 > suite MessageBox :00406E2B 68B0D64000 PUSH 0040D6B0 > "Activation" anti SI :00406E30 C6055ED5400004 MOV BYTE PTR [0040D55E],04 > Flag " SI détectable " :00406E37 6A00 PUSH 00 > handle fenêtre :00406E39 E8F0D2B4BF CALL USER32!MessageBoxA > affichage :00406E3E B814000000 MOV EAX,00000014 > restauration état EAX :00406E43 E929A4FFFF JMP 00401271 > retour à la normale Le titre de la Boite de message et le Bouton OK étant commun aux deux cas
de figure, le test 00406E14 va seulement déterminer quel est l'état en cours de la détection
(active ou inactive) et l'inverser avant d'afficher le message "Détection activée" ou "détection
désactivée". Ces deux messages ont été écrits par-dessus les informations
de la boite About aux offsets D690 et D6B0 à l'aide d'un éditeur hexadécimal. ShellAbout (
HWND hWnd, // handle of parent window
LPCTSTR szApp, // title bar and first line text
LPCTSTR szOtherStuff, // other dialog text
HICON hIcon // icon to display
);
Vous remarquerez qu'une Icône est attendue. Cela aura son intérêt
tout à l'heure. 000018E0 1540 001C 1540 00AD 1840 008A 1540 00A4 .@...@...@...@.. Soit à l'adresse 004018AD. :004014EC 50 PUSH EAX > handle de l'application :004014ED FF15C8644000 CALL [USER32!LoadIconA] :004014F3 50 PUSH EAX > icône à afficher :004014F4 6800104000 PUSH 00401000 > texte :004014F9 FF3564504000 PUSH DWORD PTR [00405064] > title bar :004014FF FF3500504000 PUSH DWORD PTR [00405000] > handle de la fenêtre :00401505 FF15F8634000 CALL [SHELL32!ShellAboutA] La Boite "A propos du Bloc-Notes" faisant apparaître une icône, le début de l'affichage de la boite en question commence en 004014EC. HICON LoadIcon(
HINSTANCE hInstance, // handle of application instance
LPCTSTR lpIconName // icon-name string or icon resource identifier
);
Il est important, en cas de bidouilles au niveau des APIs de savoir ce qui a été
poussé sur la pile au risque sinon de voir votre patch planter le système. Suivant les cas, soit
vous aurez à placer une dérivation avant les Push susceptibles de pouvoir être problématiques,
soit de Poper la pile. ShellAbout (
HWND hWnd, // handle de la fenêtre
LPCTSTR szApp, // title bar et première ligne de texte
LPCTSTR szOtherStuff, // autre dialog text
HICON hIcon // icon à afficher
);
Il est maintenant facile d'opter pour deux solutions:
J'ai choisi la seconde solution, beaucoup plus "propre" à mon
avis, en plaçant 00406E48 dans la table à l'offset 18E7.
La boite en question affichera "SoftIce détecté", ou seulement le message "FCF 2000/Reverse Enginnering". :00406E48 6A00 PUSH 00 > MB_OK :00406E4A 68B0D54000 PUSH 0040D5B0 > titre "ChrisPad" :00406E4F 803D5ED5400004 CMP BYTE PTR [0040D55E],04 > détection activée :00406E56 7407 JZ 00406E5F > non -> saute :00406E58 6A00 PUSH 00 > hTemplateFile :00406E5A EB14 JMP 00406E70 > détection désactivée :00406E5C 90 NOP > bah! :00406E5D EB05 JMP 00406E64 > Bof! :00406E5F 68D5D54000 PUSH 0040D5D5 > FCF 2000 etc... :00406E64 6A00 PUSH 00 > handle fenêtre :00406E66 E8C3D2B4BF CALL USER32!MessageBoxA :00406E6B E93DAAFFFF JMP 004018AD > End proc :00406E70 6880000000 PUSH 00000080 > dwFlagsAndAttributes :00406E75 6A03 PUSH 03 > dwCreationDistribution :00406E77 6A00 PUSH 00 > lpSecurityAttributes :00406E79 6A03 PUSH 03 > dwShareMode :00406E7B 68000000C0 PUSH C0000000 > dwDesiredAccess :00406E80 6814104000 PUSH 00401014 > lpFileName -> \\.\SICE :00406E85 E8510CB7BF CALL KERNEL32!CreateFileA :00406E8A 3DFFFFFFFF CMP EAX,FFFFFFFF > Sice Détecté? :00406E8F 74CE JZ 00406F5F > non -> saute :00406E91 68C0D54000 PUSH 0040D5C0 > "SoftIce Detected" :00406E96 EBCC JMP 00406F64 > retour le \\.\SICE ayant été écrit au préalable sous éditeur hexa à l'offset 1014 HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
Mais en procédant ainsi pour la détection de Sice, vous avez de fortes
probabilités de trouver des références disgracieuses dans le Dead listing, sans parler d'une
bête recherche sur "CreateFileA". :00406E80 6814104000 PUSH 00401014 > lpFileName -> \\.\SICE :00406E85 E8510CB7BF CALL KERNEL32!CreateFileA :00406E8A 3DFFFFFFFF CMP EAX,FFFFFFFF Vous avez 15 octets à coder, soit 3 DWORD, 1 WORD et 1 BYTE. :00406E80 Mov Dword Ptr [00406EX1], 00401014
Mov Dword Ptr [00406EX5], 68BFB70C
Mov Dword Ptr [00406EX9], 51E8FFFF
Mov Word Ptr [00406EXD], FFFF
Mov Byte Ptr [00406EXF], 3D
:00406EX1 ADD [EAX], AL -> 0000 > espace réservé pour la décompression dynamique
ADD [EAX], AL -> 0000
ADD [EAX], AL -> 0000
-> 00
:00406EY0 Suite du programme
Les Mov écrivent dans leur espace réservé les 3 lignes à
" cacher ", puis le programme les exécute, avant de continuer comme si de rien n'était. Pushad > sauvegarde des registres mov ESI, 0040D850 > adresse de départ mov EDI, 00406E48 > adresse d'arrivée Mov ECX, 50 > taille du bloc à déplacer Repz Movsb > déplacement Une fois le repz Movsb exécuté, la ligne suivante commence par la
routine déplacée, et finissent par POPAD (restitution de l'état des registres). :004010FE 803E00 CMP BYTE PTR [ESI],00 :00401101 740B JZ 0040110E :00401103 803E20 CMP BYTE PTR [ESI],20 :00401106 7F06 JG 0040110E :00401108 46 INC ESI :00401109 803E00 CMP BYTE PTR [ESI],00 :0040110C 75F5 JNZ 00401203 :0040110E B9CED64000 MOV ECX,0040D6CE > pousse l'adresse d'arrivée :00401113 51 PUSH ECX > sur la pile, et simule :00401114 C3 RET > une fin de call Avec un Push ECX pour ne pas rendre trop facile une recherche sur un JMP EAX déjà
utilisé. : 0040D6CE Push 00 > iReadWrite Push 00401014 > \\.\SICE call _lopen > pour éviter un CreateFileA Inc eax > évite le FFFFFFFF trop facile à repérer cmp eax, NULL > Sice detected? Jne 0040D6E1 > non -> retour à la normale Jmp 0040D6DA > oui -> met le Flag "SICE Detected" à 3 L'avantage de _lopen est son petit nombre de paramètres à pousser sur la pile: HFILE _lopen(
LPCSTR lpPathName, // pointer to name of file to open
int iReadWrite // file access mode
);
Fin pour le moment des Anti XXX, il est temps de passer à autre chose. BOOL GetOpenFileName(
LPOPENFILENAME lpofn // address of structure with initialization data
);
1 seul paramètre est nécessaire à cette API. :00401423 A38C564000 mov dword ptr [0040568C], eax :00401428 E8633A0000 Call comdlg32.GetOpenFileNameA Pour autant, rien à faire pour trouver dans les parages quoi que ce soit en lien avec ce que je cherchai. Et puis j'ai fait un petit tour dans mon éditeur hexa : 00001050 2A2E 2A00 4564 6974 0000 0000 2200 0000 *.*.Edit...."... 00001060 2E74 7874 0000 0000 2000 0000 E903 0000 .txt.... ....... Hey ! 0000B800 5C00 2A00 2E00 7400 7800 7400 0B00 6E00 \.*...t.x.t...n. Et quelques recherches de plus : 0000BA50 4400 6F00 6300 7500 6D00 6500 6E00 7400 D.o.c.u.m.e.n.t. 0000BA60 7300 2000 7400 6500 7800 7400 6500 0A00 s. .t.e.x.t.e... 0000BA70 5400 6F00 7500 7300 2000 2800 2A00 2E00 T.o.u.s. .(.*... 0000BA80 2A00 2900 0000 0000 CE00 5600 6F00 7500 *.).......V.o.u. Voici les éléments du filtre qui vont pouvoir nous aider... :00402FD8 FFD3 CALL EBX :00402FDA 8D7C3801 LEA EDI,[EDI+EAX+01] :00402FDE A1A4504000 MOV EAX,[004050A4] :00402FE3 50 PUSH EAX :00402FE4 57 PUSH EDI Ou un " d EDI " va vous montrer : 0187:00405550 75636F44 746E656D 65742073 00657478 Documents texte. 0187:00405560 78742E2A 00000074 00000000 00000000 *.txt........... 0187:00405570 00000000 00000000 00000000 00000000 ................ 0187:00405580 00000000 00000000 00000000 00000000 ................ Changez txt en asm, et vous ouvrirez les fichiers ayant cette extension. 0000D6F0 446F 6375 6D65 6E74 7320 7465 7874 6500 Documents texte. 0000D700 2A2E 7478 7400 446F 6375 6D65 6E74 7320 *.txt.Documents. 0000D710 6173 6D00 2A2E 6173 6D00 446F 6375 6D65 asm.*.asm.Docume 0000D720 6E74 7320 6261 7400 2A2E 6261 7400 546F nts bat.*.bat.To 0000D730 7573 2028 2A2E 2A29 002A 2E2A 0000 0000 us (*.*).*.*.... Maintenant, une petite dérivation vers de la place disponible : :00402FDA 8D7C3801 LEA EDI,[EDI+EAX+01] :00402FDE E95DA70000 JMP 0040D740 :00402FE3 50 PUSH EAX Et il n'y a plus qu'à charger notre nouveau filtre à la place de
l'ancien : :0040D740 60 PUSHAD < sauvegarde des registres :0040D741 BEF0D64000 MOV ESI,0040D6F0 < adresse de départ :0040D746 BF50554000 MOV EDI,00405550 < adresse d'arrivée :0040D74B B94D000000 MOV ECX,0000004D < taille du bloc à déplacer :0040D750 F3A4 REPZ MOVSB < déplacement :0040D752 61 POPAD < restauration des registres Mais dans la foulée, on va ajouter une gâterie ! BOOL WritePrivateProfileString(
LPCTSTR lpAppName, // pointer to section name
LPCTSTR lpKeyName, // pointer to key name
LPCTSTR lpString, // pointer to string to add
LPCTSTR lpFileName // pointer to initialization filename );
Les paramètres à pousser sur la pile sont les adresses de l'lpAppName
([Last Open File] et (SoftIce]), lpKeyName (Path et Detected), et le texte à " mémoriser "
(C:\Antipdd.txt et Yes). 0000D760 633A 5C63 6872 6973 7061 642E 6366 6700 c:\chrispad.cfg. 0000D790 FF4C 6173 7420 4F70 656E 2046 696C 6500 .Last Open File. 0000D7A0 5061 7468 0000 3900 3800 0000 4000 0C00 Path..9.8...@... reste trois choses :
Vous avez pu voir que ce n'est pas la place qui manque, mais pour éviter
d'être trop facilement localisé, j'ai continué à chercher des adresses différentes
pour loger mes bébés et éviter de vous servir toutes les modifications les unes derrières
les autres. Cette fois ci, je m'installe en 0040D770, dans les ex-infos de version. :00401423 A38C564000 MOV [0040568C],EAX > paramètre de l'API :00401428 E8633A0000 CALL comdlg32!GetOpenFileNameA :0040142D 85C0 TEST EAX,EAX > bouton OK sélectionné :0040142F 0F8483000000 JZ 004014B8 > non -> saute :00401435 56 PUSH ESI :00401436 8D85C0FEFFFF LEA EAX,[EBP-0140] > Buffet :0040143C 6800000080 PUSH 80000000 Glop ! Glop ! :0040143C E92FC30000 JMP 0040D770 Voyons le Patch : :0040D770 60 PUSHAD > sauvegarde les registres :0040D771 6860D74000 PUSH 0040D760 > c:\chrispad.cfg :0040D776 50 PUSH EAX > adresse du Buffet :0040D777 68A0D74000 PUSH 0040D7A0 > " Path " :0040D77C 6891D74000 PUSH 0040D791 > " Last Open File " :0040D781 E83DA1B6BF CALL KERNEL32!WritePrivateProfileStringA :0040D786 B88DAD4000 MOV EAX,0040AD8D > vers l'Anti Sice 3 :0040D78B 50 PUSH EAX :0040D78C C3 RET Et toujours histoire de noyer le Dead Listing, un Push Eax/Ret pour aller à
la routine suivante : :0040AD8D 6A00 PUSH 00 :0040AD8F 6880000000 PUSH 00000080 :0040AD94 6A03 PUSH 03 :0040AD96 6A00 PUSH 00 :0040AD98 6A03 PUSH 03 :0040AD9A 68000000C0 PUSH C0000000 :0040AD9F 6814104000 PUSH 00401014 > \\.\SICE :0040ADA4 E832CDB6BF CALL KERNEL32!CreateFileA :0040ADA9 6860D74000 PUSH 0040D760 > c:\chrispad.cfg :0040ADAE 3DFFFFFFFF CMP EAX,FFFFFFFF > détecté ? :0040ADB3 7507 JNZ 0040ADBC > non -> saute :0040ADB5 680CD84000 PUSH 0040D80C > " YES " :0040ADBA EB05 JMP 0040ADC1 > saute le " NON " :0040ADBC 6808D84000 PUSH 0040D808 > " NON " :0040ADC1 6810D84000 PUSH 0040D810 > " detected " -> Key :0040ADC6 6800D84000 PUSH 0040D800 > " SoftIce " -> Section :0040ADCB E8F3CAB6BF CALL KERNEL32!WritePrivateProfileStringA :0040ADD0 61 POPAD > restitue les registres :0040ADD1 6880000000 PUSH 00000080 > restaure le push écrasé :0040ADD6 E96666FFFF JMP 00401441 > et retour à la normale
VG Crypt comme son nom l'indique, est un crypteur de donnés de 9 ko! Son
objectif ne semble pas la protection en tant que tel, dans la mesure ou SoftIce rend la main sur l'Entry Point
au lancement de l'application-cible si vous passez par le Symbol Loader, et Wdasm peut réaliser un désassemblage
du programme en fournissant des ressources (String Data References…). .text 00003E9C 00001000 00004000 00001000 60000020 .data 0000084C 00005000 00001000 00005000 C0000040 .idata 00000DE8 00006000 00001000 00006000 40000040 .reloc 00000A9C 00007000 00001000 00007000 42000040 .rsrc 00006000 00008000 00006000 00008000 40000040 Après Cryptage : .text 00003FF4 00001000 00004000 00001000 E0000060 .data 0000084C 00005000 00001000 00005000 C0000040 .idata 00000DE8 00006000 00001000 00006000 40000040 .reloc 00000A9C 00007000 00001000 00007000 42000040 .rsrc 00006000 00008000 00006000 00008000 40000040 Vous remarquerez que la doc de VG Crypt ne ment pas, il n'y a pas de création de section supplémentaire, le Loader de VG Crypt s'est simplement glissé dans la section .text en augmentant sa taille de 158 octets pour pouvoir s'y loger, et cette section a été modifiée pour la rendre Readable, et eXécutable, suivant le principe suivant: 0x00000020 IMAGE_SCN_CNT_CODE 0x20000000 IMAGE_SCN_MEM_EXECUTE 0x40000000 IMAGE_SCN_MEM_READ ----------------------------------- 0x60000020 Eventuellement si vous souhaitez la rendre Writeable, il faudrait faire: 0x60000020
OR 0x80000000 IMAGE_SCN_MEM_WRITE
-----------------------------------
0xE0000020
Bon, du coup, VG Crypt sera difficile à identifier, d'autant plus qu'il
n'y a aucune "signature" de ce cryptage si vous en recherchez une avec un hexéditeur (pas de CopyRight,
rien de rien…) :00404FDD 8AA511274000 MOV AH,[EBP+00402711] > Chaîne à traiter
:00404FE1 AC LODSB > charge EAX avec le contenu de DS:SI
:00404FE2 32C4 XOR AL,AH > ou logique entre AL(E8h) et AH
:00404FE4 FEC4 INC AH > ajoute 1 à AH
:00404FE6 C0C402 ROL AH,02 > rotation à gauche de 2
:00404FE9 80C490 ADD AH,90 > ajoute 90h à AH
:00404FEC AA STOSB > transfère double mot par double mot
> le contenu de EAX dans ES:DI
:00404FED E2F2 LOOP 004050E1 > et ce tant que CX est <> de 0 (boucle)
:00404FEF E9CBFEFFFF JMP 00404EBF (JUMP) ici
:00404FF4 0000 ADD [EAX],AL
:00404FF6 0000 ADD [EAX],AL
Juste au-dessus du Jmp 00404EBF, vous avez la routine de décryptage. :00404EBF E800000000 CALL 00404EC4 :00404EC4 8B9D05274000 MOV EBX,[EBP+00402705] :00404ECA 83C328 ADD EBX,28 :00404ECD 58 POP EAX :00404ECE 2BC3 SUB EAX,EBX :00404ED0 89850D274000 MOV [EBP+0040270D],EAX :00404ED6 CC INT 3 :00404ED7 8DBD24264000 LEA EDI,[EBP+00402624] :00404EDD B93B000000 MOV ECX,0000003B :00404EE2 F3AA REPZ STOSB :00404EE4 64678F060000 POP DWORD PTR FS:[0000] :00404EEA 5A POP EDX :00404EEB 8B850D274000 MOV EAX,[EBP+0040270D] :00404EF1 018509274000 ADD [EBP+00402709],EAX :00404EF7 61 POPAD > POPAD ! :00404EF8 9D POPFD :00404EF9 8B9A09274000 MOV EBX,[EDX+00402709] :00404EFF 898A09274000 MOV [EDX+00402709],ECX :00404F05 FFE3 JMP EBX > passage de relais caractéristique ! Si vous avez un tant soit peu l'habitude des programmes cryptés/compressés,
le jmp EBX devrait vous sauter aux Yeux!
Faites un d 004010CC en arrivant en 00404EBF. Vous verrez des ????? dans la fenêtre
des Datas (codes invalides). Tracez avec F10, et en passant sur l'INT 3 en 00404ED6, vous pourrez voir que ce mnémonique
va permettre la décompression de NotePad, dans sa version pré-cryptée (par contre je ne sais
pas quelle est le rôle exacte que joue l'interruption 3 dans l'opération de décryptage…). En
continuant à tracer pas à pas, le REPZ STOSB va refermer les portes derrière vous en EFFACANT
toutes les adresses précédant la 0040ED7 (vous y verrez à la place des jolies codes que vous
aviez, de vilains ADD [EAX],AL), y compris le premier jmp que nous avions repéré en 00404FEF. [VGCrypt] L1=LOOK E9,CB > recherche du JMP 0040D95F (1) L2=BP > pose d'un break point L3=LOOK 00,FF,E3 > recherche du JMP EBX (2)- 1 byte L4=ADD 1 > avance de 1 byte L5=BP > pose d'un break point sur le jmp EBX L6=STEP > commence à tracer le programme pas à pas OPTL1=00000000 OPTL2=01010001 OPTL3=01010001 OPTL4=00010000 OPTL5=00000000 Bien sur, vous n'oublierez pas de rajouter une entête dans l'index de ProcDump: P1C=Shrinker 3.4 P1D=SalesAgent P1E=Photo 1.0 P1F=VGCrypt 2 ou 3 détails pour finir: |
Bonne Journée