Oliver's first crackme
Serial fishing e trasformazione in autokeygenerator

Data

by "Pincopall "

 

10/01/2001

UIC's Home Page

Published by Quequero


Chi va piano spesso ...

Anche questo tutorial vi propone una via per trasformare un programma in un autokeygenerator, l'altro lo trovate alla uic, e lo scrissi io su come trasformare il 3DMark99, questo tutorial è completo e spiega chiaramente tutta la procedura necessaria, bravo pinco :)

...arriva dopo ;-))

 
http://pincopall.cjb.net
E-mail: [email protected]
Pincopall on #crack-it #hackmaniaci #Kao5
 

Difficoltà

(X)NewBies (X)Intermedio ( )Avanzato ( )Master

 

Prima troveremo il giusto seriale per il nostro nome e poi faremo anke in modo ke sia il crackme stesso a dircelo una volta inseritone uno sbagliato :-)


Oliver's first crackme
Serial fishing e traformazione in AutoKeyGenerator
Written by Pincopall

Introduzione

 
Allora, questo è un CrackMe piuttosto facile, non per niente la crocetta è su NewBies, ma ho scelto di cimentarmici per poter finalmente vedere se ero in grado di trasformarlo pure in un auto Keygenerator,e per questo la crocetta su "Intermedio", seguitemi nella mia avventura :-)
 

Tools usati


SoftIce
Wdasm 32
Hex WorkShop---- un editor esadecimale qualunque

URL o FTP del programma


http://crackmes.cjb.net , nella sezione Windows Crackme

Notizie sul programma


E' un crackme ke vuole un nome ed un serial ke và in base al nome.

Essay

Allora, allacciate le cinture e pronti a partire, lanciamo il file ocrackme.exe e vediamo ke si tratta di una semplice finestrella :) con due box, uno per il nome ed uno per il serial, ed il bottone "Check".
Ok, infiliamo il nostro nome "Pincopall", la nostra password "11224433" ad cazzum, e premiamo "Check" e TADAA, non succede niente, nemmeno una Beggar  Off con scritto qualcosa, niente, mmmm vabbè, proviamo ad aprire SoftIce (Ctrl+D) e mettiamo un bpx, già ma...su ke? Bhè io ho deciso di metterlo il più generale possibile, visto ke i vari bpx GetDlgItemTexta , GetWindowTexta, MessageBox et similia non davano frutti, ho dunque messo un bel bpx hmemcpy.
Usciamo dal SIce (F5) e clikkiamo su "Check" e SoftIce poppa, premiamo 7 volte F12 e ci troveremo nel codice di ocrackme.exe, cominciamo dunque a steppare con F 10 eseguendo ogni ret, e dopo un po' ci ritroveremo qui:

:00430CB2     lea edx, dword ptr [ebp-08]       ---- arriviamo qui
:00430CB5     mov eax, dword ptr [esi+000001E0]
:00430CBB     call 0041AC18

Ok, steppiamo kon F10, arriviamo sopra la call, ankora F10 e questa ci risbatte nel Kernel, vabbè, ancora 7 volte F12 e ritorniamo in ocrackme.exe stavolta per restarci, una altra serie di ret, e alla fine dei ret arriviamo qui :

:00430CC0     mov eax, dword ptr [ebp-04] --- arriviamo qui dove mette il nostro nome in                                               eax
:00430CC3     call 00403938
:00430CC8     cmp eax, 00000006 --- si accerta ke il seriale sia almeno di 6 caratteri
:00430CCB     jge 00430CDC      --- se lo è si và avanti
:00430CCD     mov eax, 00430EF4
:00430CD2     call 0042EB3C
:00430CD7     jmp 00430EC4      --- sennò....Bambino Cattivo

Referenced by Jump at Address:
|:00430CCB(C)
|
:00430CDC    cmp dword ptr [ebp-08], 00000000 --- controlla ke il codice abbia almeno                                                   una cifra
:00430CE0    jne 00430D16 --- e se la ha , tutto bene, sennò ...
:00430CE2    mov eax, 00430F24
:00430CE7    call 0042EB3C
:00430CEC    jmp 00430EC4 --- ...Bambino Cattivo

Dunque il nostro nome deve essere di almeno 6 caratteri ed il nostro seriale deve quantomeno esistere :)
Allora, vediamo un po', il nostro nome, 6 caratteri li ha, il nostro seriale esiste, il salto a 00430CE0 salta e ci porta al primo dei loop ke modificheranno il nostro nome ovvero qui :

:00430CF1     mov eax, dword ptr [ebp-04] --- inizio loop dove rimette in eax il nostro                                                nome
:00430CF4     call 00403938 --- Controlla ke eax non sia vuota e se non lo è ci mette il
                                numero di caratteri del nome
:00430CF9     sub eax, ebx --- Sottrae a eax il numero di caratteri già modificati
:00430CFB     mov edx, dword ptr [ebp-04] --- Muove in edx il nostro nome
:00430CFE     mov dl, byte ptr [edx+eax-01] --- Muove in dl il carattere da modificare,
                                                partendo dall'ultimo
:00430D02     lea eax, dword ptr [ebp-1C]
:00430D05     call 00403860 --- Questa e quella qui sotto sono due call ke modificano                                 ankora il nostro nome, ma ankora non abbiamo il                                 seriale completo
:00430D0A     mov edx, dword ptr [ebp-1C]
:00430D0D     lea eax, dword ptr [ebp-0C]
:00430D10     call 00403940
:00430D15     inc ebx --- incrementa il numero di caratteri modificati

* Referenced by  Jump at Address:
|:00430CE0(C)
|
:00430D16     mov eax, dword ptr [ebp-04] --- arriviamo qui dove mette in eax il nostro                                               nome
:00430D19     call 00403938 --- Qui controlla ke eax non sia zero e se non lo è ci mette                                 il numero di caratteri del nome
:00430D1E     cmp ebx, eax --- il loop continua finkè eax=ebx, ovvero finkè non ha                                ritoccato tutti i caratteri del nome
:00430D20     jl 00430CF1  --- se non li ha ankora finiti di modificare tutti, il loop                                riparte
:00430D22     mov ebx, 00000001
:00430D27     jmp 00430D5F --- Questo salto ci porta al secondo loop

Dunque vediamo qui il primo loop ke verrà scorso 9 volte ( Pincopall è di 9 caratteri ) e poi passerà alla istruzione successiva, per non sorbirci tutte le volte il loop, in SIce clikkiamo sulla riga all'offset 00430D22 in modo da metterci un bp, usciamo da SIce e questo subito ricompare dopo aver finito il loop; eseguiamo dunque il salto all'offset 00430D27 e arriviamo al secondo loop di modifica :

:00430D29    push [ebp-14]   --- viene pushato ogni volta il nome modificato
:00430D2C    lea eax, dword ptr [ebp-1C]
:00430D2F    mov edx, dword ptr [ebp-04]   --- viene mosso in edx il nostro nome
:00430D32    mov dl, byte ptr [edx+ebx-01] --- viene messo in dl il carattere da modificare
:00430D36    call 00403860
:00430D3B    push [ebp-1C]
:00430D3E    lea edx, dword ptr [ebp-20]
:00430D41    mov eax, dword ptr [ebp-0C]      --- viene messo in eax il nome al contrario
:00430D44    movzx eax, byte ptr [eax+ebx-01] --- viene messo in eax il primo carattere                                                   del nome al contrario
:00430D49    call 00406778
:00430D4E    push [ebp-20]
:00430D51    lea eax, dword ptr [ebp-14]
:00430D54    mov edx, 00000003
:00430D59    call 004039F8
:00430D5E    inc ebx --- incrementa il numero dei caratteri esaminati

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00430D27(U)
|
:00430D5F     mov eax, dword ptr [ebp-04] --- il salto ci porta qui dove viene messo in eax                                           il nostro nome
:00430D62     call 00403938             --- Questa call l'abbiamo già vista in precedenza
:00430D67     cmp ebx, eax              --- Guarda se ha modificato tutti i caratteri
:00430D69     jl 00430D29               --- se no ricomincia il loop
:00430D6B     mov ebx, 00000001         --- se si muovi in ebx, 1
:00430D70     lea eax, dword ptr [ebp-0C]

Come vedete il secondo loop è molto simile al primo,  ed alla fine, in ebp-14 troveremo il nostro nome modificateo, ad esempio da "Pincopall" si arriva a "P108i108n97c112o111p99a110l105" e come vedete manca un carattere, infatti se ho un nome di X caratteri, il loop ne modificherà X-1, continuiamo , una volta finito il loop a steppare, finkè non ci ritroviamo nel terzo :
 

|
:00430DC7   mov eax, dword ptr [ebp-14] --- qui ci porta il salto all'offset 430DC7 e                                             mette in eax il nome ottenuto dai primi 2                                             loop
:00430DCA   call 00403938 --- solita call
:00430DCF   dec eax       --- decrementa eax
:00430DD0   cmp ebx, eax  --- e lo confronta con ebx ke viene incrementato all'offset                               430DC6
:00430DD2   jl 00430D7A   --- se ebx è minore allora si riinizia il loop

Nel mio caso eax è uguale a 1E, infatti è trenta caratteri e quando ebx è 1D il salto non salta, a quel punto il codice finirà in un salto ke ci porterà al 4° loop, ovvero qui :

:00430DFE     inc ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00430DE1(U)
|
:00430DFF     mov eax, dword ptr [ebp-0C]
:00430E02     call 00403938
:00430E07     cmp ebx, eax
:00430E09     jl 00430DE3
:00430E0B     mov ebx, 00000003
:00430E10     lea eax, dword ptr [ebp-0C]
:00430E13     call 004036BC
:00430E18     cmp ebx, 00000030
:00430E1B     jge 00430E3F ---questo salto NON salta

Di questo loop vi riporto solo la fine, come farò degli altri in quanto lo scopo di questo tutorial non voleva essere lo spiegarvi la routine di creazione del seriale ke potrete facilmente studiarvi da soli, sennò ke gusto c'è ? :) ma voleva essere il far diventare il programma un autokeygenerator. Quindi , finito il loop qui sopra, un jmp ci porta al loop ke ha inizio all'offset 00430E1D e da quì si arriva alla fine del :

:00430E2C    mov edx, dword ptr [ebp-1C]
:00430E2F    lea eax, dword ptr [ebp-0C]
:00430E32    call 00403940
:00430E37    add ebx, 00000003
:00430E3A    cmp ebx, 00000030
:00430E3D    jl 00430E1D

E da qui si arriva finalmente all'ultimo loop ke inizia all'offset 00430E46 e termina qui :

:00430EA0     inc ebx

* Referenced by a  Jump at Address:
|:00430E44(U)
|
:00430EA1     mov eax, dword ptr [ebp-0C]
:00430EA4     call 00403938
:00430EA9     cmp ebx, eax
:00430EAB     jle 00430E46              --- finito il loop
:00430EAD     mov eax, dword ptr [ebp-0C] --- viene messo in eax il serial giusto
:00430EB0     mov edx, dword ptr [ebp-08] --- ed in edx quello da noi immesso
:00430EB3     call 00403A48 --- in questa call vengono confrontati i serial
:00430EB8     jne 00430EC4 --- se non sono uguali non appare la MessageBox di complimenti
:00430EBA     mov eax, 00430F40 --- viene messa in eax la stringa di congratulazioni
Vediamo dentro la call ke confronta i seriali :

:00403A48     push ebx
:00403A49     push esi
:00403A4A     push edi
:00403A4B     mov esi, eax
:00403A4D     mov edi, edx
:00403A4F     cmp eax, edx  --- qui c'è il confronto fra seriali
:00403A51     je 00403AE6   --- e se sono uguali si va alle congratulazoni
:00403A57     test esi, esi --- sennò guarda se il codice generato non esiste
:00403A59     je 00403AC3   --- e se lo è : errore
:00403A5B     test edi, edi --- e se non lo è guarda se nullo è il serial da noi immesso
:00403A5D     je 00403ACA   --- e se lo è : errore
:00403A5F     mov eax, dword ptr [esi-04] --- sennò fà andare avanti il prog ke però non                                               fà apparire niente
:00403A62     mov edx, dword ptr [edi-04]
:00403A65     sub eax, edx
 
 

Bene, ovviamente basta fare quando si è terminato il loop un "d eax" per trovare il serial, ke per la cronaca, per Pincopall è "431114434654410".

Bene, abbiamo finito il serial fishing, e credo abbiate notato ke è stato abbastanza facile, e ora arriviamo al vero scopo del nostro cercare il seriale, non è infatti, almeno per me , essere registrati, ma trasformare il crackMe in un generatore di kiavi, bene, mettiamoci all'opera.
Noi vogliamo ke, se il seriale inserito fosse sbagliato, il programma ci mostri una MessageBox con il codice da mettere in base al nostro nome, la nostra MessageBox sarà inoltre il più semplice possibile, con solo il pulsante di Ok, vi riporto sotto la sintassi dell'API MessageBox :

int MessageBox(

    HWND hWnd, // handle of owner window
    LPCTSTR lpText, // address of text in message box
    LPCTSTR lpCaption, // address of title of message box
    UINT uType  // style of message box
   );

Dunque, vediamo ke ci dobbiamo mettere dentro e, una volta pronta vediamo kome inserirla nel codice del programma:
intanto noi vogliamo una Messagebox kon il pulsante ok, e come ci dice la guida alle API il flag da mettere è 0, il primo push sarà quindi un push 00, perkè i parametri vanno pushati nel senso opposto in cui vengono passati, quaesto per la proprietà LIFO (Last In First Out ) ke ha lo stack; poi possiamo subito impostare l'handle of owner window ke sarà ank'esso zero, ed ancora, sin da subito sappiamo quale sarà l'indirizzo cui far andare la call, se infatti vediamo fra le Imported Functions del programma troviamo una MessageBox, clikkiamoci sopra, e vediamo ke c'è una call 004057F4, bene, questa sarà anke la call ke dovremo usare noi.
Abbiamo dunque per ora un:

push 00
push   address of title of message box
push   address of text in message box
push 00
Call 004057F4

Ci sono però ankora da pushare  il titolo della MessageBox nonkè il suo contenuto, e mentre il titolo sarà il nostro nome, il contenuto sarà il seriale esatto.
Bene, il nostro seriale giusto è contenuto in ebp-0C , mentre il nostro nome iniziale è in 00BA1720. Vediamo intanto ke tale MessageBox dovrà apparire al salot di quel jne all'offset 00430EB8 ke andrà quindi reindirizzato.E vediamo inoltre ke dopo tale salto eax viene rimodificato poikè vi viene inserita la stringa di congratulazioni, dunque possiamo usare eax per i nostri scopi facendo diventare il nostro codice:

push 00
mov eax, 00BA1720
push eax
mov eax, [ebp-0C]
push eax
push 00
Call 004057F4

Ok, la nostra MessageBox è pronta, ora c'è solo da decidere dove infilarla nel programma. Bene, apriamo WDasm ed andiamo a vedere le sezioni :

     Object01: CODE     RVA: 00001000 Offset: 00000400 Size: 00030200 Flags: 60000020
   Object02: DATA     RVA: 00032000 Offset: 00030600 Size: 00000C00 Flags: C0000040
   Object03: BSS      RVA: 00033000 Offset: 00031200 Size: 00000000 Flags: C0000000
   Object04: .idata   RVA: 00034000 Offset: 00031200 Size: 00001E00 Flags: C0000040
   Object05: .tls     RVA: 00036000 Offset: 00033000 Size: 00000000 Flags: C0000000
   Object06: .rdata   RVA: 00037000 Offset: 00033000 Size: 00000200 Flags: 50000040
   Object07: .reloc   RVA: 00038000 Offset: 00033200 Size: 00003600 Flags: 50000040
   Object08: .rsrc    RVA: 0003C000 Offset: 00036800 Size: 00004600 Flags: 50000040

Come vedete la sezione CODE ha una dimensione di 30200 bytes a partire dall'offset 400, mentre la sezione DATA, ke la segue comincia all'offset 30600, andiamo dunque a vedere kosa c'è prima di quel 30600 con il nostro editor esadecimale, e troviamo un sacco di byte 00 da modificare a nostro piacimento in cui possiamo quindi mettere gli opcode della nostra MessageBox, stando però attenti a non toccare il primo di questi byte perkè potrebbe sempre essere un terminatore di stringa.
Attenzione però, perkè ai byte corrispondenti alle istruzioni della nostra messagebox, ci vanno messi anke quelli corrispondeti ad un jmp incondizionato ke c riporti alla normale esecuzione del programma come se il codice fosse stato errato , ovvero un jmp 00430EC4 ke nel nostro codice andrà messo subito dopo la call 004057F4.
Ma vediamo, prima di mettere i relativi opcode, a ke indirizzo poi mi risulteranno nel disassemblato, ebbene, se provate ad andare alla fine del disassemblato troverete una serie di

:004310D6 00000000000000000000    BYTE 10 DUP(0)

E se guardate in basso a destra troverete a ke offset andarlo a trovare nell'editor esadecimale, per esempio in questo sopra è 00304D6h, bene dunque, possiamo per esempio mettere proprio qui la nostra messagebox.
Ordunque vediamo ke opcode mettere, allora per i push 00 si mette un 6A00, per i mov eax, 00BA1720   e [ebp-0C] si mette rispettivamente B82017BA00 e B845F4, per i push eax un 50 , già ma per il jmp?  e per la call? bhè, per il jmp si mette E9 e , ribaltato, la differenza fra l'indirizzo di destinazione e l'indirizzo della istruzione successiva a quella di partenza, e stesso dicasi per la call, solo ke al posto dell'E9 c andrà un E8, ma vediamo ora il risultato finale :

:004310E0 6A00                    push 00000000
:004310E2 B82017BA00              mov eax, 00BA1720
:004310E7 50                      push eax
:004310E8 8B45F4                  mov eax, dword ptr [ebp-0C]
:004310EB 50                      push eax
:004310EC 6A00                    push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
                                  |
:004310EE E80147FDFF              Call 004057F4
:004310F3 E9CCFDFFFF              jmp 00430EC4

Non resta ora ke kambiare quel jnz all'offset 00430EB8, ke era il salta ke c portava all'errore kon un bel jmp 004310E0, bene, per vedere l'opcode da dare a quest'ultimo basta andare in SoftIce, entrare come prima in ocrackme.exe e mettere un bpx 00430EB8, ora usciamo da e lui subito si rifà vivo posizionato sulla riga ke c serve, digitiamo " a eip" e scriviamo accanto a quell'offset : jmp 004310E0, ma , sfiga, è un salto lungo , ke non vuole + 2 bytes, bensì 5, e ke per questo mi và a cancellare la fondamentale stringa all'offset 00430EBA. Ma allora come fare? Bene, ecco cosa si deve fare, si deve prendere quel mov eax,00430F40 e metterlo alla fine del nostro codice, dopo il salto condizionato all'offset 4310F3, e dopo questo mov dobbiamo inserire un jmp ke ci riporterà a 00430EBF, inoltre, prima del nostro codice dobbiamo inserire un je ke ci porterà direttamente a quel mov, e quindi a quel secondo salto incondizionato, nel caso ke il codice da noi immesso vada bene.
MA vediamo ke opcode mettere per questi due nuovi salti, mentre ovviamente per il mov metteremo quello ke già ha, ovvero
B8400F4300; dunque, per il jmp usiamo la formula sopra citata e troviamo ke l'opcode ad esso relativo è E9BDFDFFFF, mentre troviamo ke per il je 004310F8 , ke andrà posizionato subito sopra il primo deo nostri push 00, ovvero all' offset 004310DE, l'opcode sarà 7418 ; questo sarà alla fine il nostro codice con i relativi opcode:

:004310DE 7418                    je 004310F8
:004310E0 6A00                    push 00000000
:004310E2 B82017BA00              mov eax, 00BA1720
:004310E7 50                      push eax
:004310E8 8B45F4                  mov eax, dword ptr [ebp-0C]
:004310EB 50                      push eax
:004310EC 6A00                    push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
                                  |
:004310EE E80147FDFF              Call 004057F4
:004310F3 E9CCFDFFFF              jmp 00430EC4

* Referenced by a Jump at Address:
|:004310DE(C)
|
:004310F8 B8400F4300              mov eax, 00430F40
:004310FD E9BDFDFFFF              jmp 00430EBF

C'è inoltre ora da considerare ke il salto all'offset 00430EB8 non c dovrà più portare a 4310E0 ma bensì a 004310DE, andiamo dunque a vedere kome apparirà il codice all'indirizzo 430EB8:

:00430EB8 E921020000              jmp 004310DE
:00430EBD 90                      nop
:00430EBE 90                      nop

Andiamo dunque ad inserire quei byte al posto di quelli del jne 00430EC4 e del mov eax, 00430F40 e salviamo.
Dunque abbiamo finito, proviamo, facciamo partire il prog, mettiamo "Pincopall" , "Dummy_serial" e lui TADAA fà apparire la message Box con titolo "Pincopall" e argomento "431114434654410", alèèè funzia, è diventato un keygenerator !

That's the End
ByeZ


Pincopall

Note finali

Un saluto ed un ringraziamento in primis a +Malattia perkè è un grande, poi a Tutti i membri della UIC, ed in particolare a Il_Bieco ke se ne partirà a giorni per gli USA con con biglietto per New York e ke, una volta là, aperta la valigia mi ci troverà dentro :) eheheh  CIAO BIECONE FATTE SENTIIII'.

And last but not least, come ogni mio tute, un salutoz a Ra1n (ke è Nio col nick nuovo :-), B3bos, GiPOCO, C1CC10 e tutti quelli di #hackit99

Disclaimer

Vorrei ricordare che questo software non può essere nè comprato nè rubato, per cui ke volete da me?! 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 immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.