|
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.
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 :
|
|
|
|
|
|
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.)
|
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)
TaskLock : http://users.aol.com/Jajernigan/sgllck30.zip
CommandLine95 : ftp://ftp.winsite.com/pub/pc/win95/miscutil/cline95.zip
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