ED!SON WINDOWS 95 Cracking Tutorial v 1.00


 
 
SOMMAIRE 
 
 

1. Introduction au cracking sous Zindows 95
2. Petite intro sur SoftIce 2.00 (pour Zin 95)
3. Trouvez les serials (code d'enregistrement)
    3.1. Task Lock 3.0 – un simple numéro d'enregistrement
    3.2. Command Line 95 – un simple nom / code d'enregistrement
4. Créer un générateur de code pour Command Line 95
5. Comment les instructions "Push", "Call" & autres fonctionnent lors d'un appel de fonction
6. A propos des programmes en Visual Basic

Annexes :
A.Syntaxe des fonctions
B.Où trouver la marchandise ?
C.Contactez – moi


1) Introduction au cracking sous Zin 95

 Craquer un programme sous Windows est nettement plus facile que de craquer un programme sous Dos. Sous Windows, il est très difficile de cacher quelque chose à quelqu'un qui trifouille pour chercher des infos, du moins tant que les fonctions de programmation propre à Zindows sont utilisées (les API).

 Le premier outil dont vous avez besoin (et de loin le seul) est SoftIce 2 / Win95 (note de TaZ : une version 3.24 est dispo ainsi qu'une mise à jour pour Zin 98, à vous de chercher sur le net), le meilleur débuggueur de chez Numega. Certaines personnes le trouve difficile à utiliser (note de TaZ : ça tombe bien, on trouve des explications sur ce site) mais je vais vous expliquer comment être efficace avec, en espérant que vous me comprendrez :-) (note de TaZ : une doc complète de SoftIce est dispo sur le site de Lord Caligo ainsi que sur d'autres sites).

 Toutes les adresses qui vous permettront de trouver la marchandise se trouvent en annexe.

2) Rapide Intro à SoftIce

 Voici une pseudo représentation d'un écran de SoftIce :

 
Registres Utilisez la touche R pour les éditer
Fenêtre de données Utilisez la touche D pour voir une adresse, E pour l'éditer
Code ASM Utilisez la touche V pour voir une adresse, A pour insérer du code
Fenêtre de commande Tapez les commandes et lisez le résultat
 

 D'autres commandes importantes :

  Ø H / F1 - Aide
  Ø F5 / CTRL + D - Exécution du programme
  Ø F8 - Trace into
  Ø F10 - Trace over

(Pour de plus amples détails, voir la doc de Cyberbobjr)

3) TrouveR les codes d'enregistrements

 C'est sûrement la façon la plus simple de s'entraîner que de trouver un shareware et d'essayer de s'enregistrer.

    3.1) Task Lock 3 - un simple numéro d'enregistrement

 Voici une protection simple, un code qui ne change jamais !

        3.1.1) Examinons le programme

 Est - il en 16 ou 32 bit ? Où dois - je entrer le code d'enregistrement ? Est - ce que l'aide peut m'apporter des indices sur la manière dont l'enregistrement fonctionne (TaZ : on se croirait au Cluedo) ? Allons - y et dénichons queque chose avant de continuer !

 ... Vous devriez être en train de chercher ? ... Est - ce que vous cherchez ? ... Avez - vous cherché ?

 OK, vous savez maintenant que c'est une application 32 bit qui tourne sur Zin 95 et que vous pouvez enregistrer le programme en entrant simplement un code d'enregistrement dans une boîte de dialogue qui apparaît lorsqu'on choisit dans le menu "Register / Register ...". Vous savez également, après avoir lu l'aide, qu'il existe deux types d'enregistrement : individuel ou plate - forme. Il y a de fortes probabilités qu'il y aura 2 recherches à faire pour trouver les codes.

        3.1.2) Les routines de code

 Les codes sont généralement saisis dans une fenêtre d'édition de Windows. Pour trouvez le code, le programme doit lire le contenu de la fenêtre d'édition grâce à une de ces fonctions :
 
 
16 bit
32 bit 
GetWindowText 
GetWindowTextA, GetWindowTextW 
GetDlgitemText
GetDlgitemTextA, GetDlgitemTextW 
 
 
 Auriez - vous la même idée que moi ? Si l'on posait un breakpoint ("point d'arrêt") sur la fonction "GetWindowText" ?

 Pour poser un breakpoint dans SoftIce, vous devez d'abord entrer dans le débuggueur en appuyant sur CTRL + D, ensuite utilisez la commande BPX suivie du nom de la fonction ou de son adresse mémoire. TaskLock étant un programme 32 bit, posons un breakpoint sur "GetWindowTextA". Si cela ne fonctionne pas, vous pouvez essayer les autres. Tapez ceci (sous SoftIce) :
 :bpx getwindowtexta

 Si vous obtenez un message d'erreur comme "No LTD", assurez - vous qu'aucune autres applications ne tournent en tâche de fond. J'ai remarqué que Norton Commander sous Dos pouvait interférer avec cette fonction. Vous pouvez lister vos breakpoints en tapant :
 :bl

 Cela devrait ressembler à queque chose comme ça :
  00) BPX USER32! GetWindowTextA c=01

 Pour sortir de SoftIce, pressez à nouveau les touches CTRL + D.

 Voilà, vous avez posé votre breakpoint qui interceptera tous les appels de la fonction GetWindowTextA. Bon, maintenant essayons d'entrer une valeur dans le champ d'enregistrement et cliquez sur OK ... et la une s*******e de boîte de dialogue vous annonce que votre code est faux. Ce n'était pas le bon breakpoint, posons le sur GetDlgItemTextA.

 D'abord, effaçons l'ancien breakpoint :
  : bc 0  (0 est le numéro du breakpoint dans la liste)
 

 Posons le nouveau :
  :bpx getdlgitemtexta

 Essayons ...

        3.1.3) Dans le débuggueur

 Ca marche ! Vous êtes maintenant dans SoftIce, à l'endroit où la fonction GetDlgItemTextA commence. Pour aller à l'endroit où elle est appelée, pressez la touche F11. Vous êtes maintenant dans SGLSET.EXE. Si vous n'êtes pas sûr, regardez la ligne avant le code et la fenêtre de commande, ça pourrait ressemblez à ça :

----------------------------------- SGLSET ! . text+1b13 --------------

 Vous pouvez supprimer le breakpoint en tapant :
  :bd 0

 Pour le réactiver plus par exemple, il suffit de taper :
  :be 0

 La première ligne dans la fenêtre de code devrait ressembler à ça :

  CALL [user32!GetDlgItemTextA]

 Pour voir les lignes suivantes, pressez les touches CTRL + HAUT quelques fois, jusqu'à ce que vous voyez les lignes suivantes apparaître. Si vous ne connaissez rien à l'assembleur (TaZ : il faudrait s'y mettre, ça aide plus qu'on ne croit pour le cracking !!!), j'ai ajouté des commentaires au code :

 RET                       ; fin de fonction
 PUSH  EBP                 ; début de la fonction
 MOV  EBP, ESP             ; ...
 SUB  ESP                  ; ...
 PUSH  ESI                 ; ...
 LEA  EAX, [EBP-34]        ; EAX = EBP-34
 PUSH  EDI                 ; ...
 MOV  ESI, ECX             ; ...
 PUSH  32                  ; sauve la longueur maxi accepté
 PUSH  EAX                 ; sauve la valeur EAX
 PUSH  000003F4            ;sauve l'identificateur de contrôle
 PUSH  DWORD PTR [ESI+1C]  ;
 CALL  [user32!GetDlgItemTextA]  ;appel de la fonction

 L'instruction "PUSH" sauve une valeur dans la pile pour une utilisation ultérieure. Après avoir analysé le code, on sait que le texte est sauvegardé en EAX et que EAX est égal à EBP-34. Donc, regardons la valeur EBP-34 en tapant :
  :d ebp-34

 Vous pouvez lire la valeur que vous avez entré si vous consultez la fenêtre de données. Maintenant, il nous faut trouver l'endroit où votre code est comparé au code valable pour enregistrer le logiciel. Donc, on remonte dans le programme, instruction par instruction avec la touche F10 jusqu'à ce que l'on trouve queque chose à propos de EBP-34 ... Vous ne remonterez pas longtemps avant de voir un code qui ressemble à ça :

LEA  EAX, [EBP+FFFFFF64]      ; EAX = EBP-9C
LEA  ECX, [EBP-34]            ; ECX = EBP-34
PUSH EAX                      ; sauve EAX
PUSH ECX                      ; sauve ECX
CALL 00403DD0                 ; appel une fonction
ADD  ESP, 08                  ; efface l'info sauvée
TEST EAX, EAX                 ;
JNZ  00402BC0                 ; saut si différent de 0

 A mon avis, cela ressemble à une comparaison de chaîne de caractères. Cela fonctionne de la façon suivante : entrée de 2 chaînes de caractères, prend la valeur 0 si identique sinon différent de 0.

 Et pourquoi, à votre avis, le programme compare une chaîne de caractère à une autre saisie, pour voir si celle - ci est valide (je pense que vous aviez déjà compris).

 Bon qu'est - ce qui se cache derrière la valeur [EBP+FFFFFF64] ? SoftIce ne gère pas bien les nombres négatifs, donc pour trouver la valeur, il faut effectuer le calcul :

  100000000 - FFFFFF64 = 9C

 Vous pouvez aussi faire le calcul sous SoftIce de la façon suivante :
  : ? 0 - FFFFFF64

 Le nombre 100000000 est trop grand pour SoftIce mais de toute manière, on obtient le même résultat. Et maintenant, regardons ce qui se cache derrière EBP-9C en tapant :
  : d ebp-9c

 La fenêtre de données nous donne une longue suite de nombre - c'est le bon code - ! Mais rappelez - vous ce que je disais précédemment... 2 types d'enregistrement donnent 2 codes ... donc après avoir écrit le code obtenu, on continue à remonter avec F10 et on arrive au code suivant :

LEA  EAX, [EBP-68]   ; EAX = EBP - 68
LEA  ECX, [EBP-34]   ; ECX = EBP - 34
PUSH EAX             ; sauve EAX
PUSH ECX             ; sauve ECX
CALL 00403DD0        ; appel une fonction
ADD  ESP, 08         ; efface l'info sauvegardée
TEST EAX, EAX        ;
JNZ  00402BFF        ; saut si différent de 0

 Et que trouvez - vous à l'adresse EBP-68 ? ... un autre code d'enregistrement.

 Voilà, j'espère que tout fonctionne ...
 

    3.2) Command Line 95 - un simple Nom / Code d'enregistrement

 C'est un bon petit programme avec un simple schéma de protection.

        3.2.1) Examinons le programme

 Vous vous apercevrez que c'est une application 32 bit, avec un nom et un code d'enregistrement à entrer dans une fenêtre de dialogue. Attaquons !

        3.2.2) Repérage de la routine

 Même principe que pour TaskLock pour les breakpoints. On peut poser des breakpoints à la fois sur GetWindowTextA et GetDlgItemTextA. Basculez sous SoftIce (CTRL + D) et tapez :
  : bpx getwindowtexta
  : bpx getdlgitemtexta

 Entamez la phase d'enregistrement en entrant un nom et un code dans le fenêtre prévue à cet effet. Par exemple :
  Nom : ED!SON '96
  Code : 12345

 Le programme s'arrête sur GetDlgItemTextA. Comme pour TaskLock, on se sert de F11 pour retourner à la fonction d'appel. Ensuite, on se sert de CTRL + HAUT pour arriver au code suivant :

MOV  ESI, [ESP+0C]   ; longueur maxi
PUSH 1E              ;
PUSH 0040A680        ;
PUSH 000003ED        ;
PUSH ESI             ;
CALL [User32!GetDlgItemTextA]  ; appel de la fonction

 Le nombre 40A680 semble intéressant, voyons sa valeur :
  : d 40a680

 Et voilà ce qu'on obtient dans la fenêtre de données si un nom n'est pas saisi :

PUSH 00              ; rien à cirer
PUSH 00              ; de même
PUSH 000003F6        ;
MOV  EDI, 0040A680   ;
PUSH ESI             ;
CALL [User32!GetDlgItemInt]  ; appel de la fonction

GetDlgItemInt et GetDlgItemText sont deux fonctions similaires mais elles nécessitent une réference de la boite d'edition. Il est stocké en EAX et si l'on regarde la fenêtre de registres, on peut lire :
  EAX = 00003039

 Convertissons le chiffre hexadécimal 3039 en tapant :
  : ? 3039

 et l'on obtient :
  00003039   0000012345   "09"
    Hex         Déc       Ascii

 Et voilà le code entré puis si l'on regarde le code qui suit, il est sauvegardé :

MOV  [0040A548], EAX   ;
MOV  EDX, EAX          ;

        3.2.3) Calcul du code et validation du code

 Calcul

MOV  ECX, FFFFFFFF               ; calcul de la longueur de la chaîne
SUB  EAX, EAX                    ; ...
REPNZ SCASB                      ; ...
NOT  ECX                         ; ...
DEC  ECX                         ; ECX contient la valeur de la longueur
MOVSX EAX, BYTE PTR [0040A680]   ;
IMUL ECX, EAX                    ; ECX = ECX * EAX
SHL  ECX, 0A                     ; décalage logique à gauche de 0A
ADD  ECX, 0002F8CC               ; ajoute 2F8CC au résultat
MOV  [0040A664], ECX             ;

 Validation

CMP  ECX, EDX    ; comparaison des codes
JZ  00402DA6     ; si égal à 0, saut

 Si vous aviez esquivé la comparaison des codes, vous auriez pu voir ce qu'aurait été votre code en tapant :
 : ? ECX

 Pour notre code, ça donne : 000DC0CC 0000901324

 Donc le bon code est : 901324.

 Retournez au programme en pressant CTRL + D ou F5 et essayiez d'entrer le bon code ... Ca roule !

4) Création d'un générateur de code d'enregistrement pour Command Line 95

 Analysons à nouveau le calcul du code et traduisons le en C. Voilà ce que ça donne :

 code = ((uppercase_first_char * lentgh_of_string) <<0x0A + 0x2F8CC)

Remarque : la chose à ne pas oublier est que tous les caractères sont convertis quand ils sont saisis dans la boîte de dialogue, nous devons donc faire la même chose.
 << 0x0A "signifie multiplié par 2^10"

Un petit programme en C pourrait ressembler à ça :
 #include <string.h>
 #include <stdio.h>

 int main()
 {
  unsigned long code;
  unsigned char buffer [0x1E];

  printf("CommandLine 95 Keymaker by ED!SON '96\n");
  printf("Enter name :     ");
  gets(buffer);

  strupr(buffer);
  code = ( ((unsigned long)buffer[0] * (unsigned long)strlen(buffer))<< 0x0A) + 0x2F8CC;

  printf("Your code is : %lu", code);

  return 0;
}

5) Comment les instructions "CALL", "PUSH" et autres fonctionne quand le programme appelle une fonction

 Analysons à nouveau le code de Tasklock :

PUSH 32                  ; sauve longueur maxi de la chaîne
PUSH EAX                 ; sauve dans la pile
PUSH 000003F4            ; sauve identificateur de contrôle
PUSH DWORD PTR [ESI+1C]  ; sauve la zone mémoire dans laquelle la valeur va être saisie
CALL [USER32!GetDlgItemTextA] ;

 En langage C, ça pourrait ressembler à ça :

  GetDlgItemTextA (hwndDlg, 0x3F4, buffer, 0x32);
     ^-- [ESI+1C]       ^-- EAX

 L'instruction "PUSH" sauvegarde des données dans la pile. Chaque nouvelle instruction "PUSH" ajoute une valeur de plus dans la pile et ensuite l'instruction cherche ce qui ne colle pas dans la pile pour faire ce que vous savez (TaZ : sensé nous e******r).

6) A propos des programmes en visual basic

 Les fichiers exécutables en Visual Basic ne le sont pas vraiment. Ils contiennent uniquement du code pour appeler une DLL du style VBRUNxxx.DLL qui lit les instructions dont le programme a besoin pour tourner. C'est pour cette raison que les programmes sont si lents, et qu'ils ne peuvent être désassemblées.

 La solution est un décompilateur, pour les versions 2 et 3 de Visual Basic, il en existe un appelé DODI (shareware se trouvant sur le net, sous Zin 95, il existe une version 4 de Visual Basic - 32 bit - mais on ne trouve pas de décompilateur, du moins pour le moment.

Remarque : les vrais programmeurs ne codent pas en basic !!

(TaZ : ce tutorial bien ficelé date d'au moins deux ans c'est pour cette raison que de nouvelles versions de programmes comme Visual Basic 5 et même 6 ne sont pas mentionnés. Les adresses que vous trouverez après ne sont également plus valables mais sont citées pour info, un p'tit mail et je vous les envoie.)
 
 

ANNEXES 
 

A. Syntaxe des fonctions

Il est plus facile de comprendre les fonctions dont on parle quand elles sont traduites de la façon suivante (C) :

 int GetWindowText (int windowhandle, char *buffer, int maxlen);
 int GetDlgItemText (int dialoghandle, in controlid, char *buffer, int maxlen);
 int GetDlgItem (int dialoghandle, int controlid, int *flag, int type);

Pour une description plus approfondie des fonctions, consultez un livre sur les API de Zindows 95 (TaZ : voir la référence exacte de ce livre sur ce site)

B. Où obtenir les logiciels ?

 TaskLock : http://users.aol.com/Jajernigan/sgllck30.zip
 CommandLine95 : ftp://ftp.winsite.com/pub/pc/win95/miscutil/cline95.zip

C. Contactez - moi

 On IRC (EFnet) : In #Ucf96, #Cracking
 E-mail : edison@ccnux.utm.my ou an461165@anon.penet.fi
 Sur mon site : http://www.geocities.com/soho/2680/cracking.html


Tarduit par TaZ le 29/05/1998