Aujourd'hui, nous nous attaquons à un programme qui à déjà été analysé par le Group de Travail : ZipStudio.
La nouvelle version semble poser, même avec l'ancien cours, de sérieux problèmes à beaucoups de Newbies jusqu'à vois des " ZipStudio Incrackable ? " sur le forum. Je signale que je ne réexpliquerai pas tous ce qui a été dis dans le premier essai à son propos.
I. zstudio.dll
Pourquoi (re)parle-on nous de cette DLL ? Simplement parcequ'une détection de Debugger se fait dans le procédure DLLmain ( DLLEntryPoint ). Comment savons-nous cela... entre autre en utilisant FrogSice dont voici le Log :
; Chargement
;
---------------------------------------------------------------------------------
**
SoftICE detection ** code 07, at
FCB2:1004FCB2 Interrupt:68h
** SoftICE detection **
code 07, at FCB2:004CFCB2
Interrupt:68h
** SoftICE detection ** code 01, at
0177:00000177 Interrupt:03h
** SoftICE detection ** code 0B,
at cs:004CF94C Attempting to load:
SICE
** SoftICE
detection ** code 0B, at
cs:004CF988 Attempting to load: NTICE
** SoftICE detection **
code 07, at FCB2:004BFCB2
Interrupt:68h
** SoftICE detection ** code 01, at
0177:00000177 Interrupt:03h
** SoftICE detection ** code 0B,
at cs:004BE8BC Attempting to load:
SICE
** SoftICE
detection ** code 0B, at
cs:004BE8F8 Attempting to load: NTICE
** SoftICE detection **
code 0B, at cs:00490660 Attempting to
load: SICE
**
SoftICE detection ** code 0B, at
cs:0049069C Attempting to load: NTICE
; En affichant la Fenetre
principale
;
---------------------------------------------------------------------------------
** SoftICE detection **
code 07, at FCB2:004BFCB2
Interrupt:68h
** SoftICE detection ** code 01, at
0177:00000177 Interrupt:03h
; En fermant cette
dernière
;
---------------------------------------------------------------------------------
** SoftICE detection **
code 07, at FCB2:004CFCB2
Interrupt:68h
** SoftICE detection ** code 01, at
0177:00000177 Interrupt:03h
On voit directement que le premier anti-sice se fait dans une DLL ( CS = 1004FCB2 ) et que c'est une INT 68.
Pour la neutraliser, il suffit de mettre un CC a l'EP de la DLL, ensuite tracer dans son code avec F10. Il y a un des call qui qui le programme :
//******************** Program
Entry Point ********
:1003E000
CC
int
03
;Pour forcer le BP. Ne pas oublier de remplacer par 83h
:1003E001
3DE8110410
cmp eax, 100411E8
:1003E006
007408A1
add byte ptr [eax+ecx-5F], dh
:1003E00A
E8110410FF
call 0F13E420
:1003E00F
E0C3
loopnz 1003DFD4
:1003E011
55
push ebp
:1003E012
8BEC
mov ebp, esp
:1003E014
83EC14
sub esp, 00000014
:1003E017
53
push ebx
:1003E018
56
push esi
:1003E019
57
push edi
:1003E01A
E8CF010000
call 1003E1EE
:1003E01F
A16C120410
mov eax, dword ptr [1004126C]
:1003E024
2B0568120410
sub eax, dword ptr [10041268]
:1003E02A
8945F4
mov dword ptr [ebp-0C], eax
:1003E02D
8B0DA0160410
mov ecx, dword ptr [100416A0]
:1003E033
030DAC160410
add ecx, dword ptr [100416AC]
:1003E039
894DF8
mov dword ptr [ebp-08], ecx
:1003E03C
8B156C120410
mov edx, dword ptr [1004126C]
:1003E042
3B55F8
cmp edx, dword ptr [ebp-08]
:1003E045
7520
jne 1003E067
:1003E047
A178110410
mov eax, dword ptr [10041178]
:1003E04C
2B0580110410
sub eax, dword ptr [10041180]
:1003E052
50
push eax
:1003E053
8B0D7C110410
mov ecx, dword ptr [1004117C]
:1003E059
51
push ecx
:1003E05A
E8A5010000
call 1003E204
:1003E05F
50
push eax
:1003E060
E815050000
call 1003E57A
:1003E065
EB28
jmp 1003E08F
* Referenced by a
(U)nconditional or (C)onditional Jump at Address:
|:1003E045(C)
|
:1003E067
8B1578110410
mov edx, dword ptr [10041178]
:1003E06D
2B1580110410
sub edx, dword ptr [10041180]
:1003E073
52
push edx
:1003E074
A180110410
mov eax, dword ptr [10041180]
:1003E079
50
push eax
:1003E07A
E885010000
call 1003E204
:1003E07F
50
push eax
:1003E080
E8F5040000
call 1003E57A
:1003E085
6898160410
push 10041698
:1003E08A
E8F3020000
call 1003E382
* Referenced by a
(U)nconditional or (C)onditional Jump at Address:
|:1003E065(U)
|
:1003E08F
E87F010000
call 1003E213
:1003E094
E8????????
call 10040176
:1003E099
E8E5010000
call 1003E283
Le call en 1003E094 détecte les debugger et si debugger il y a, exit le programme. Le problème, c'est qu'il saute dans du code préalablement décrypté et qu'il est donc impossible de patcher directement. Cependant, quand ce call est exécuté, l'instruction INT 68 est déjà décrypté en mémoire, on peut donc le dévier et patcher l'INT 68 en NOP NOP :
:1003E094
E8473F0000
call 10041FE0
...
*
Referenced by a CALL at Address:
|:1003E094
|
:10041FE0
66C7053B0104109090 mov word ptr [1004013B],
9090 ;On patch l'instruction en NOPs
:10041FE9
E988E1FFFF
jmp
10040176
;Et on redonne la main
D'après FrogsIce, il n'y a qu'un seul Anti-sice dans la DLL ( vu que le suivant se fait dans le code de l'EXE ). Nous en avons donc terminé pour le problème principale de la pluspart d'entre vous.
Rem : pour trouver l'adresse de l'INT68, il suffit de tracer avec F8 dans le call en 1003E094. A un moment, vous vous retrouverai dans VMM ( dans le code de gestion des interruptions ), à ce moment, faites 2-3 F12 pour revenir dans le code zstudio.dll et vous devez aperçevoir l'instruction juste au-dessus de l'adresse de retour.
II. Zip Studio.exe
Attaquons-nous à présent à notre petit préféré, ZipStudio. Un rapide coup d'oeil au PE Header nous apprend qu'il est compressé par UPX. ( Voir les nom des sections ). Ensuite, d'après le Log de FrogsIce, il semblerait qu'il y aie seulement un bloc important :
** SoftICE detection **
code 07, at FCB2:004CFCB2
Interrupt:68h
** SoftICE detection ** code 01, at
0177:00000177 Interrupt:03h
En posant 3 BreakPoints adaptés :
BPINT 03 ( pour l'int 03
),
BPM Exec_Int X IF ax==68 (
pour l'int 68 )
et BPM CreateFileA X ( pour la détection
MeltICE )
J'ai trouvé le code qui exécute les deux interruptions :
0177:004CFB07
B443
MOV
AH,43
;L'int 68
0177:004CFB09
CD68
INT 68
0177:004CFB0B
3D86F30000
CMP EAX,0000F386
0177:004CFB10
66FA
CLI
0177:004CFB12
FB
STI
0177:004CFB13
A7
CMPSD
Après ce bloc d'instruction contenant l'Int 68, le programme installe un SEH.
Explication : Quand une Exception survient dans un programme, normallement, vous voyez apparaître la trop bien-connue boite de dialogue affichant les registres, ect.. Mais si on veux, le programme peut gérer lui-même ses erreurs. Pour cela, il utilise le SEH. Pour installer le SEH ,il suffit d'appeler SetHunhandledExceptionFilter avec comme paramêtre l'adresse de la fonction à exécuté lors d'une Exception.
Ci-dessous, le programme installe le SEH en 004CFB3A et créé une Exception ( avec l'int 03 ). Si le programme est debuggé, il va géré l'erreur et retourner après l'int 03 ( ExitProcess ! ). Dans le cas contraire, c'est la fonction en 004CFB3A qui sera exécutée.
0177:004CFB14
8965FC
MOV [EBP-04],ESP
0177:004CFB17
683AFB4C00
PUSH 004CFB3A
0177:004CFB1C
E80363F3FF
CALL
KERNEL32!SetUnhandledExceptionFilter
0177:004CFB21
BD4B484342
MOV EBP,4243484B ;BCHK
0177:004CFB26
B804000000
MOV EAX,00000004
0177:004CFB2B
CC
INT 3
0177:004CFB2C
E8DB68F3FF
CALL USER32!MessageBoxA
0177:004CFB31
E8E660F3FF
CALL KERNEL32!ExitProcess
0177:004CFB36
66FA
CLI
0177:004CFB38
FB
STI
0177:004CFB39
A7
CMPSD
0177:004CFB3A
8B65FC
MOV ESP,[EBP-04]
0177:004CFB3D
6843FB4C00
PUSH 004CFB43
0177:004CFB42
C3
RET
0177:004CFB43
C3
RET
Si c'est la fonction en 004CFB3A qui est exécutée, le programme ne retournera pas en 004CFB2C ( après l'INT 03 ) mais en 004CFB43. Pour neutraliser cette protection, il faudra d'abord NOPer l'INT 68 et remplacer l'INT 03 par ADD ESP,04 ; RET.
0177:004CF932
E8A562F3FF
CALL KERNEL32!CreateFileA
0177:004CF937
83F8FF
CMP EAX,-01
0177:004CF93A
7408
JZ 004CF944
0177:004CF93C
50
PUSH EAX
0177:004CF93D
E87A62F3FF
CALL KERNEL32!CloseHandle
0177:004CF942
B301
MOV BL,01
0177:004CF944
8BC3
MOV EAX,EBX
0177:004CF946
5B
POP EBX
0177:004CF947
C3
RET
Ci-dessus se trouve le code de la detection MeltICE. Il suffira de patcher le MOV BL,01 en NOPs pour la neutraliser. Ce bloque d'instruction a été simplement trouvé en mettant un BPX sur CreateFileA et en reguardant la valeur de son premier paramètre en *(ESP+4).
En continuant notre voyage dans le code, on se retrouve nez-à-nez avec une INT 03 :
:004BE938
55
push ebp
:004BE939
8BEC
mov ebp, esp
:004BE93B
51
push ecx
:004BE93C
53
push ebx
:004BE93D
56
push esi
:004BE93E
57
push edi
:004BE93F
33C0
xor eax, eax
:004BE941
55
push ebp
:004BE942
6877E94B00
push 004BE977
:004BE947
64FF30
push dword ptr fs:[eax]
:004BE94A
648920
mov dword ptr fs:[eax], esp
:004BE94D
E8AEFFFFFF
call 004BE900
:004BE952
6A00
push 00000000
:004BE954
6808524A00
push 004A5208
:004BE959
E8AE78F4FF
call 0040620C
:004BE95E
66B90801
mov cx, 0108
:004BE962
66BE6E00
mov si, 006E
:004BE966
AC
lodsb
:004BE967
CC
int 03
Pour neutraliser cela, nous allons essayer de retrouver le code appelant. Pour cela, on met des BPX au début de la fonction en 004BE938, on relance et on reguarde en [ESP]. On voit qu'on vient d'ici :
:004BED2C
55
push ebp
:004BED2D
8BEC
mov ebp, esp
:004BED2F
83C4F0
add esp, FFFFFFF0
:004BED32
53
push ebx
:004BED33
56
push esi
:004BED34
57
push edi
:004BED35
33C9
xor ecx, ecx
:004BED37
894DF0
mov dword ptr [ebp-10], ecx
:004BED3A
8945FC
mov dword ptr [ebp-04], eax
:004BED3D
33C0
xor eax, eax
:004BED3F
55
push ebp
:004BED40
6833F04B00
push 004BF033
:004BED45
64FF30
push dword ptr fs:[eax]
:004BED48
648920
mov dword ptr fs:[eax], esp
:004BED4B
6A00
push 00000000
:004BED4D
68E44C4A00
push 004A4CE4
:004BED52
E8B574F4FF
call 0040620C
:004BED57
E8DCFBFFFF
call 004BE938
Et si on remplace le PUSH EBP par un RET, l'Anti-Sice est neutralisé.
Après cela, il y a encore 2 détections INT 68/BCHK ( exactement le même code que pour le premier cas ), 1 détection MeltICE ( Idem ) et 2 détections comme la dernière qui, chez moi ne posent étonnament pas problème.. (?), mais que vous pouvez quand même neutraliser.
INT68 : 004CFB09,
004BCFA1, 004CE287 ; Remplacer par NOP ; NOP
BCHK : 004CFB2B,
004BCFC3, 004CE2A9 ; Remplacer par ADD ESP,04 ;
RET
MeltICE : 00490656, 004CF942 ; Remplacer par NOP ; NOP
INT03 : 004BED2C, 004BD010, 004CE2F8 ; Remplacer par RET
UPX donne la main à l'OEP ici :
:0081E492
61
popad
:0081E493
E97C1ACBFF
jmp 004CFF14
On va donc le dévier vers notre code et patcher en mémoire :
0081E493:
E968000000
jmp .00081E500
...
0081E500:
66C70509FB4C009090
mov
w,[0004CFB09],09090 ;Premier bloc
INT68/BCHK
0081E509:
C7052BFB4C0083C404C3
mov d,[0004CFB2B],0C304C483 ;
0081E513:
66C705A1CF4B009090
mov
w,[0004BCFA1],09090 ;Second bloc
INT68/BCHK
0081E51C:
C705C3CF4B0083C404C3
mov d,[0004BCFC3],0C304C483 ;
0081E526:
66C70587E24C009090
mov
w,[0004CE287],09090 ;Dernier bloc
INT68/BCHK
0081E52F:
C705A9E24C0083C404C3
mov d,[0004CE2A9],0C304C483 ;
0081E539:
66C705560649009090
mov
w,[000490656],09090 ;Les 2 MeltICE
0081E542:
66C70542F94C009090
mov
w,[0004CF942],09090 ;
0081E54B:
C6052CED4B00C3
mov
b,[0004BED2C],0C3 ;Les 3 INT3
0081E552:
C60510D04B00C3
mov
b,[0004BD010],0C3 ;
0081E559:
C605F8E24C00C3
mov
b,[0004CE2F8],0C3 ;
0081E560:
E9AF19CBFF
jmp
0FFD67314
;Et on saute à l'OEP
Voilà ce qui termine les protections Anti-debug. De plus, j'ai l'impression que les INT03 sont compris dans les fonctions lié au caractère Shareware de ZipStudio car je n'ai plus de NagScreen..
Remarquez bien que ce cours n'explique pas comment cracker ce programme.. il donne juste un aperçus des moyens que l'on peut uriliser pour passer les Anti-debug utilisés.. D'ailleurs, il n'est pas possible d'utiliser le programme dans cet état. Les 3 bloc INT03 sont en fait des fonctions importantes de ZipStudio et ne contiennent pas QUE du code Anti-debug. Il va donc falloire etudier cela de plus pret...
Amicalement,
TeeJi