Comment keygener pas mal de programmes (utilisation des BPR...)

Avant de vous parler des methodes comme l'utilisation de BPR, je vais vous decrire ce qu'est le keygening pour ceux qui ne savent pas !!
Keygener un programme c'est quoi ?
c'est ecrire un programme qui genere des clefs (serials) valides pour un programme donnes , en fonction des noms , numero de serie du disque dur ...
Bref, on trace avec soft ice la generation du serial en memoire et on reprogramme ceci , afin que l'on obtiene les codes valides pour ce programme tres rapidement :)
C'est tres interressant , croyez moi :)
bon tout d'abord , je vais vous montrer un exemple tres simple !!
sans methode specifique , et ensuite , dans un prochain exemple
vous montrez qu'utilisez les BPR est un gain de temps non negligable !!

************************************************************************
** How to keygen the Cracking4newies Crackme 3 project **
************************************************************************

niveau: debutant

I)C'est parti !!

Ok, c'est partie , il est temps de keygener cette chiotte :) donc dans soft
ice , mettez vos BPX preferes !! ceus utiliser dans les protections par
names / serials :
bpx getwindowtewta et getdlgitemtexta.

Entrez votre nom et un faut serial (name : ACiD BuRN / Serial : 12345).
Clickez sur enter et vous etes de retour dans soft ice !!
pressez F12 parce que vous n'etes pas a la bonne place , mais dans cette merde
de user32.dll...
Maitentant , vous etes dans le crackme ! (j'espere que vous comprendez tout,
je suis trop fatigue !)
Tracez tant que vous n'arrivez pas a ca:


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010C6(C)
|
:004010AF 0FBE4415C0 movsx eax, byte ptr [ebp+edx-40]
; mets en eax la 1ere valeur ascii de votre nom (pour ACiD BuRN : A=41)

:004010B4 03F0   add esi, eax / 
:004010B6 8D7DC0 lea edi, dword ptr [ebp-40] / 
:004010B9 83C9FF or ecx, FFFFFFFF / 
:004010BC 33C0   xor eax, eax / 
:004010BE 42     inc edx / Boucle 
:004010BF F2     repnz /
:004010C0 AE     scasb /
:004010C1 F7D1   not ecx /
:004010C3 49     dec ecx / 
:004010C4 3BD1   cmp edx, ecx / 
:004010C6 76E7   jbe 004010AF / 

ok cool, mais que fait cette boucle ? :

movsx eax, byte ptr [ebp+edx-40] <== eax = valeur ascii du caractere a la position EDX
add esi, eax <== esi = esi + eax
inc edx <== caractere suivant
cmp edx, ecx <== compare la longeur du nom avec le compter en edx
jbe 004010AF <== Boucle tant que tout les chars n'ont pas ete fait!

Donc , cette boucle prends les valuers ascii de chaque lettres et les ajoutes dans ESI.
Resulat pour ACiD BuRN: 2A8h

41h + 43h + 69h + 44h + 20h + 42h + 75h + 52h + 4E = 2A8h
A C i D space B u R N

Apres cette boucle , vous arrivez ici:

:004010C8 897508     mov dword ptr [ebp+08], esi ; [ebp+8] prends la valeur d'ESI
:004010CB C1650807   shl dword ptr [ebp+08], 07  ; [ebp+8] = shl [ebp+8],7
:004010CF 8D4DF4     lea ecx, dword ptr [ebp-0C] 
:004010D2 6A0A       push 0000000A
:004010D4 51         push ecx
:004010D5 68E9030000 push 000003E9
:004010DA 53         push ebx

Comme vous pouvez le voir, la valeur d'ESI (pour moi: 2A8) est place dans [ebp+8].
ensuite,on voit : shl dword ptr [ebp+08], 07
Interessant ;)
Ben, on continu a tracer :-]
tant que vous n'arrivez pas a ca :

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010E4(C)
|
:00401102 8D55F4      lea edx, dword ptr [ebp-0C]
:00401105 52          push edx
:00401106 E840010000  call 0040124B
:0040110B 8B4D08      mov ecx, dword ptr [ebp+08] ; ECX = [ebp+8] ([ebp+8]= shl esi,7)
:0040110E 83C404      add esp, 00000004
:00401111 03CE        add ecx, esi                ; ECX = ECX + ESI (ESI=2A8 pour moi)
:00401113 3BC8        cmp ecx, eax                ; ? eax = fake serial / ? ecx = bon
:00401115 6A00        push 00000000
:00401117 751B        jne 00401134                ; si c'est pas egal saute a BAD CRACKER

* Possible StringData Ref from Data Obj ->"Good!"
|
:00401119 685C504000 push 0040505C

* Possible StringData Ref from Data Obj ->"Congratulations!!"
|
:0040111E 6848504000 push 00405048
:00401123 53 push ebx

Sympa tout ca! vous pouvez coder un keygen facilement non ? !!
laissez moi vous repetez l'algo:

1st part: additionez les valeurs ascii du nom et mettre le resulat qq part (ESI en memoire)
2nd part: Prendez la valeur en ESI et fait un shl,7 dessus et met le resultat qq part
([ebp+8] en memoire)

3rd part: additionez la valeur de la premiere partie et additionez la a celle de la
2eme partie.

4th part: Prenez le resultat en decimal et vous avez votre serial :)

Name : ACiD BuRN
sERiAL : 87720

Je vous ai tout donner pour faire votre propre keygen, mais je vous file qd meme mes sources:
je vais vous montrer 2 sources! une en delphi+asm et une en C+asm
celle en delphi a ete codé a 2h du matins !! vite fait :) mais ca marche :))


*********************SOURCES DELPHI************************

procedure TForm1.Edit1Change(Sender: TObject);

var i,ascii,result: integer;

begin
for i:=1 to length(edit1.text) do
begin

ascii:=ascii + ord(edit1.text[i]);
end;

asm
mov eax,ascii
mov ecx,ascii
shl eax,7
add eax,ecx
mov ascii,eax
end;

result:=ascii;
edit2.text:=inttostr(result);
end;
end.


*********************FIN DE SOURCES DELPHI*********************************************


Maintenant la version en C+asm (le C me sert juste pour declarer les variables!
Bien moin chiant que l'asm directe!!)

*********************SOURCES C++ + ASM************************************************

#include
#include
#include

int main(){
int i,len;

unsigned char name[100];

unsigned long check=0;

printf("\[ Cracking4Newbies crackme3 ] *Keygen* By : ACiD BuRN / ECLiPSE 1999\n");
printf("\______________________________________________________________________\n");
printf("\nEnter your name: ");
gets(name);
len=strlen(name);

asm
{

xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi
mov esi, [len]
start:

movsx eax, [name+ecx]
add edi, eax
mov eax, edi
inc ecx
cmp ecx, esi
jne start

shl edi, 7
add edi,eax
mov [check], edi

}

printf("Your Serial is: %lu" ,check);
printf("\nEnjoy!");
getch();
return 0;

}


*********************FIN DE SOURCES C++ + ASM****************************************


*************************************************************************************
**** BPR: La bonne methode :) ****
*************************************************************************************

Maintenant ! utilisation des BPR pour keygener !
La technique je vais vous montrer marche tres tres bien avec les programmes en C++ par exemple :)
je ne vais pas vous saoulez longtemps , mais ecrire directement un exemple d'utilisation de cette commande!!

on va bosser sur un Crackme: RD116 Crackme

Ok, la protection est de type name / serial! ca a ete ecrit en C++
Coool, tres bien pour s'amuser avec !!
On peut keygener ce crackme sans utiliser les BPR , mais grace aux BPR vous allez voir comment tomber directement sur la routine de generation du serial !!! let's go:

Entre votre nom : ACiD BuRN et serial: 112233
Sous soft ice mettez les bpx suivants: bpx getdlgitemtexta et bpx getwindowtexta ....
Ensuite pressez le bouton pour verifiez le serial et vous etes de retour sous soft ice!!
On voit "Break due to BPX USER32!GETWINDOWTEXTA ...
ok! alors ne pressez pas F11 ni F12 encore sinon on ne poura pas examiner les parametres sur la pile !!

On va agir inteligement plutot ! On va examnier la pile !
Nous allons regarder les parametres et mais pour cela on va se mettre en Dword sous soft ice !! ca sera plus lisible deja.
Sous soft ice: dd esp
"dd" veut dire: display dword et "esp" c'est pour le pointeur de pile!
Apres avoir fait "dd esp" la fenetre de soft ice change et on peut voir les parametres :

xxxx:yyyyyyyy A B C D ................
xxxx:yyyyyyyy E F G H ................

Ou A,B,C,D,E... sont du genre: XXXXXXXX

vous devez voir qq chose qui ressemble a cela:

xxxx:yyyyyyyy 5F403504 00000098 00654250 0000000A ...........
on ne vas s'occuper que de ca !!

(donc vous l'avez remarque , ici A=5F403504 , B=00000098 ...)
on voit ici l'addresse a laquelle notre nom se termine (00654250)

Tapez D "addresse a laquelle finis le nom"
exemple ici: D 00654250

vous pouvez maintenant pressez F11 et vous pourvez voir votre nom a l'addresse que vous avez tapez :) c bon signe deja !!

Nous allons maintentant poser un bpr (break on memory range)
cette type de bp marche de la facon suivante:

bpr "adresse de depart" "addresse de fin" RW

RW veut dire: Read et writte (lecture et ecriture)
Donc, sa stopera qd on lit ou ecrit a cette addresse en memoire !

Donc tapez ceci sous soft ice:
bpr 654250 654250+(longeur_du_nom - 1) rw

Dans notre exemple cela donne pour ACiD BuRN (longeur: 9 -> 9 - 1 = 8)

bpr 654250 654250+8 rw

Vous pouvez desactiver les bpx sur getwindowtexta et getdlgitemtexta now !
Vous n'avez plus qu'a presser F5, et on se retrouvera directement dans la routine de generation de serial !!

Notes: Pressez F5 tant que vous n'etes pas dans le crackme !!
c'est a dire que les DLL on s'en branle :)

Une fois que vous etes dans le crackme vous arrivez directe sur la generation.

une partie qui bosse sur le nom:

:00401580 8A18        mov bl, byte ptr [eax]      ; Prends la valeur ascii (position cl)
:00401582 32D9        xor bl, cl                  ; XOR cette valeur avec le compteur
:00401584 8818        mov byte ptr [eax], bl      ; store le resultat
:00401586 41          inc ecx                     ; incremente ecx (ecx = ecx + 1 )
:00401587 40          inc eax                     ; incremente eax (eax = eax + 1 )
:00401588 803800      cmp byte ptr [eax], 00      ; encore des lettres ? 
:0040158B 75F3        jne 00401580                ; si oui, lettre suivante!
:0040158D 33C0        xor eax, eax                ; remet a zero 
:0040158F 33DB        xor ebx, ebx                ; les registres
:00401591 33C9        xor ecx, ecx                ; EAX, EBX, ECX
:00401593 B90A000000  mov ecx, 0000000A           ; ECX = Ah (10 en hexa)
:00401598 33D2        xor edx, edx                ; EDX = 0
:0040159A 8B45F0      mov eax, dword ptr [ebp-10] ; on recupere les valeurs


2eme partie: sur le serial entre :

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004015A8(C)
|
:0040159D 8A18       mov bl, byte ptr [eax]    ; Prends la valeur ascii (position cl)
:0040159F 32D9       xor bl, cl                ; XOR cette valeur avec le compteur
:004015A1 8818       mov byte ptr [eax], bl    ; store le resultat
:004015A3 41         inc ecx                   ; incremente ecx (ecx = ecx + 1 )
:004015A4 40         inc eax                   ; incremente eax (eax = eax + 1 )
:004015A5 803800     cmp byte ptr [eax], 00    ; encore des chiffres ?
:004015A8 75F3       jne 0040159D
:004015AA 8B45E4     mov eax, dword ptr [ebp-1C]
:004015AD 8B55F0     mov edx, dword ptr [ebp-10]


Et la derniere routine: verification du serial

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004015BF(C)
|
:004015B0 33C9      xor ecx, ecx            ; ECX = 0
:004015B2 8A18      mov bl, byte ptr [eax]  ; on recupere les valeurs et on les
:004015B4 8A0A      mov cl, byte ptr [edx]  ; mets dans EAX et EDX
:004015B6 3AD9      cmp bl, cl              ; on compare! c'est egale ? 
:004015B8 7509      jne 004015C3            ; non jmp : bad cracker
:004015BA 40        inc eax                 ; eax = eax + 1
:004015BB 42        inc edx                 ; edx = edx + 1
:004015BC 803800    cmp byte ptr [eax], 00  ; on fait ca pour tout !
:004015BF 75EF      jne 004015B0
:004015C1 EB16      jmp 004015D9            ; si tout est ok! GENTIL CRACKER

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401503(U), :0040151C(U), :004015B8(C)
|
:004015C3 6A00      push 00000000

* Possible StringData Ref from Data Obj ->"Rat"
|
:004015C5 686C3040  push 0040306C

* Possible StringData Ref from Data Obj ->"Mauvais serial, essaye encore... "

..........


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004015C1(U)
|
:004015D9 6A00         push 00000000   ; tout est ok !! on arrive ici

* Possible StringData Ref from Data Obj ->"Bien jou"
|
:004015DB 6834304000  push 00403034

* Possible StringData Ref from Data Obj ->"C' est crack"
|
:004015E0 6820304000  push 00403020
:004015E5 8B4DE0      mov ecx, dword ptr [ebp-20]


Donc voila !! je crois que vous avez compris ce qu'il se passe ici :)
La routine de genearation est tres simple !!
je ne vais donc pas m'attarder dessus , mais je vais donner les sources du keygen
bien sur !!
Apres le C++ , le delphi , c'est autour du VB !!
Ayant la flemme de traduire ca en ASM (tres simple , mais j'ai pas le gout) je vous
propose tout de meme ces sources !!

Le but de cette explication etait la familiarisation avec les BPR !!
Pas de savoir keygener juste ce crackme la !!
Avec cette technique vous pouvez keygener bcp de choses , ensuite ca depends
de votre niveau en asm et de la registration !!
si ca fait 1000 lignes ! on fait copier coller ;) et on programme en ASM
sans trop se poser de questions !
bref , voici les sources:

********************** Source en VB: RDD-116 Crackme 1 Keygen***********************

Private Sub Text1_Change()
If Len(Text1.Text) < 6 Then

Text2.Text = "Le nom doit etre superieur à 6 chars"
Else
For i = 1 To Len(Text1.Text)
a = 9 + i
temp = Asc(Mid$(Text1.Text, i, 1)) Xor i Xor a
result = result & Chr(temp)
Next i

Text2.Text = result
End If
End Sub


********************** Source en VB: RDD-116 Crackme 1 Keygen***********************


hehe simple non ?
voila, la partie des keygens est terminee, mais entrainez vous avec les BPR!
c'est super et utilise par bcp de keygners aussi...
Pour le delphi, il vous faut trouver l'addresse memoire de votre nom et faire a peu pres la meme chose ensuite :))
Enjoy !