Une bien belle image... ;o) COURS

ETUDE DE SYSTEM-MECHANIC
 
 

PROTECTIONS
ASPACK
ANTI-SICE
KEY
TIME LIMITE

URL: http://www.iolo.com/

DATE

01/03/2000

 


INFOs :

Unfortunately, many people are not entirely familiar with the procedures of maintenance that must be performed in
order to service computer systems properly, and most system technicians will agree that the necessary tools are not included with the operating system.
System Mechanic is a complete collection of all of the necessary tools to keep your system running smooth, fast, and error free.

How much does it cost?

· Standard Edition:  $19.95
· Professional Edition:  $39.95
· Industrial Edition:  $59.95


Salut à tous,
 

Petite étude de System Mechanic
Alors on s'équipe de tout ce qu'il faut : Jus de fruits, barres de céréales...
(certains pour la frime disent : Alcool, drogueS et autres accélérateurs de particules...)
(Essayez de faire une nuit de debug en vous aidant d'un litre de Vodka et vous verrez...)

Il s'agit d'un prog compacté par AsPack 108.3 et équipé d'un anti-sice de base mais qui plante la machine !
 
 
Donc 1ère manipulation : le décompactage

Comme asPack est plus que connu on passe directement par un unasPack.
On se retrouve alors avec un bel executable que l'on peut désassembler...
Il n'y a pas d'informations faciles style : " le JZ est ici !" donc on passe en phase débug.
 
 
Par où commencer ?

1er point l'anti-sice :

Trés facile on tombe dessus dès le début du prog

// Il est possible d'utiliser FrogSice pour avoir une petite aide...
 
 
//Program Entry Point 
:004E8FB4 55                      push ebp
:004E8FB5 8BEC                    mov ebp, esp
:004E8FB7 83C4EC                  add esp, FFFFFFEC
:004E8FBA 33C0                    xor eax, eax
:004E8FBC 8945F0                  mov dword ptr [ebp-10], eax
:004E8FBF 8945EC                  mov dword ptr [ebp-14], eax
:004E8FC2 B88C8B4E00              mov eax, 004E8B8C
:004E8FC7 E830D1F1FF              call 004060FC
:004E8FCC 33C0                    xor eax, eax
:004E8FCE 55                      push ebp
:004E8FCF 68D0954E00              push 004E95D0
:004E8FD4 64FF30                  push dword ptr fs:[eax]
:004E8FD7 648920                  mov dword ptr fs:[eax], esp
:004E8FDA E8051EFFFF             call 004DADE4
:004E8FDF 84C0                    test al, al
:004E8FE1 7509                    jne 004E8FEC
:004E8FE3 E84C1EFFFF             call 004DAE34
:004E8FE8 84C0                    test al, al
:004E8FEA 740A                    je 004E8FF6
|
:004E8FEC E8931EFFFF              call 004DAE84
:004E8FF1 E8CEA9F1FF              call 004039C4
|
:004E8FF6 8D55EC                  lea edx, dword ptr [ebp-14]
:004E8FF9 A17CB24E00              mov eax, dword ptr [004EB27C]
:004E8FFE 8B00                    mov eax, dword ptr [eax]
:004E9000 E85FA4F4FF              call 00433464
:004E9005 8B45EC                  mov eax, dword ptr [ebp-14]
:004E9008 8D55F0                  lea edx, dword ptr [ebp-10]

 
 
 
 
 

Time limite
 
 
 

Anti "SICE"
 

Anti "NTICE"
 

Plante le PC ;o((
 

 

On voit trés bien que quelques octets en 004E8FCC vont nous permettre de mieux étudier ce programme.
  004E8FDA      jmp 004E8FF6

2iem point le time limite :

Il s'agit d'un time limite à 30 jours (1E jours en hexa).
Donc pour un time limite on commence par GetLocalTime. Que l'on trouve 2 fois
en 004DB2F1 et 004DB273
 
:004DB273 E888C7FFFF              call 004D7A00
:004DB278 85C0                    test eax, eax
:004DB27A 7F75                    jg 004DB2F1
:004DB27C B894B44D00              mov eax, 004DB494

:004DB2F1 E80AC7FFFF              call 004D7A00
:004DB2F6 83F81E                  cmp eax, 0000001E
:004DB2F9 7E75                    jle 004DB370
:004DB2FB B85CB64D00              mov eax, 004DB65C

eax = nb jours restant

jmp si > 0
 

eax = nb jours restant
eax <= 30 ?
oui alors jmp

Il y a plusieurs façons de passer ce test :
- on peut renvoyer une valeur toujours inférieure à
- on peut bipasser les tests
- etc...
 
 

3iem point les clefs d'enregistrement :

On a vu dans les infos qu'il y a 3 modes  d'enregistrement (donc, a priori 3 clefs possible pour un utilisateur).
Donc on rempli du mieux possible la boite  d'enregistrement et l'on place en break point sur HMEMCPY.
On appuie sur OK et l'on suit tranquillement le code  pour arriver en 004B1BDB
 
:004B1BDB E8D4640200             call 004D80B4
:004B1BE0 84C0                    test al,  al
:004B1BE2 740A                   je 004B1BEE
:004B1BE4 E87B600200              call 004D7C64
:004B1BE9 E953010000             jmp 004B1D41
|
:004B1BEE E891900200              call  004DAC84
:004B1BF3 84C0                    test al, al
:004B1BF5 740A                   je 004B1C01
:004B1BF7 E888920200              call  004DAE84
:004B1BFC E940010000             jmp 004B1D41
|
:004B1C01 B201                    mov dl, 01
:004B1C03 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C06 8B80FC010000            mov eax, dword ptr [eax+000001FC]
:004B1C0C E85312F7FF              call 00422E64
:004B1C11 33C0                    xor eax, eax
:004B1C13 8945F8                  mov dword ptr [ebp-08], eax
:004B1C16 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C19 E86EF8FFFF              call 004B148C
:004B1C1E 84C0                    test al, al
:004B1C20 0F841B010000           je 004B1D41
:004B1C26 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1C29 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C2C 8B80DC010000            mov eax, dword ptr [eax+000001DC]
:004B1C32 E8D112F7FF              call 00422F08
:004B1C37 8B45F0                  mov eax, dword ptr [ebp-10]
:004B1C3A 8D4DE8                  lea ecx, dword ptr [ebp-18]

:004B1C3D BA01000000              mov edx, 00000001
:004B1C42 E8816B0200             call 004D87C8
:004B1C47 8B45E8                 mov eax, dword ptr [ebp-18]
:004B1C4A 50                      push eax
:004B1C4B 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1C4E 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C51 8B80E8010000            mov eax, dword ptr [eax+000001E8]
:004B1C57 E8AC12F7FF              call 00422F08
:004B1C5C 8B55F0                  mov edx, dword ptr [ebp-10]
:004B1C5F 58                      pop eax
:004B1C60 E89F22F5FF              call 00403F04
:004B1C65 7507                    jne 004B1C6E
:004B1C68 C745F802000000          mov [ebp-08], 00000001
:004B1C6E 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1C71 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C74 8B80DC010000            mov eax, dword ptr [eax+000001DC]
:004B1C7A E88912F7FF              call 00422F08
:004B1C7F 8B45F0                  mov eax, dword ptr [ebp-10]
:004B1C82 8D4DE8                  lea ecx, dword ptr [ebp-18]

:004B1C85 BA02000000              mov edx, 00000002
:004B1C8A E8396B0200             call 004D87C8
:004B1C8F 8B45E8                 mov eax, dword ptr [ebp-18]
:004B1C92 50                      push eax
:004B1C93 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1C96 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1C99 8B80E8010000            mov eax, dword ptr [eax+000001E8]
:004B1C9F E86412F7FF              call 00422F08
:004B1CA4 8B55F0                  mov edx, dword ptr [ebp-10]
:004B1CA7 58                      pop eax
:004B1CA8 E85722F5FF              call 00403F04
:004B1CAD 7507                    jne 004B1CB6
:004B1CAF C745F802000000          mov [ebp-08], 00000002
:004B1CB6 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1CB9 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1CBC 8B80DC010000            mov eax, dword ptr [eax+000001DC]
:004B1CC2 E84112F7FF              call 00422F08
:004B1CC7 8B45F0                  mov eax, dword ptr [ebp-10]
:004B1CCA 8D4DE8                  lea ecx, dword ptr [ebp-18]

:004B1CCD BA03000000              mov edx, 00000003
:004B1CD2 E8F16A0200             call 004D87C8
:004B1CD7 8B45E8                 mov eax, dword ptr [ebp-18]
:004B1CDA 50                      push eax
:004B1CDB 8D55F0                  lea edx, dword ptr [ebp-10]
:004B1CDE 8B45FC                  mov eax, dword ptr [ebp-04]
:004B1CE1 8B80E8010000            mov eax, dword ptr [eax+000001E8]
:004B1CE7 E81C12F7FF              call 00422F08
:004B1CEC 8B55F0                  mov edx, dword ptr [ebp-10]
:004B1CEF 58                      pop eax
:004B1CF0 E80F22F5FF              call 00403F04
:004B1CF5 7507                   jne 004B1CFE
:004B1CF7 C745F803000000         mov [ebp-08], 00000003
|
:004B1CFE 8B45F8                  mov eax, dword ptr [ebp-08]
:004B1D01 48                      dec eax
:004B1D02 7408                    je 004B1D0C
:004B1D04 48                      dec eax
:004B1D05 7414                    je 004B1D1B
:004B1D07 48                      dec eax
:004B1D08 7420                    je 004B1D2A
:004B1D0A EB2D                   jmp 004B1D39

Test le nom de crackers "célèbres" ?
al = 0 ?
oui alors jmp
 
 

non noté
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

test de la clef n°1
Calcul de la clef 1
eax = clef mode Standart
 
 
 
 
 
 

test bonne clef
non jmp
oui alors clef n°1 OK
 
 
 
 
 
 

test de la clef n°2
Calcul de la clef 2
eax = clef mode Pro
 
 
 
 
 
 

test bonne clef
non jmp
oui alors clef n°2 OK
 
 
 
 
 
 

test de la clef n°3
Calcul de la clef 3
eax = clef mode Entreprise
 
 
 
 
 

test bonne clef
non jmp
oui alors clef n°3 OK

eax = quel n° de clef ?
eax = n° de clef  -  1
eax = 0 alors clef 1

eax = 0 alors clef 2

eax = 0 alors clef 3
Aucune clef alors message d'erreur

On voit bien qu'il n'y a plus de problème pour un test poussé du programme...
On peut même choisir le clef qui nous convient le mieux (Enterprise bien sur ;o))

Exp : pour   ByteCop

Std : 84696-ST351-178656....
Pro : 90635-PR945-774717....
Ent : 79746-ND856-663606....

A vous de trouver les chiffres manquant :o))
 
 
 
 Etudions la façon de placer les modifications

Ici on va utiliser une technique de Reverse !
En fait on va ajouter un section dans le programme et y placer
2 choses : un patch pour l'anti-sice et une fonction affichant
une boite de dialogue avec les clefs en fonction du userName !
On ne passe pas le time-limit car il ne sert à rien !

Comment faire pour ajouter une section à un programme ???
 - pour le faire à la main avec procDump vous lisez qq tutorials...
   ce n'est pas que ce soit complexe à l'extrème mais il fut faire des manips ennyeuses.
 - vous utilisez Topo (freeware at  http://i.am/MrCrimson  )

Donc fainéant comme je suis je prends l'option N°2 :o))
(On peut aussi uiliser l'espace libre par exp en 005B2960 et +)

Avant il faut trouver ce que l'on va patcher !

1°) L'anti-sice

On a vu au début que l'anti-sice se passe par :
  004E8FDA      jmp 004E8FF6

2°) L'appel de la fonction

A quel endroit placer ce CALL ?
Tout simplement à la place de l'appel de la boite de message signalant une erreur de code !
(si le code est bon pourquoi donner plus d'infos ?)
 
 
CALL at 004B1D3C 
|
:004B1564 55                      push ebp
:004B1565 8BEC                    mov ebp, esp
:004B1567 51                      push ecx
:004B1568 8945FC                  mov dword ptr [ebp-04], eax
:004B156B B880154B00             mov eax, 004B1580
:004B1570 E8AFF7F8FF              call 00440D24
:004B1575 59                      pop ecx
:004B1576 5D                      pop ebp
:004B1577 C3                      ret

 
 
 

eax pointe sur le message d'erreur
Affiche une MessageBox

 

On va donc modifier le mov eax par un jmp routine_info_clef. on se servira ensuite de
la routine d'affichage de la messageBox pour dessiner la boite d'infos.

Cette première idée n'est pas forcement aussi bonne que ça car il va faloir refaire le calcul des clefs...
Une solution plus logique pourrait-être :
 - lors du calcul des clefs copier celles-ci dans le message d'erreur !
 - en fonction du type de clef (standart, pro, entreprise) on place la clef en position 1,2 ou 3 !
 - ainsi l'information sur les clefs n'interviendrait qu'en cas d'erreur de saisie ;o)

Solution adoptée : voyons où la placer.
 
 
CALL by 
:004B1C42   , :004B1C8A   , :004B1CD2   , :004D85F7   , :004D867B  ,004D86FF 
|
:004D87C8 55                      push ebp
:004D87C9 8BEC                    mov ebp, esp
:004D87CB 83C4D0                  add esp, FFFFFFD0
:004D87CE 53                      push ebx
:004D87CF 33DB                    xor ebx, ebx
:004D87D1 895DD4                  mov dword ptr [ebp-2C], ebx
:004D87D4 895DD8                  mov dword ptr [ebp-28], ebx
:004D87D7 895DEC                  mov dword ptr [ebp-14], ebx
:004D87DA 895DE8                  mov dword ptr [ebp-18], ebx
:004D87DD 894DF4                  mov dword ptr [ebp-0C], ecx
:004D87E0 8955F8                  mov dword ptr [ebp-08], edx
:004D87E3 8945FC                  mov dword ptr [ebp-04], eax
:004D87E6 8B45FC                  mov eax, dword ptr [ebp-04]
:004D87E9 E8BAB7F2FF              call 00403FA8
...etc...
:004D8A2F 8B45F4                  mov eax, dword ptr [ebp-0C]
:004D8A32 8B55E8                  mov edx, dword ptr [ebp-18]
:004D8A35 E8D6B1F2FF              call 00403C10
:004D8A3A 33C0                    xor eax, eax
:004D8A3C 5A                      pop edx
:004D8A3D 59                      pop ecx
:004D8A3E 59                      pop ecx
:004D8A3F 648910                  mov dword ptr fs:[eax], edx
:004D8A42 68718A4D00              push 004D8A71

 
 

Début de la routine de calcul des clefs
 
 
 
 
 
 

Zone où sera placée la clef

Type de clef
 
 
 
 
 

Ici la clef est stable !

Donc on va gentiment détourner le programme à l'adresse 004D8A3A pour qu'il se rende sur notre routine.
 
 
004D8A3A    JMP new_Function

New_Function:
pushad 
mov esi, [ebp-18] 
mov edi, [ebp-8] 
mov ecx, 16h 
dec edi 
imul edi, edi,18h
add edi, 004B1580
rep movsb
mov word ptr [edi], 0A0D
popad
xor eax, eax
pop edx
pop ecx
pop ecx
JMP 004D8A3F

ici il faut mettre l'adresse de votre patch
 

Juste par sécurité
adrs clef en mémoire
Type de clef 

ecx = longueur de la clef

Calcul de l'offset dans EDI
+ adresse du message
(on pourrait mettre MovsW)
On passe à la ligne

On execute les instructions supprimées par le JMP new_function.
 

On retourne à la suite du programme...

Voilà avec ce patch le programme affiche les clefs si celle saisie n'est pas correcte !

Reste le problème de positionement du patch ???
 
 
 Patch d'un programme dont la décompression se fait en plusieurs phases

Quand le programme se charge en mémoire tout n'est pas immédiatement disponible.
Il y a un pré-loader qui va décompresser le loader qui va lui même décompresser le programme !
Avec entre deux des manipulations possible sur la table d'import ! (pas ici)
Cela peut paraître plus complexe que la normale MAIS il n'en est rien :
Voici un exemple d'implémentation du patch à l'adresse 005B2960 adresse laissée libre par le prog.
 
018F:005B2960  90                  NOP
018F:005B2961  52                  PUSH      EDX
018F:005B2962  BABD105B00          MOV       EDX,005B10BD
018F:005B2967  C702E9B81800        MOV       DWORD PTR [EDX],0018B8E9
018F:005B296D  C6420400            MOV       BYTE PTR [EDX+04],00
018F:005B2971  5A                  POP       EDX
018F:005B2972  E989E6FFFF          JMP       005B1000
018F:005B2977  90                  NOP
018F:005B2978  90                  NOP
018F:005B2979  90                  NOP
018F:005B297A  52                  PUSH      EDX
018F:005B297B  BA58155B00          MOV       EDX,005B1558
018F:005B2980  C702E9381400        MOV       DWORD PTR [EDX],001438E9
018F:005B2986  C6420400            MOV       BYTE PTR [EDX+04],00
018F:005B298A  5A                  POP       EDX
018F:005B298B  6800800000          PUSH      00008000
018F:005B2990  E92DE7FFFF          JMP       005B10C2
018F:005B2995  61                  POPAD
018F:005B2996  7508                JNZ       005B29A0
018F:005B2998  B801000000          MOV       EAX,00000001
018F:005B299D  C20C00              RET       000C
018F:005B29A0  52                  PUSH      EDX
018F:005B29A1  BADA8F4E00          MOV       EDX,004E8FDA
018F:005B29A6  66C702EB1A          MOV       WORD PTR [EDX],1AEB
018F:005B29AB  BA3A8A4D00          MOV       EDX,004D8A3A
018F:005B29B0  C702E9000000        MOV       DWORD PTR [EDX],7F9F0DE9
018F:005B29B6  C6420400            MOV       BYTE PTR [EDX+04],00
018F:005B29BA  5A                  POP       EDX
018F:005B29BB  50                  PUSH      EAX
018F:005B29BC  C3                  RET
018F:005B29BD  90                  NOP
018F:005B29BE  60                  PUSHAD
018F:005B29BF  8B75E8              MOV       ESI,[EBP-18]
018F:005B29C2  8B7DF8              MOV       EDI,[EBP-08]
018F:005B29C5  B916000000          MOV       ECX,00000016
018F:005B29CA  4F                  DEC       EDI
018F:005B29CB  6BFF18              IMUL      EDI,EDI,18
018F:005B29CE  81C780154B00        ADD       EDI,004B1580
018F:005B29D4  F2A4                REPNZ MOVSB
018F:005B29D6  66C7070D0A          MOV       WORD PTR [EDI],0A0D
018F:005B29DB  61                  POPAD
018F:005B29DC  33C0                XOR       EAX,EAX
018F:005B29DE  5A                  POP       EDX
018F:005B29DF  59                  POP       ECX
018F:005B29E0  59                  POP       ECX
018F:005B29E1  E95960F2FF          JMP       004D8A3F

On sauve EDX
On place l'adresse du patch
On place le code de JMP 005B297A
à l'adresse 005B10BD

On passe point d'entrée original.

//pour plus de clarté

On sauve EDX
On place l'adresse du patch
On place le code de JMP 005B2995
à l'adresse 005B1558

On execute les instructions manquantes et
on retourne au prog
*** le véritable patch
Ce qui précède ne sert qu'à arrivé ici !
// instructions supprimées par le patch
Sauve EDX
On place l'adresse du patch AntiSice
On place le code de jmp 004E8FF6
On procède de même pour la nouvelle fonction
en 004D8A3A (affichage des clefs...)

On restaure edx
On place EAX sur la pile et on retourne donc à l'adresse qui était dans EAX (le point d'entrée du programme décompressé ;o)

New_function : affichage des clefs
dans le message d'erreur...
On peut faire plus beau mais c'est juste
un exemple...(à ne pas suivre ;o))

Donc en résumé : on sait que l'on doit placer un patch à une certaine adresse avant le lancement
du programme décompressé. On place un break point mémoire en écriture sur cette adresse et on
regarde quand cette zone est écrite. On remonte de cette même façon étape par étape pour arriver
à une adresse écrite directement au chargement du programme compressé. Pour chaque étape il y
aura un patch qui va modifié le code pour permettre d'aller à l'étape suivante et ainsi de suite.
(Bon c'est peut-être pas très clair mais c'est assez évident à faire non ?)

Je retente une explication avec un dessin (texte) :

On détourne l'OEP (Point d'entrée original du prog compressé) pour aller sur un 1er patch:

PEP: Point d'entrée détourné vers le 1er patch
 xxx (xxx = instruction qqconque)
 XXX Ici on patch la partie 1 (PP1)
 xxx
 JMP OEP
PP1:
 xxx (xxx = instruction qqconque)
 XXX Ici on patch la partie 2 (PP2)
 xxx
 JMP RP1
PP2:
 xxx (xxx = instruction qqconque)
 XXX Ici on patch la partie 3 (PP3)
 xxx
 JMP RP2
Etc...

OEP:
 xxx
 xxx
 XXX ici décompression de la partie 2
 PP1 Jmp sur le patch
RP1: Adresse de retour aprés le patch
 xxx
 xxx
 xxx suite du prog
 xxx
 xxx
 XXX ici décompression de la partie 3
 PP2 Jmp sur le patch
RP2: Adresse de retour aprés le patch
 xxx suite du prog
 xxx
 xxx
Etc...

Je ne sais si c'est beaucoup plus clair mais en réfléchissant un tout petit peu...
 
 
 
Nous voilà donc à la fin de notre étude...
Les secrets de la protection de System Mechanic sont connus !

Pour ceux qui se demandent pourquoi il y a, cette fois-ci, toutes les adresses à patcher ?
Réponse : Généralement je ne le fais pas mais cette fois-ci avec un anti-sice qui plante le PC,
je livre plus d'infos pour éviter que les utilisateurs malheureux ne perdent leurs données en cours ;o) !

PAS DE SITE PAS D'ADRESSE EMAIL :
Question ? => posez-les sur les forums français...
SVP: POSEZ DES QUESTIONS EN RAPPORT AVEC CETTE ETUDE ou LE REVERSE ! (merci)


 
 

Comme toujours : 

VOUS NE DEVEZ PAS UTILISER CE COURS POUR OBTENIR ILLEGALEMENT DES PROGRAMMES.
IL DOIT JUSTE SERVIR A VOTRE EDUCATION.
AVOIR CE COURS EST LEGAL MAIS L'APPLIQUER NE L'EST PAS !!!