| Protection | Anti SoftIce + Compression | Les Protections Renforcées | ||
| Outils | ProcDump SoftIce | |||
| Cible | Cible n°5 |
By Christal |
French Initiation in the use of the FPLoader Il était une fois un zoli programme détectant Softice, mais sans autre
conséquence que de signaler le fait que ce célèbre débuggeur avait été
piégé, et un rire que j'ai jugé sardonnique... La façon dont MeltICE fonctionne est très simple: Vous aurez remarqué que ce test se situe quelques lignes en dessous de l'Entry
Point (401000) de l'application. Pour peu que le Symbol Loader de Sice vous rende la main sur cet Entry Point,
il devient facile de shunter le test anti-SoftIce, en poussant la valeur 00 dans [004161EE], le flag de détection
de SoftIce. (vous noterez que FrogsICE n'est pas capable de retourner le bon offset:segment
d'un programme 32 bits) Le Code 07 et dans le cas qui nous intéresse, j'ai obtenu un retour ici: en utilisant ce breakpoint: Cette fois ci, le problème peut être résolu en modifiant le
branchement en 00401290. Génial, la signature d'UPX... Une DEUXIEME signature, celle de Pe-ExeEncrypter par Stone (http://www.cracking.net/stone), un maître du
genre… Les Characteristics sont typiques d'un programme compressé, on va les modifier
rapidement en changeant le E0000080, et les C0000040 par des E0000020. De cette façon, SoftIce rendra la
main sur l'entry point en lançant le programme/cible via le Symbol Loader, suivant la règle suivante: Désormais, le programme est désassemblable (sans les ressources),
et débuggable. Remplacez le JMP EAX, par un JMP EIP, pour obliger le programme à boucler
sur lui même, et relevez le contenu de EAX: 0045B300. C'est l'entrypoint de la partie compressée par
UPX, et vous allez en avoir besoin: Notez le. Le jmp Entry_point est l'une des caractéristiques de ce compresseur. Dans
notre cas, l'entry point du programme d'origine est le classique 00401000. Il pourra arriver que ce ne soit pas
le cas, et alors le PoPad juste au dessus pourra devenir votre fil d'Ariane… 0045D093 POP ESI Mais le POP EDI et POP EBP ont été écrasés. Il faudra
les penser à les restorer. Adresse1_du_Patch Le patch 1 va restorer les 2 codes écrasés par la mise en place du
jmp branchant vers Adresse1_du_patch, puis de DWORD va modifier 4 octets à l'adresse du jmp 00401000. Le
Byte va finir le travail (un jmp long est codé sur 5 octets). Désormais, le jmp 00401000 est devenu
un jmp 0045CBED, en 0045B47D, et va brancher sur Adresse2_du_patch. Le patch 2 va modifier un octet en 00401039, empéchant la mise à 1
de [004161EE], et un autre octet en 00401290, en remplaçant le 742E par un EB2E.
Bye Bye Anti SoftIce...
Hommage à Frog's Print
Ou comment contourner une protection anti-SoftIce
Ou encore, comment se fâcher avec un copain…
Dans l'espoir (maigre) de ne pas me fâcher complètement avec le copain qui a réalisé
l'application en question, je resterai assez évasif quand à son nom, et à celui de son petit
bijoux.
Hélas, je ne doute pas que plusieurs d'entre vous finirons par le reconnaître, et que vous aurez su
apprécier à sa juste valeur la qualité du travail de TxMaMBxLx. Du grand Art!
Pour savoir de quel façon l'exécutable détectait la présence de SoftIce, j'ai lancé
l'indispensable FPLoader de Frog'sPrint (http://www.thepentagon.com/frog_s_print), qui est allé
se loger à coté de l'horloge dans la barre des tâches, puis j'ai lancé l'application.
Aussitôt le si bel écran bleu de MicroSoft est apparu, affichant:
=> Cible DxxPxxx Nxxx
** SOFTICE DETECTION ** code 0B, at cs:004161F6
Attempting to load: SICE
Voyons ce que la doc jointe avec FrogICE nous en dit:
Le Code 0B
Cette méthode est mieux connue sous le nom de "MeltICE" parce qu'elle a été librement
distribuée via http://www.winfiles.com. A l'origine, elle fut utilisée par Numéga pour permettre au Symbol Loader
de vérifier si SoftIce était actif ou non. Le code se trouve dans nmtrans.dll (répertoire
de Numéga\SoftIce95):* Possible StringData Ref from Data Obj ->"\\.\SICE"
|
:100198DA 6824950710 push 10079524 > \\.\SICE
:100198DF FFD6 call esi > createfileA
:100198E1 83F8FF cmp eax, -1
:100198E4 8BF8 mov edi, eax
:100198E6 752B jne 10019913
Il essaye d'ouvrir les drivers de SoftIce (SICE, SIWVID pour Win9x, NTICE pour WinNT), avec l'API CreateFileA .
FPLoader permet de détourner facilement le résultat de cette recherche de la présence de SoftIce,
et vous retournera dans ce cas "SoftIce détecté à cs:10079524"
Il y a des centaines de BPX (dixit Frog's Print) que vous pourriez utiliser pour détecter cette recherche:
- BPX CreateFileA if *(esp->4+4)=='SICE' || *(esp->4+4)=='SIWV' || *(esp->4+4)=='NTIC'
- BPINT 30 if eax==002A001 && (*edi=='SICE' || *edi=='SIWV')
- BPINT 30 if (*edi=='SICE' || *edi=='SIWV')
- BPX KERNEL32!ORD_0001 if *edi=='SICE'
- BPX VMM_GetDDBList if eax->3=='SICE' || eax->3=='SIWV'
En posant un bpx CreateFileA, et en ayant caché (Hook) la présence de SoftIce grâce au FPLoader,
je suis arrivé ici après 23 appuis sur F12:015F:00401000 6A00 PUSH 00
015F:00401002 E886400100 CALL 0041508D
015F:00401007 85C0 TEST EAX,EAX
015F:00401009 7507 JNZ 00401012
015F:0040100B 6A00 PUSH 00
015F:0040100D E881400100 CALL 00415093
015F:00401012 6A00 PUSH 00
015F:00401014 6800000004 PUSH 04000000
015F:00401019 6A03 PUSH 03
015F:0040101B 6A00 PUSH 00
015F:0040101D 6A03 PUSH 03
015F:0040101F 68000000C0 PUSH C0000000
015F:00401024 68F2614100 PUSH 004161F2
015F:00401029 E86B400100 CALL 00415099 > CreateFileA
015F:0040102E 83F8FF CMP EAX,-01 > Sice détecté?
015F:00401031 740A JZ 0040103D > no jump
015F:00401033 C705EE61410001000000MOV DWORD PTR [004161EE],00000001
015F:0040103D E8E0020000 CALL 00401322
015F:00401042 E8E5040000 CALL 0040152C
015F:00401047 33C0 XOR EAX,EAX
Bon, après avoir fait la modification en mémoire, et relancé la cible, débarrassé
du détecteur de SoftIce, l'application s'ouvre avec…
SOFTICE DETECTED!!!
Ouch!
Soit je m'y suis mal pris, soit il y a un second test de détection…
En réutilisant le FPLoader, j'ai obtenu un deuxième écran bleu:=> MSPEC=C:
** SoftICE detection ** code 07, at FCAF:00002FF0(?)
Interrupt:68h >eax=00004301h ebx=00000000h ecx=800074A8h
edx=800052D0h esi=00008B98h edi=0059FB28h ebp=0059FB20h
La seconde méthode utilisée pour détecter SoftIce joue sur l' int 68h (V86)
Voici le principe général de ce test de dépistage:
mov ah,43h
int 68h
cmp ax,0F386h
jz SoftICE_Detected
0CA5:1103 2EFF2E0500 JMP FAR CS:[0005]
0CA5:1108 80FC43 CMP AH,43 identification SoftIce 4301
0CA5:110B 0F842601 JZ 1235
0CA5:110F 80FC44 CMP AH,44
0CA5:1112 0F84C200 JZ 11D8
0CA5:1116 3D8150 CMP AX,5081
BPX exec_int if ax==68
En traçant à partir de ces adresses, vous retournez vite aux codes du programme:015F:0040127F B443 MOV AH,43
015F:00401281 CD68 INT 68 > int 68
015F:00401283 663D86F3 CMP AX,F386
015F:00401287 7537 JNZ 004012C0
015F:00401289 833DEE61410001 CMP DWORD PTR [004161EE],01 >
Flag anti SoftIce
015F:00401290 742E JZ 004012C0 > à modifier
015F:00401292 6887924000 PUSH 00409287
015F:00401297 68CF070000 PUSH 000007CF
015F:0040129C FF7508 PUSH DWORD PTR [EBP+08]
015F:0040129F E8BF3D0100 CALL USER32!SetDlgItemTextA
015F:004012A4 C705EE61410001000000MOV DWORD PTR [004161EE],00000001
015F:004012AE 6813934000 PUSH 00409313
015F:004012B3 68B70B0000 PUSH 00000BB7
015F:004012B8 FF7508 PUSH DWORD PTR [EBP+08]
015F:004012BB E8A33D0100 CALL USER32!SetDlgItemTextA
015F:004012C0 33C0 XOR EAX,EAX
015F:004012C2 5E POP ESI
015F:004012C3 5F POP EDI
015F:004012C4 5B POP EBX
015F:004012C5 C9 LEAVE
015F:004012C6 C21000 RET 0010
Yaplusqua!
Ouverture de l'éditeur hexadécimal de votre choix, recherche, et…
RIEN!
Aie!
Le programme doit certainement réserver encore quelques surprises…
Voyons voir, en commençant par regarder ce que peut nous indiquer l'hexéditeur:
Au bout de quelques lignes:.......$Id: UPX
0.82 Copyright (
C) 1996-1999 Las
zlo Molnar & Mar
kus Oberhumer $.
Mais quelques lignes plus bas:..............En
crypted by Stone
CF - PowerLame
PE-ExeEnCrypter
! :) 2nd&mi
Il nous gâte, le monsieur, une double encryption/compression…
Commençons par rassembler les informations:
Lancement de procDump: options "PE Editor"
EntryPoint 004D000, image Base 00400000
Puis clic sur l'option " Séctions"UPX0 00038000 00001000 00000000 00000400 E0000080
UPX1 00023000 00039000 00022600 00000400 E0000040
.rsrc 00001000 0005C000 00000C00 00022A00 C0000040
.Stone 00001000 0005D000 0000011B 00023800 C0000040
0x00000020 IMAGE_SCN_CNT_CODE
0x20000000 IMAGE_SCN_MEM_EXECUTE
0x40000000 IMAGE_SCN_MEM_READ
OR 0x80000000 IMAGE_SCN_MEM_WRITE
-----------------------------------
0xE0000020
Mais comment réussir à patcher cette cible bi-compressée?
- En utilisant R!SC Process Patcher, mais compte tenu de la double compression/encryption, il risque d'avoir du
mal à mettre la main sur le deuxième test anti-SoftIce.
- Ecrire un script pour ProcDump qui automatiserait la création d'un Dump. Faisable, mais d'un intérêt
modéré dans la mesure ou une telle double compression ne se retrouvera probablement jamais. Beaucoup
d'énergie pour pas grand chose.
- En réalisant un patch par hard Patching. Pas évident, on y reviendra.
- En réalisant à la main le dump de la cible. Facile, mais l'inconvénient, c'est que le résultat
sera un exécutable plus gros que celui d'origine.
Commençons par la solutions la plus facile, le dump de la cible.
En traçant de l'entrypoint, vous verrez que c'est STONE qui ouvre le bal (logique d'après l'EP),
suivi de UPX.
Il va falloir procéder en deux étapes, une pour l'encryption ,l'autre pour la compression.
C'est parti.
Il ne faut pas oublier notre Anti-SoftIce, et avant d'arriver en 00401033, vous taperez, sur la ligne de commande
de SoftIce, "e 401033". Ainsi, vous verrez les codes de cette adresse s'afficher dans la fenêtre
des Datas. Il n'y aura plus qu'à cliquer sur le 01 pour le remplacer par 00, puis [Echap], pour valider
la modification. C'est plus rapide que de passer par le mode assemblage. En 00401290 une simple inversion de drapeau
suffira (R FL Z).
Mais pour le moment, vous êtes dans la section Cible!.Stone.
En traçant, vous arrivez en 0045D096, stoppez tout:015F:0045D094 5F POP EDI
015F:0045D095 5D POP EBP
015F:0045D096 FFE0 JMP EAX > passe la main à UPX
015F:0045D098 0000 ADD [EAX],AL > début de la zone compressée
Ouvrez ProcDump, et cliquez sur " Options " pour choisir " Rebuilt Import Table ", puis sélectionnez
la cible 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 143 ko d'origine, vous avez toujours un programme
de la même taille. C'est assez normal dans la mesure ou Pe-ExeEncrypter est un crypteur et non pas un compresseur.
Ave UPX la taille va certainement changer…
Il faut maintenant modifier l'entry point de ce premier Dump que vous venez de réaliser. Encore grâce
à ProcDump, vous allez pouvoir remplacer les 4D000 du départ par 45B300 (entry point donné par EAX) - 400000 (image base) = 5B300 (nouvel EP). Vous ferrez cette modification
en utilisant l'options "PE Editor". Et, bien sur, vous n'oublierez pas d'utilisez la fonction "Kill
Task" pour supprimer la boucle folle sur la cible qui est toujours en mémoire.
Ok! Vous voilà avec un dump décrypté, exécutable, désassemblable (mais toujours
sans ressources) et débuggable.
Passons à l'étape 2:
le dump décompressé.
En relançant la Cible via le Loader de Sice, vous attaquerez le programme par l'adresse 004FB300 (et heureusement…),
dans la section UPX1.
Le passage de relais d'UPX au programme d'origine est assez facile à trouver: pour en connaître l'adresse,
il suffit, bien souvent, d'aller regarder à la fin du listing que vous aurez pu obtenir avec Wdasm::0045B47C 61 popad > restauration des registres
:0045B47D E97E5BFAFF jmp 00401000 > vers programme d'origine
:0045B482 0000 add byte ptr [eax], al > zone compressée ou nulle
Il ne reste plus qu'à faire les mêmes opérations que pour le dump précédent,
en remplaçant le jmp 0040100 par un jmp EIP, et à la fin du Dump donner le nouvel EP, soit 1000.
Vous voici avec un programme de 367 ko, au lieu des 143 ko avant décompression, et qui va pouvoir être
patché "normalement" et sans autres surprises.
Bye Bye Anti SiftIce…
Hard Patching:
Dans la cas d'une encryption et d'une souscouche de compression, le gros problème est de trouver de la place
pour y glisser les quelques lignes nécessaire à un patch modifiant la partie anti SoftIce. L'objectif
de ce texte n'étant pas de réussir un Patch Hard de la cible (comprenez l'application d'un patch
ne nécessitant pas de passer par des dumps mémoire), voici quand même ce qu'il y aurait moyen
de faire:
0045D094 POP EDI
0045D095 POP EBP
0045D096 JMP EAX > fin du décryptage de STONE
à remplacer par
0045D096 JMP adresse1_du_patch > adresse à trouver015F:0045D090 5B POP EBX
015F:0045D091 59 POP ECX
015F:0045D092 5A POP EDX
015F:0045D093 5E POP ESI
015F:0045D094 E93FFBFFFF JMP 0045CBD8 > par exemple en 0045CBD8
015F:0045D099 004000 ADD [EAX+00],AL
015F:0045CBD8 5F POP EDI > restoration du POP EDI
015F:0045CBD9 5D POP EBP > idem pour EBP
015F:0045CBDA C7057DB44500E96B1700MOV DWORD PTR [0045B47D],00176BE9
015F:0045CBE4 C60581B4450000 MOV BYTE PTR [0045B481],00
C'est 2 lignes de commandes modifient le jmp 401000 pour le forcer à venir en Adresse2_du_Patch
015F:0045CBEB FFE0 JMP EAX > retour à la "normale"
Adresse2_du_Patch (à la suite du premier)
015F:0045CBED C6053910400000 MOV BYTE PTR [00401039],00 > 1er anti-Sice
015F:0045CBF4 C60590124000EB MOV BYTE PTR [00401290],EB > 2ème anti-Sice
015F:0045CBFB E90044FAFF JMP 00401000 > vers le prog décrypt/décomp
015F:0045CC00 0000 ADD [EAX],AL
Spécial Greetz à TaMaMBoLo pour ses Drapeaux Noirs, et particulièrement le n°5...
Bonne journée
Christal