CommandLine 95: quattro modi per evitare la protezione
(Super newbies all'opera)


13/04/2000

by "AndreaGeddon"

 

 

UIC's Home Page

Published by Quequero


The crack is In there.

Un ottimo tute solo per i NewBies tosti...Per gli altri solo un ripasso, grazie Andrea :)

The crack is IN there
UIC's form
Home page: www.andreageddon.8m.com
E-mail: [email protected]
Canale IRC:    #crack-it
UIC's form

Difficolt�

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

 

Eccovi quattro modi per eliminare una stupida protezione.


CommandLine 95: quattro modi per evitare la protezione
Super Newbies all'opera
Written by AndreaGeddon

Introduzione

Siccome il cracking � veramente semplice, per non cadere nel banale scrivo quattro modi diversi per eliminare la protezione di questo programma. Incluso il sorgente del keymaker.

Tools usati

SotIce

WDasm

Exescope (opzionale)

un Hex Editor se volete patchare il prog

URL o FTP del programma

Qui

Notizie sul programma 

Semplice protezione nome/serial con un piccolo algo. Ma va? Pensavo non ci fossero algo in vista :) NdQue

Essay

Siccome sarebbe troppo deprimente scrivere un tute solo sull'algo, esamineremo i seguenti diversi modi di fregare il programma:

- Trovare il seriale giusto

- Fare un keymaker (con tanto di sorgente)

- Crakkarlo e fargli credere che ogni seriale sia quello giusto

- Crakkarlo sopprimendo i nag screen

cos� magari il tutto potrebbe risultare un pochino pi� interessante. Iniziamo col primo punto. Fatevi una copia dell'exe cos� potrete riusarlo.

Se registrate il prog, per ritornare non registrati e continuare gli esperimenti andate nel file cline95.ini in c:\windows e cancellate il serial dall'ultima riga.

 

PUNTO PRIMO: TROVARE IL SERIALE GIUSTO

Okey, lanciamo il programma e bam, ci appare un nag screen. Se guardiamo meglio ci appare lo stesso nag anche in chiusura del programma. Nel nag c'� un simpatico pulsantino... si chiama register! Premiamolo e ci appare la solita finestrella con due Edit Box corrispondenti al nome e al serial. Mettiamo nome e serial inventati (io metto AndreaGeddon e 123456789). Mettete il numero 123456789 per adesso, perch� non tutti i numeri vanno bene. Vedremo poi il perch�.

Per breakare usiamo GetDlgItemTextA. Premiamo OK e bam! il sice ci porta a questo codice:

 

* Reference To: USER32.GetDlgItemTextA, Ord:00EDh

|

:0040246C    Call dword ptr [0040B284]          Prende il nome

:00402472    push 00000000                       |

:00402474    push 00000000                       |parametri da passare alla

:00402476    push 00000405                       |prossima call

:0040247B    mov edi, 004093E0                   |

:00402480    push esi                            |

 

* Reference To: USER32.GetDlgItemInt, Ord:00ECh

|

:00402481    Call dword ptr [0040B280]          \prende il serial inserito

:00402487    mov dword ptr [004092CC], eax       |lo salva in una locazione di memoria

:0040248C    mov edx, eax                       /e lo mette in EDX

:0040248E    mov ecx, FFFFFFFF                  \

:00402493    sub eax, eax                        |Fa uno scan del nome

:00402495    repnz                               |ed ottiene la sua

:00402496    scasb                               |lunghezza, nel mio

:00402497    not ecx                             |caso 0C (12 char)

:00402499    dec ecx                            /

:0040249A    movsx eax, byte ptr [004093E0]    \

:004024A1    imul ecx, eax                      |routine che genera il serial

:004024A4    shl ecx, 0A                        |

:004024A7    add ecx, 0002F8CC                 /

:004024AD    mov dword ptr [004093D4], ecx     \

:004024B3    cmp ecx, edx                       |Controlli per vedere se

:004024B5    je 004024E6                        |il serial � giusto

:004024B7    cmp edx, 0361DECA                  |o � sbagliato

:004024BD    je 004024E6                        Se il salto avviene la registrazione ha successo

:004024BF    push 00000010                      Se il salto non avviene la registrazione fallisce.

 

* Possible StringData Ref from Data Obj ->"REGISTRATION CODE ERROR"

|

:004024C1    push 004082C4

 

* Possible StringData Ref from Data Obj ->"Sorry, that is an invalid registration "

->"code"

|

:004024C6    push 00408298

:004024CB    push esi

 

* Reference To: USER32.MessageBoxA, Ord:0188h

|

:004024CC    Call dword ptr [0040B2C4]

:004024D2    mov eax, 00000001

:004024D7    pop edi

:004024D8    mov dword ptr [00408040], 00000000

:004024E2    pop esi

:004024E3    ret 0010

 

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004024B5(C), :004024BD(C)

|

:004024E6    push 00000000   --> il salto di prima ci porta qui!

 

* Possible StringData Ref from Data Obj ->"REGISTRATION CODE ACCEPTED"

|

:004024E8    push 0040827C

 

* Possible StringData Ref from Data Obj ->"Thank you for registering Command "

->"Line95!"

|

:004024ED    push 00408250

:004024F2    push esi

 

Praticamente non ha bisogno di spiegazioni. Come se fosse scritto in un lignuaggio di alto livello. Appare evidente che i due jump ci portano alle stringhe "registration code accepted", mentre se non li eseguiamo incappiamo in "registration code error".

Dehihi! Ho staccato un attimo per vedere Celebrity DeathMatch. Stasera hanno fatto Uno scontro tra tre modelle, Shakespeare contro BustaRhymes, e 4 sfigati del mondo reale. Ci voleva un p� di sana violenza e di cervelli sparsi per il ring. Torniamo a noi. Dove eravamo?

Dal softice quando arriviamo al jump alla linea 004024B5 proviamo ad invertire il flag zero (andateci sopra, cliccate e premete ins, quindi enter, vedrete che il flag si � trasformato da minuscolo in maiuscolo o viceversa). Il programma continua e dice che il codice che hai messo � giusto. Allora � evidente che siamo nel punto giusto. La linea precedente al jump contiene un

CMP   ECX, EDX

In cui EDX contiene il numero inserito, ed ecx contiene il numero esatto. E qui arriva il primo problema: ma in EDX c'� un numero diverso, come mai? Se avete inserito il serial 123456789, in EDX ci trovate 75BCD15. Questo non � altro che il corrispondente esadecimale di 12345678. Se infatti andate sulla linea del compare e scrivete il comando

? EDX

avrete come risposta la seguente riga:

075BCD15     0123456789     "    "

Dove tra virgolette ci sono un p� di caratteri strani. Una volta arrivati al compare, quindi, ECX contiene l'equivalente esadecimale del serial esatto. Scrivaiamo allora:

? ECX

ed otterremo come risultato il corrispondente decimale del serial esatto, nel mio caso �

000F28CC     0000993484      "   "

cio� 993484. Cos� abbiamo trovato il serial giusto, per� non abbiamo fatto un bel niente di reversing, quindi nel prossimo punto vedremo come viene generato il serial, perch� abbiamo dovuto usare il comando "?" (evaluate expression) per vedere il serial giusto e perch� vi avevo consigliato di inserire 123456789 come serial.

 

PUNTO SECONDO: TROVARE COME VIENE GENERATO IL SERIALE E FARE UN KEYMAKER

Okay, adesso risponderemo agli interrogativi che ci sono rimasti dopo il primo punto. Innanzitutto, perch� vi avevo consigliato di inserire il serial 123456789? Semplice, perch� per prendere il serial viene usata la funzione GetDlgItemInt, che prende il serial e lo trasforma in un intero con o senza segno. Questa API restituisce in EAX il corrispondente esadecimale del valore preso. Se il valore preso � pi� grande di INT_MAX (o UINT_MAX). Se aveste messo un serial maggiore di 4294967295 (la costante INT_MAX che corrisponde a 2^32 -1) non avreste trovato in EAX e poi in EDX il corrispondente esadecimale, ma ci avreste trovato 0. Okay, questa era una puntualizzazione non molto utile, ma almeno abbiamo spiegato GetDlgItemInt.

Abbiamo dovuto usare il comando "?" perch� appunto la API GetDlgItemInt restituisce il corrispondente esadecimale del numero messo, e questo comando ci traduce il valore da esadecimale a decimale. Vediamo ora in dettaglio la generazione del serial. Quello che ci serve � il seguente codice:

 

:0040249A    movsx eax, byte ptr [004093E0]    mette in eax il valore hex del primo char del nome

:004024A1    imul ecx, eax                     moltiplica EAX per ECX, in cui EAX contiene il primo

                                               char del nome, ed in ECX c'� C, che sarebbe il numero

                                               di caratteri di cui � composto il nome. La somma

                                               verr� messa in ECX

:004024A4    shl ecx, 0A                       prende il risultato della precedente somma e

                                               ci fa uno shift a sinistra di 0A

:004024A7    add ecx, 0002F8CC                 aggiunge al valore ottenuto il valore 0002F8CC.

 

E' tutto qui. Si riduce a tre operazioni, una moltiplicazione, uno shift e un'addizione. Il valore che otterremo in ECX sar� il serial esatto. Fare un keymaker non � difficile, quindi. Notate che dopo il

    cmp   ecx, edx

c'� la linea

    cmp   edx, 0361DECA

e se d� esito positivo salta alla parte di registrazione avvenuta del programma. Quindi oltre al keymaker abbiamo trovato anche una chiave universale, che va bene con qualsiasi numero! Come prima, anche questa chiave � esadecimale, e quindi in decimale sarebbe  56745674. Qualsiasi nome verr� registrato se inseriamo questo valore.

Comunque noi siamo reverser, e quindi eccovi il codice del keymaker. Per compilarlo vi serve il TASM 5, usate le seguenti linee:

tasm32 nomefile.asm

tlink   nomefile.obj

se col tlink doveste avere dei problemi, usate

tlink /3 nomefile.obj

--------------------------------------------------------------------------------------------------------------------------

.386                 ;le solite direttive
.MODEL SMALL       
;del compilatore
.STACK 800h
.DATA             
;definiamo tutte le stringhe che useremo

Titolo             DB 13,10,'KeyGenerator per Command Line 95 v1.0 $',13,10
Titolo2            DB 13,10,'Scritto da AndreaGeddon $',13,10
Titolo3            DB 13,10,'      __     _    _   __    __   ____        __ $',13,10
Titolo4            DB 13,10,'     /  \   | \  | | |  \ | .\ | ___|       /  \ $',13,10
Titolo5            DB 13,10,'    / /\ \  |  \ | | | . \|  / | |__       / /\ \ $',13,10
Titolo6            DB 13,10,'   / /--\ \ | |\\| | |   /|  \ | __|__   / /--\ \ $',13,10
Titolo7            DB 13,10,' /_/     \_\|_| \ _| |__/ |_|_\|______| /_/    \_\ $',13,10
Titolo8            DB 13,10,'   ____   ____     __   __     ___   _    _ $',13,10
Titolo9            DB 13,10,' / ___\ | ___|   |  \ |  \  /   \ | \  | | $',13,10
Titolo10           DB 13,10,' | | _   | |__    | . \| . \| /\ | |  \ | | $',13,10
Titolo11           DB 13,10,' | |__| | | __|_ |   /|   /| \/ | | |\\| | $',13,10
Titolo12           DB 13,10,' \____/ |______| |__/ |__/  \___/ |_| \ _| $',13,10
Titolo13           DB 13,10,' $',13,10
Titolo14           DB 13,10,'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- $',13,10
Prompt        DB 13,10,'Inserisci il nome: $',13,10
Nome         DB 13,10,'',13,10
Serial            DD 13,10,'',13,10
SerialTitle        DB 13,10,'Il tuo serial: $',13,10
Buffer            DB 13,10,'',13,10

.CODE                      
   ;iniziamo il codice
start:
    mov ax, @data
    mov ds, ax   
    mov    dx, OFFSET Titolo    
;titoli vari
    mov    ah, 9                           
;potevo evitare
    int    21h                                
;tutti questi trafiletti
    mov    dx, OFFSET Titolo2   
;con una routine
    mov    ah, 9                            
;ma che ci posso fare
    int    21h                               
;se sono pigro...
    mov    dx, OFFSET Titolo3
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo4
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo5
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo6
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo7
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo8
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo9
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo10
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo11
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo12
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo13
    mov    ah, 9
    int    21h
    mov    dx, OFFSET Titolo14
    mov    ah, 9
    int    21h
    mov dx, OFFSET Prompt
    mov ah, 9
    int 21h
    xor ebx, ebx
PrendiNome:
    mov ah, 1       
  ;int21 con funzione 1, prendiamo un carattere
  int 21h            
; da tastiera

    cmp al, 0Dh     
   ;controlliamo che non sia INVIO
    je Calcoli        
;se � invio allora il nome � stato immesso
    mov    [Nome+ebx], al  
;e saltiamo ai calcoli
    inc ebx
    jmp PrendiNome
Calcoli:
    mov    al, byte ptr [Nome]
;qui calcoliamo il serial
    movsx    eax, al           
    imul    eax, ebx           
;sono questa riga
    shl eax, 0Ah               
;e questa
    add eax, 00002F8CCh       
;e questa
    mov    [Serial], eax       
;quelle che ci generano il serial
    xor    esi, esi          
;ora per� lo dobbiamo visualizzare
    mov    esi, 07h          
;in decimale
Converti:                   
;usiamo questa routine
    mov    eax, [Serial]
    cmp    eax, 000000000
    jz    Convertito
    xor    edx, edx
    mov    ecx, 0Ah
    div    ecx             
;dividiamo il valore hex per 0A (10)
    mov    [Serial], eax  
;prendiamo il resto
    add    dl, 030h        
    mov    byte ptr [Buffer+esi], dl 
;e lo mettiamo in questa pila
    dec    esi
    jmp    Converti
Convertito:
    mov    dx, OFFSET SerialTitle    
;quando arriveremo qui, nella pila
    mov    ah, 9                  
;che ho chiamato buffer troveremo il
    int    21h                     
;seriale che dobbiamo visualizzare
    mov    word ptr [Buffer+08h], '$ ' 
;in decimale
    mov    edx, OFFSET byte ptr [Buffer]
    mov    ah, 9
    int    21h
    mov ah,4ch 
;abbiamo finito quindi terminiamo il programma
    mov al,0   
;return=0
    int 21h    
;game over
END start

---------------------------------------------------------------------------------------------------------------------------

L'ho scritto di fretta, ma sembra funzionare. Segnalate evntuali (anzi, probabili) errori.

 

PUNTO TERZO: REGISTRARSI CON UN SERIALE QUALSIASI

Adesso inizia la parte di cracking. Facendo riferimento alla routine completa scritta nel punto primo arriviamo alla riga 004024B5. Qui c� un simpatico jump che se lo eseguiamo ci porta alla parte di programma che dice "registrazione accettata". Se quindi spariamo softice e lo modifichiamo al volo, il programma � registrato. Se riavviamo il programma, ci riappare il nag screen. Evidentemente c'� almeno un altro compare che controlla se il codice che avevamo inserito � giusto. Se fate girare almeno un paio dei vostri neuroni e guardate un p� in giro, trovate il file CLINE95.INI nella directory di winzozz. Le ultime due righe di questo .ini contengono il serial e il nome registrati. Quindi le informazioni per il nag vengono lette da qui all'avvio del programma. Ora potremmo breakare sulle api per gli ini, ma c'� un sistema molto pi� rapido e comodo per trovare gli eventuali altri check del seriale. Il primo � quello che abbiamo nel codice sopra. Notiamo che nel check viene usato il numero 0002F8CC. Se in wdasm cerchiamo questo numero, ci apparir� due volte. Una volta nel punto che gi� conosciamo, un altra volta in un punto che non abbiamo visto gi�. Se vedete bene, la routine nuova � identica a quella che gi� conosciamo, quindi basta che anche qui modifichiamo il jump che segue il compare di ecx con edx, ed il programma � registrato con un codice finto. Se riavviamo il programma, ora non ci sono pi� nags.

 

PUNTO QUARTO: CRACCKIAMOLO ELIMINANDO I NAG SCREEN

Cosa ci spinge a crakkare questo programma? I noiosi e scomodi nag screen che appaiono all'inizio e all'uscita del programma, quindi un altro modo di crakkarlo sarebbe quello di eliminare direttamente questi nag. Vediamo come procedere. Ho provato ad attaccare CreateWindow e ShowWindow, ma senza nessun risultato.

L'idea � quella di non far eseguire i nag e di saltare direttamente alla main window. Quindi sono andato in Exescope, ho caricato il CLine95 e ho spulciato tra Resources\Dialogs. Ci sono quattro dialog, se le vediamo la numero 111 � il nag che appare all'inizio/uscita programma. Okay. Andiamo in Wdasm e cerchiamo tra le dialog references. Anche qui troviamo quattro identificatori, ma sono diversi da quelli indicati in Exescope. Perch�? Perch� in exescope i valori erano decimali, in Wdasm sono Esadecimali. Il corrispondente esadecimale di 111 � 006Fh. Vediamo in che punto del codice ci sono riferimenti a questa dialog. Il primo lo troviamo alla linea 00401352. Basta andare indietro di qualche linea, e ci troviamo alla linea 00401339 un JNE. Guarda caso quando questo jump viene eseguito, saltiamo tutta la parte riguardante la dialog 006F. Quindi Questo JNE deve diventare JMP. Cerchiamo altri punti di riferimento nel codice per la dialog 006F, e ne troviamo un altro alla linea 00402155. Anche qui stessa cosa. Risaliamo di qualche linea fino a 00402146, dove c'� un altro JNE. Lo trasformiamo in JMP, et... voil�. Adesso il programma non mostra pi� il nag screen all'inizio/uscita programma, anche se non � registrato. Per trasformare un JNE in JMP basta che cercate con l'hex editor i byte corrispondenti al jump (segnatevi un p� di byte prima) e cambiate il 75xx in EBxx.

 

E con questo � tutto. Questo programma per� � mooolto semplice, non aspettatevi di avere la vita cos� facile con tutti i prog che trovate.

AndreaGeddon

Note finali

Doh. Finalmente ho finito di copiare il tutorial nel form di Quequero (che l'ha rubato a Fravia!)..A the sandman, � fravia che l'ha copiato a lui e io pure :) NdQue. Spero che questo testo sia abbastanza chiaro per i newbies. Scusate se � venuto un p� da schifo, ma ho fatto un copia/incolla rapido rapido che mi ha mandato a puttane un p� di roba. Bah, FPage di merda. Saluto tutta la ML.

Ciauuuuuuuuuuuuuuuuuuuuuuuuuuuz

 

Disclaimer

Vi ricordo che queste informazioni sono solo a scopo puramente didattico. Non mi ritengo responsabile dell'uso che ne verr� fatto.

 
UIC's page of reverse engineering, scegli dove andare:

Home   Anonimato   Assembly    CrackMe   ContactMe   Forum   Iscrizione      
       Lezioni    Links   Linux   NewBies   News   Playstation        
  Tools   Tutorial   Search   UIC Faq

UIC