SMCrackMe de Kharneth - Solution d'elooo

Valid XHTML 1.1! Valid CSS!

Télécharger la cible

NiveauOutilsAuteur
Newbie avancéOllydbgelooo

Sommaire

Introduction

Pour ce crackme (qui est en fait un keygenme, l'unique but étant de coder un keygen), Kharneth s'est particulièrement éclaté avec le junk code).
Si vous avez pris la peine de le tracer un peu, vous avez pu voir à quoi ça ressemblait dans le debugger :

Si on recolle le code après l'avoir rendu lisible, et en le posant en séquentiel, voyez ce que ça donne, via les screenshots successifs.

Retour au sommaire

Etude du code

Image 1

Du junk code qui sert à rien mis à part à nous faire sauter tout partout :)
Ca m'a fait penser à mon WTF_CrackMe quand je suis tombée là-dessus ;)

Image 2

On récupère l'adresse vers le jmp GetDlgItemTextA dans l'IAT, puis on lui soustrait 0xB1600B5.

Image 3
Image 4
Image 5
Image 6
Image 7

Du junk code toujours,et on rétablit la pile.

Image 8
Image 9
Image 10

Ci-dessus par exemple,on voit particulièrement bien l'émulation de jump, via des pushs suivis de ret.

Image 11
Image 12

On voit le passage d'arguments pour GetDlgItemTextA:

Image 13
Image 14

Ici on calcule la valeur d'eax (en lui rajoutant 0xB1600B5 qui avait été soustrait auparavant), afin de récupérer la bonne valeur qui nous fera sauter vers GetDlgItemTextA.

Image 15

On teste si au moins un caractère a été entré dans l'editbox. Si c'est le cas, on stocke le nombre de caractères de la string dans [00403055].

Image 16
Image 17

Junk code toujours, et on rétablit la pile.

Image 18
Image 19
Image 20

Ci-dessus on retrouve encore les jump émulés.

Image 21

Même principe que pour GetDlgItemTextA : on récupère l'adresse vers le jmp CharUpperA dans l'IAT et on lui soustrait une valeur.

Image 22
Image 23

On passe les paramètres pour CharUpperA sur la pile puis on l'appelle.
En fait, il met le nom entré en majuscules.

Image 24
Image 25

On récupère le nom NETBIOS de la machine depuis laquelle est lancé le keygenme, via GetComputername.

Puis vient l'algo de génération du serial avec les screenshots ci-dessous. Je pense que je n'ai pas besoin de commenter plus. L'algo n'est pas compliqué à comprendre.

Image 26
Image 27
Image 28
Image 29
Image 30
Image 31
Image 32
Image 33
Image 34
Image 35
Image 36
Image 37
Image 38
Image 39

Je n'ai pas regardé la suite, mais on peut supposer qu'il va récupérer ensuite le serial entré et le comparer au serial qui a été généré grace à l'algo précédent.
On a largement assez d'info là pour coder notre keygen :)

Retour au sommaire

Source du keygen en asm

Donc voici la source en asm (masm) de mon keygen pour le keygenme de Kharneth.
C'est pas du grand art, juste du code "à la elooo"...

;======================================================================
;	SMCrackMe_keygen
;	elooo
;======================================================================
.486p
.model flat, stdcall
option casemap :none
;======================================================================
;   Includes
;======================================================================
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
;======================================================================
;   Macros
;======================================================================
      print MACRO Quoted_Text:VARARG
        LOCAL Txt
          .data
            Txt db Quoted_Text,0
          .code
            invoke StdOut,ADDR Txt
      ENDM

      input MACRO Quoted_Prompt_Text:VARARG
        LOCAL Txt
        LOCAL Buffer
          .data
            Txt db Quoted_Prompt_Text,0
            Buffer db 512 dup(0)
          .code
            invoke StdOut,ADDR Txt
            invoke StdIn,ADDR Buffer,LENGTHOF Buffer
            mov eax, offset Buffer
      ENDM
;======================================================================
;   DATA
;======================================================================
.data
Taille          dd 512
Taille2         dd 512
;======================================================================
;   DATA?
;======================================================================
.data?
ComputerName    db 512 dup (?)  ; buffer du nom du computer
offsetNom       dword ?         ; offset du buffer du nom entre
;======================================================================
;   CODE
;======================================================================
.code
start:
pushad

	print 13,10,"********************************************************"
	print 13,10,"*                 SMCrackMe de Kharneth                *"	
	print 13,10,"*                    Keygen par elooo                  *"
	print 13,10,"*                      Code en asm                     *"	
	print 13,10,"********************************************************"
	print 13,10,13,10
	
	invoke GetComputerName, addr ComputerName, addr Taille	
	.if eax != NULL
		print "ComputerName = "
		invoke StdOut, addr ComputerName
		xor eax, eax
		mov ecx, 1Ah
		mov esi, offset ComputerName
		mov edi, esi 
		
@@:		lodsb
		or al, al
		je fincomputername
		cdq
		div ecx
		mov al, dl
		stosb
		jmp @B
		
fincomputername:		
		input 13,10,"Entre un nom : "
		mov offsetNom, eax
		invoke CharUpperBuff, offsetNom, Taille2
		mov esi, offsetNom
		mov edi, esi
		xor eax, eax
		xor ebx, ebx		
		mov ecx, 1Ah

boucle2:		
		lodsb
		cmp al, 0Dh
		jne goboucle2
		test ebx, ebx
		jz fincomputername
		jmp finnom		
goboucle2:
		cmp al, 41h
		jl badChar
		cmp al, 5Ah
		jg badChar
		sub al, 41h
		cdq
		div ecx
		cmp byte ptr [ComputerName+ebx], 0
		jne @F
		xor ebx, ebx
@@:		add dl, byte ptr [ComputerName+ebx]		
		inc ebx
		add dl, 41h
		mov al, dl
		cmp al, 5Ah
		jle @F
		sub al, 5Ah
		add al, 40h
@@:		stosb
		jmp boucle2
		
badChar:
		print 13,10,0
		print "Je ne gere que les noms a caracteres alphabetiques coco :("
		jmp fincomputername	
		
finnom:
		print 13,10,"Et ton serial tant attendu est : "
		invoke StdOut, offsetNom
		
	.else 
		print "WTF ? Pas moyen de recuperer le nom NETBIOS de ta machine :o ",13, 10	
	.endif
	
	invoke ExitProcess,0		
popad
END start

Le keygen est téléchargeable ici.

Retour au sommaire

Cordialement,
elooo.

Retour au sommaire