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 !