Fornixcrackme1
(Auto-KeyGen)

by "x86"

 

10/09/2004

UIC's Home Page

Published by Quequero

Che mondo sarebbe senza un Chinotto ...

Grazie xu :)

C'è almeno qualcuno a cui piace nel Chan ?

....

Home page (se presente): non ancora presente :\
E-mail: [email protected]
Nick x86, canale IRC/EFnet frequentato #crack-it

....

Difficoltà

(x)NewBies ( )Intermedio ( )Avanzato ( )Master

 
 

Introduzione

A questo crackme nn serve nessuna introduzione, ero alla ricerca di un crackme e sbadatamente ho scaricato una cosa per un'altra, dopo averlo iniziato a guardare in Ida, ho capito che era troppo facile e che avevo sbagliato target, ma oramai gli avevo dedicato troppo tempo e così ho deciso di scrivere un tute......

Tools usati

Basta solo Ida per capire il crackme, se poi volete anche provare a modificare il crackme per farlo diventare un Auto-KeyGen potete utilizzare anche OllyDbg

URL o FTP del programma

Io l'ho trovato su www.crackmes.de

Notizie sul programma

Notizie: Bah, l'unica cosa interessante si può trovare nelle note è: Serial is machine dependent

Essay


Per prima cosa prendete Ida e aspettate che lo dissasembli tutto, ci metterà due secondi, inoltre vi dico subito che il crackme non è cryptato, altro problema in meno, forse se lo era mi divertivo di più! una volta finito iniziamo a dare un'okkiata al codice, tralasciamo la prima parte del codice, che serve a caricare le risorse e precisamente la musichetta che sentirete appena mandate il crackme in esecuzione, andiamo avanti e dirigiamoci sulla DialogProcedure, all'inidirizzo .text:00401096, poco sotto ho trovato le due Call SendDlgItemMessageA che come Msg hanno WM_GETTEXT, quindi è in questo punto prenderà il testo del nickname e del serial. Iniziamo subito a vedere cosa fa il crackme una volta preso i valori del nickname e del serial
:
.text:00401182 mov eax, offset NickName
.text:00401187 push eax ; lParam
.text:00401188 push 14h ; wParam
.text:0040118A push WM_GETTEXT ; Msg
.text:0040118C push 64h ; nIDDlgItem
.text:0040118E push [ebp+hDlg] ; hDlg
.text:00401191 call SendDlgItemMessageA
.text:00401196 mov eax, offset Serial
.text:0040119B push eax ; lParam
.text:0040119C push 0Ah ; wParam
.text:0040119E push WM_GETTEXT ; Msg
.text:004011A0 push 65h ; nIDDlgItem
.text:004011A2 push [ebp+hDlg] ; hDlg
.text:004011A5 call SendDlgItemMessageA
.text:004011AA push offset NickName ; lpString
.text:004011AF call lstrlenA
.text:004011B4 mov [ebp+var_4], eax
.text:004011B7 cmp eax, 4
.text:004011BA ja short loc_4011D5
.text:004011BC push 10h ; uType
.text:004011BE push offset aFornixSFirst_0 ; lpCaption
.text:004011C3 push offset aTheNameShouldB ; lpText
.text:004011C8 push [ebp+hDlg] ; hWnd
.text:004011CB call MessageBoxA

Ecco, il nickname viene messo nel buffer rinominato per l'occorenza "NickName" e il serial nel buffer rinominato "Serial" (che frase ...), dopodichè tramite l'api lstrlenA prende la lunghezza del NickName inserito, io avevo inserito "x86x86x", ritorna in eax il valore 7. La lunghezza del nickname deve maggiore di 4 char come si può notare dal salto "Ja" che se andate a controllare in un manuale troverete scritto "Salta se maggiore", ok noi abbiano inserito un nickname di lunghezza 7 char e quindi proseguiamo all'inidirizzo 4011D5:

.text:004011D5 loc_4011D5: ; CODE XREF: sub_40117B+3Fj
.text:004011D5 push 0 ; nFileSystemNameSize
.text:004011D7 push 0 ; lpFileSystemNameBuffer
.text:004011D9 push 0 ; lpFileSystemFlags
.text:004011DB push 0 ; lpMaximumComponentLength
.text:004011DD push 0 ; lpVolumeSerialNumber
.text:004011DF push 14h ; nVolumeNameSize
.text:004011E1 push offset VolumeNameBuffer ; lpVolumeNameBuffer
.text:004011E6 push offset RootPathName ; lpRootPathName
.text:004011EB call GetVolumeInformationA
.text:004011F0 push offset VolumeNameBuffer ; lpString2
.text:004011F5 push offset String1 ; lpString1
.text:004011FA call lstrcpyA
.text:004011FF push offset NickName ; lpString2
.text:00401204 push offset String1 ; lpString1
.text:00401209 call lstrcatA
.text:0040120E call sub_401253
.text:00401213 call sub_401283
.text:00401218 call sub_4012B6
.text:0040121D test eax, eax
.text:0040121F jnz short loc_40123A
.text:00401221 mov eax, offset aMoreWorkToDo ; "More Work To Do"
.text:00401226 push eax ; lParam
.text:00401227 push 0 ; wParam
.text:00401229 push 0Ch ; Msg
.text:0040122B push 65h ; nIDDlgItem
.text:0040122D push [ebp+hDlg] ; hDlg
.text:00401230 call SendDlgItemMessageA
.text:00401235 popa
.text:00401236 leave
.text:00401237 retn 4

Adesso una volta arrivati qui, la prima cosa che troveremo e l'api GetVolumeInformationA, che in questo caso viene utilizzata per prendere il nome dell'etichetta data al volume "C:\", se volete essere certi a cosa punta visionate il contenuto del buffer denominato RootPatchName (Nel mio c, io ho l'etichetta "Win_xp"), mentre per vedere il nome dell'etichetta restituito, dopo aver eseguito l'api, potete visionare il contenuti del buffer VolumeNameBuffer (questo lo potete far con Olly, basta scrivere nella commandline "d 004062AC" che è l'inidirizzo del buffer, dopo questa precisazione andiamo avanti e vediamo che viene utilizza l'api lstrcpyA per copiare il nome dell'etichetta nel buffer chiamato String1, successivamente l'api lstrcatA per copiare il nostro nickname alla fine dell'etichetta appena copiata in String1, ad ex. dopo queste call io nel buffer string1 avrò "Win_Xpx86x86x", andiamo avanti ed entriamo nella prima call (non sto dicendo niente di fantastico, se avete dubbi su cosa fanno le api citate in precendeza prendete un manuale c o andate su Msdn online):

sub_401253 proc near ; CODE XREF: sub_40117B+93p
.text:00401253 mov esi, offset String1
.text:00401258 mov edi, offset word_4062C0
.text:0040125D mov edx, offset NickName
.text:00401262 mov ecx, 4
.text:00401267
.text:00401267 loc_401267: ; CODE XREF: sub_401253+2Aj
.text:00401267 test ecx, ecx
.text:00401269 jz short loc_40127F
.text:0040126B mov al, [esi]
.text:0040126D mov ah, [edx]
.text:0040126F xor al, ah
.text:00401271 and al, 5Fh
.text:00401273 or al, 40h
.text:00401275 xor al, 9
.text:00401277 mov [edi], al
.text:00401279 inc esi
.text:0040127A inc edi
.text:0040127B dec ecx
.text:0040127C inc edx
.text:0040127D jmp short loc_401267
.text:0040127F ; ---------------------------------------------------------------------------
.text:0040127F
.text:0040127F loc_40127F: ; CODE XREF: sub_401253+16j
.text:0040127F mov byte ptr [edi], 24h
.text:00401282 retn
.text:00401282 sub_401253 endp

Come possiamo notare esi punta alla stringa "Win_xpx86x86x", edi ad un buffer vuoto e infine edx al nickname che nel mio caso è "x86x86x", poi mette 4 in ecx per utilizzarlo come contatore, quindi possiamo subito intuire che verranno utilizzati solo i prima quattro char per i calcoli. Iniziamo il ciclo, viene preso un carattere alla volta sia della String1 che del nostro nickname, vengono xorati, con il risultato viene fatto un and con 5Fh, poi un or con 40h ed infine uno xor con il valore 9, il risultato viene messo all'interno del buffer vuoto puntato da edi, questi calcoli vengono fatti per i primi quattro caratteri, dove alla fine una volta usciti dal ciclo come si può notare all'indirizzo 0040127F il quinto char conterrà il valore 24h "$", il risultato di questi calcoli darà "FXQN$", andiamo avanti ed entriamo nella seconda call:

.text:00401283 sub_401283 proc near ; CODE XREF: sub_40117B+98p
.text:00401283 mov esi, offset NickName
.text:00401288 mov edi, offset word_4062C0
.text:0040128D mov edx, offset String1
.text:00401292 add edi, 5
.text:00401295 mov ecx, 4
.text:0040129A
.text:0040129A loc_40129A: ; CODE XREF: sub_401283+2Dj
.text:0040129A test ecx, ecx
.text:0040129C jz short loc_4012B2
.text:0040129E mov al, [esi]
.text:004012A0 mov ah, [edx]
.text:004012A2 xor al, ah
.text:004012A4 and al, 3Fh
.text:004012A6 or al, 30h
.text:004012A8 xor al, 9
.text:004012AA mov [edi], al
.text:004012AC inc esi
.text:004012AD inc edi
.text:004012AE dec ecx
.text:004012AF inc edx
.text:004012B0 jmp short loc_40129A
.text:004012B2 ; ---------------------------------------------------------------------------
.text:004012B2
.text:004012B2 loc_4012B2: ; CODE XREF: sub_401283+19j
.text:004012B2 mov byte ptr [edi], 0
.text:004012B5 retn
.text:004012B5 sub_401283 endp

Qui esi punta al nickname, edx alla nostra String1 "Win_xpx86x86x" e edi alla stringa appena calcolata "FXQN$", ad edi inoltre viene aggiunto 5, in modo da posizionarsi alla fine della stringa appena citata. Come al solito vengono elaborati solo 4 char, il ciclo dei calcoli e simile a quello visto in precedenza, quindi non lo sto a spiegare! il risultato cmq è "FXQN$681>", adesso entriamo nell'ultima call e vediamo cosa succede:

.text:004012B6 sub_4012B6 proc near ; CODE XREF: sub_40117B+9Dp
.text:004012B6 mov esi, offset Serial
.text:004012BB mov edi, offset word_4062C0
.text:004012C0 mov edx, offset unk_406292
.text:004012C5 push esi
.text:004012C6 push edx
.text:004012C7 jmp short loc_4012D1
.text:004012C9 ; ---------------------------------------------------------------------------
.text:004012C9
.text:004012C9 loc_4012C9: ; CODE XREF: sub_4012B6+1Ej
.text:004012C9 mov al, [esi]
.text:004012CB xor al, 9
.text:004012CD mov [edx], al
.text:004012CF inc esi
.text:004012D0 inc edx
.text:004012D1
.text:004012D1 loc_4012D1: ; CODE XREF: sub_4012B6+11j
.text:004012D1 cmp byte ptr [esi], 0
.text:004012D4 jnz short loc_4012C9
.text:004012D6 pop edx
.text:004012D7 pop esi
.text:004012D8
.text:004012D8 loc_4012D8: ; CODE XREF: sub_4012B6+38j
.text:004012D8 cmp byte ptr [edi], 0
.text:004012DB jnz short loc_4012E4
.text:004012DD cmp byte ptr [edx], 0
.text:004012E0 jnz short loc_4012E4
.text:004012E2 jmp short loc_4012F6
.text:004012E4 ; ---------------------------------------------------------------------------
.text:004012E4
.text:004012E4 loc_4012E4: ; CODE XREF: sub_4012B6+25j
.text:004012E4 ; sub_4012B6+2Aj
.text:004012E4 mov ah, [edi]
.text:004012E6 mov al, [edx]
.text:004012E8 cmp al, ah
.text:004012EA jnz short loc_4012F0
.text:004012EC inc edi
.text:004012ED inc edx
.text:004012EE jmp short loc_4012D8
.text:004012F0 ; ---------------------------------------------------------------------------
.text:004012F0
.text:004012F0 loc_4012F0: ; CODE XREF: sub_4012B6+34j
.text:004012F0 mov eax, 0
.text:004012F5 retn
.text:004012F6 ; ---------------------------------------------------------------------------
.text:004012F6
.text:004012F6 loc_4012F6: ; CODE XREF: sub_4012B6+2Cj
.text:004012F6 mov eax, 1
.text:004012FB retn
.text:004012FB sub_4012B6 endp

Esi è il puntatore al Serial inserito, edi il puntatore al serial appena generato "FXQN$681>" e edx punta al buffer che conterrà il nostro serial dopo che ogni char è stato xorato con il valore 9; Come si può notare più avanti tutta la protezione è la verifica dei char puntati da edx siano uguali ai char puntati da edi che è il serial appena generato! quindi a noi per trovare il serial corretto da inserire, bastera che "FXQN$681>" venga xorato con il valore 9 (unico calcolo effettuato prima del confronto) il risultato sarà il serial da inserire "OQXG-?187" !!! Come potete notare una volta confrontato il serial, se è corretto mette in eax il valore 1 (la protezione è tutta quà, quindi volendo potete modicare anche il mov eax, 0 in mov eax, 1 e per ogni serial inserito vi dirà "Good Cracker", chiaramente deve aver una lunghezza maggiore di 4 il nickname)!

N.b.:Vi faccio notare che in entrambi i calcoli delle prime due call i valori vengono xorati con 9, e che alla fine il serial confrontato con quello calcolato è stato anche lui xorato con 9, eapparte per il valore 24h che viene inserito senza essere xorato con 9, il serial corretto generato può essere pescato tranquillamente dal valore contenuto in al prima dello xor con 9! Chiaramente dovete ricordarvi di inserire il "-" tra il primo gruppo di 4 char e l'ultimo gruopp di 4 char! Provare per credere! Se volete quindi scrivere un KeyGen per questo crackme, vi conviene fargli fare i calcoli delle due call senza lo xor con 9 (ottendo già i due gruppi di 4 char corretti) e far xorare con 9 solo il carattere 24h per ottenere il "-" o lo aggiungete direttamente voi! (vedete quale più vi aggrada!!!).

Dato che nn avevo molto tempo di starmi a scrivere interamente un keyGen, ho trasformato il crackme in un Auto-KeyGen! Vediamo le modifiche da fare:

Indirizzo Prima Dopo
4012C9 mov byte ptr al, [esi]
mov byte ptr al, [edi][edi]
4012CF inc esi inc edi
4012D1 cmp byte ptr [esi], 0 cmp byte ptr [edi], 0
4012EA jnz short loc_4012F0 jmp short loc_4012F0
401221 mov eax, fornixcr.0040606A mov eax, fornixcr.00406292

Ecco qua, non facciamo altro che invece di xorare con 9 il nostro serial immesso, facciamo xorare il nostro serial calcolato il quale ci darà quello corretto da inserire nell'editbox!Infatti in edx, adesso troveremo il serial "OQXG-?187", forziamo il jnz di controllo che adesso non serve a nulla, una volta nella call SendDlgItemMessageA, gli modifichiamo il primo paramentro (il quale serve a puntare la stringa da visualizzare nell'editbox) e quindi in eax, invece di far puntare la stringa contenuta in 0040606A (More Work To Do) la modifichiamo e la facciamo puntare al buffer che contiene il serial corretto e precisamente 406292, cosi ci visualizzera questo nell'editbox!

Per creare le modiche io ho utilizzato OllyDbg, basta posizionarsi sulla istruzione da cambiare "doppio click" si aprirà una finestrella dove potete cambiare l'istruzione, e cosi via per tutte le altre; dato che le modifiche da fare sono tutte + o - vicine nel codice, per renderle definitive, basterà che selezioniamo tutto il codice un po prima della prima istruzione fino a un po dopo dell'ultima istruzione (è facile vedere dove sono le istruzioni modificate, sono in colore rosso), tasto destro del mouse "Copy to executable" -> "selection" (io solitamente faccio così, ma potete anche scegliere Copy to executable-> all modifications con la quale nn serve nemmeno selezionare le istruzioni), vi si aprirà un'altra finestra con parte selezionata, di nuovo tasto destro sulla parte selezionata, scegliete "save file" dategli un nome!

Se non avete molta dimestichezza con OllyDbg, potete utilizzare un qualsiasi ExeEditor per modificare il crackme! Se poi avete più tempo di me potete anche divertirvi a modificare anche gli altri testi del crackme, tipo MsgBox di About, testi visualizzati dentro le edibox, ecc ecc basta un po di fantasia !!!!

Allegato: AutoKG_byx86

                                                                                                                 By x86

Note finali

Come al solito saluto la mia girl :) che nn mi stuferò mai di dire che è troppo brava a sopportarmi ... Il Que, AndreaGeddon, d3im0s ... che come ogni anno ci vediamo al mare! albe, Spider (non dovevi rivelare che sono un pubblicitario di google.....ahahhah), True-love, e tutti gli altri componenti della U.I.C.

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo che ogni sviluppatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Reversiamo al solo scopo informativo e per migliorare la nostra conoscenza del linguaggio Assembly.