NuMega SmartCheck 5.0 Reversing


26/01/2000

by "phobos"
(aka D4rKSP4rr0w)
 

 

UIC's Home Page

Published by Quequero


"...se adesso
vi fermate,
forse
vi salvate, 
questo io vi
dico da vero
amico..."
                       S. King, "IT"


Wellaaaaaa bravo buon tute....Cmq mi stupisco che i programmatori numega abbiamo creato una così semplice protezione....chissà, erano ubriachi? :)

 
UIC's form
E-mail: [email protected]
On IRC:#crack-it,  #uic
Nick: ph0b0s
UIN 37507754 
UIC's form

Difficoltà

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

 

Salve ragazzi, leggendo del materiale riguardo al craxxing delle applicazioni scritte in Visual Basic, in particolare ho 'ritrovato' in uno dei miei CD-Rom pieni di Cracking tutorial, uno scritto da ALoR per NEURO ZONE 2, datato Gennaio 1999. In questo tute, e' affrontato il problema dello stepping nelle DLL di runtime del VB, e l'impossibilita' di segurle, vista la mostruosita' del file msvbvm50.dll...
A tal proposito, spicca l'utilita' di un debugger, fornito come sempre dalla Numega, chiamato SmartCheck 5.0...


Come 'registrare' SmartCheck ver. 5.0

 

TimeLock 32 ver. 2.0

Written by phobos (aka D4rKSP4rr0W)

Introduzione

Cito testualmente dal tute di ALoR:

"Piazzare un breakpoint su Hmemcpy in un VB5prg e' da suicidio !!!
Istantaneamente ci ritroveremo a navigare in quell'inferno che il nostro amico Bill Gate$ ha soprannominato simpaticamente: msvbvm50.dll. Perdendo cosi' di
vista il nostro obbiettivo: il confronto tra stringhe.
...
Trovare la giusta stringa non sembrava tanto difficile... fino a quando e' arrivato SmartCheck. Ora e' addirittura una cazzata!!! Come dicono fravia+ e +HCU "Like watching a movie!" :)"
...
Eseguendo un programma con SmartCheck potremo notare sulla parte sinistra tutti (e dico TUTTI) gli eventi del programma. Dal form.load ai text.keypress ai label.caption alle funzioni di formattazione (lenght(), trim(), hex(), ecc) alle funzioni di calcolo, insomma quando dico tutto... intendo anche il numero di scarpe del programmatore... :)))
Sulla parte destra della schermata si possono invece controllare i valori dei parametri passati alle funzioni e quelli ritornati.
Per di piu' sempre nello stesso pannello ci dice anche l'indirizzo in cui e' chiamata la funzione in esame."
...
Cosa possiamo chiedere di piu' ?? Sappiamo dove e cosa sta facendo il nostro prg da "analizzare"... Io direi che in questa maniera il cracking dei VB5 prg e' davvero fin troppo facile e senza quell'ingrediente che spinge un cracker a portare a termine il suo lavoro: LA SFIDA !!"

Visto che bel programma?
Io incuriosito da 'cotanta' enfasi, mi sono scaricato una bella copia della versione 5.0...

Tools usati

Numega SoftICE

Una ventina di minuti di tempo...
Se fumate...le vostre sigarette preferite :-)
Se non fumate...quanto vi decidete a cominciare che le morti per cancro sono in drastico calo?? ;-)

URL o FTP del programma

ftp://ftp.kgb.ru/NTUtil/NuMega/
File: smchk50.exe

Notizie sul programma

Il programma in esame e' un debugger funzionante in "Real-Mode", dedicato ai programmi scritti in Visual Basic.
E' dotato di due meccanismi di protezione: uno basato su un codice da inserire nella fase di installazione da parte di 'Install Shield' e un altro: trialita' di 14 giorni con possibilita' di 'unlocking' mediante Unlock Code, calcolato a partire da un Serial Code Generato fornito nella box di registrazione del programma. Il meccanismo di registrazione di questo programma, come molti altri e' basato su una particolare dll, chiamata Time Lock 32 (situata nella directory C:\WINDOWS e chiamata tl32v20.dll, ne avete sentito parlare?) la quale si occupa di tutta la procedura di registrazione: controllo del seriale, generato in base al Registration Number, salvataggio delle informazioni nel registro di Winzozz e number check all'avvio del programma. Il Reg. Number viene generato ogni volta che il programma viene installato su HD e varia di volta in volta.

Essay

Suddividiamo il nostro 'attacco' in due fasi: una prima mirata a sbloccare l'installazione del programma, e la seconda alla sua registrazione...
Tutti pronti?

Si parte!!

Prima fase:

Avviamo l'eseguibile ad autoestrazione che abbiamo appena scaricato...
Appare una dialog che ci avvisa che stiamo installando lo smartcheck...clicchiamo su OK...
"Kakkio!!! serve un codice!!! Quello strxç*!!!!! di pho!!!"
;-) calmi... calmi... ci arriviamo...
Vediamo prima che succede all'install shield se inseriamo un numero 'fake', ci appare una bella message box che ci avvisa che abbiamo inserito il numero sbagliato, clicchiamo su OK e il programma si auto-termina...
Riavviamo, BPXiamo su Sice con la funzione HMemCpy (tanto odiata in VB, ma indispensabile negli altri eseguibili ;-))
entriamo nell'ice, usciamo dalla funzione in questione (F11), e torniamo al punto del programma che ha inserito la stringa, da noi immessa, in memoria (F12 6 Volte), come si fa a capire queste cose? intuito...(modo elegante per dire culo!! ;-), scherzi apparte, con l'esperienza si inizia a 'sentire il codice' per usare una frase fatta (see +ORC Cracking Lessons).
Siamo immediatamente dopo la chiamata alla funzione GetWindowText,
Esaminiamo il codice, single stepping (F10), superiamo una istruzione di LEA, quattro di PUSH ed incontriamo la nostra cara LStrCpm... (funzione che compara due stringhe) subito sotto la quale c'e':

XXXX:XXXX    OR AX,AX
XXXX:XXXX    JNZ 0DDE       <--- nota bene
XXXX:XXXX    PUSH SI
XXXX:XXXX    PUSH 0632
XXXX:XXXX    JMP 0DE1
XXXX:0DDE     PUSH SI
XXXX:XXXX    PUSH 00
XXXX:XXXX    CALL USER!ENDDIALOG
.
.
.
XXXX:0DE1  XXXXX

Nel punto del salto condizionale, ci arriviamo con la flag zero settata su zero (cacofonico, ma come dirlo in altri termini?), quindi, se il salto viene effettuato, in :0DDE vengono pushati i valori che saranno passati alla funzione enddialog, quella che generera' la nostra 'beggar off' e terminera' il programma.
Quindi, dobbiamo invertire la flag Zero, per evitare che cio' accada, e che venga invece eseguito il salto assoluto a 0DE1, che fa continuare il programma.
Cambiamo la flag: r fl z
facciamo eseguire il salto assoluto e usciamo dall'ice...
"Miracolo!!! Il prog. continua nell'installazione!!! Grande phob!!!"
Grazie!!...solo dieci minuti fa ero uno str@#!!...misteri della psiche umana... ;-)

Abbiamo terminato l'installazione del programma, proviamo ad avviarlo...
Ci appare la finestra principale del programma.
Come passo successivo, dobbiamo configurarlo:
Andiamo su 'Program' -> 'Settings..' quindi ci appare una dialog con quattro spread sheet (penso si scriva cosi' :-/) in 'error detection' selezioniamo tutte le caselline con il segno di spunta; quindi clicchiamo su 'Advanced' e selezioniamo le tre caselle: 'Reset GetLastError befor each API call', 'Report errors even if no source code is available' e 'Report each error only once', lasciamo le altre opzioni deselezionate.
Passiamo allo sheet 'reporting' e deselezioniamo solo la casella relativa a 'Report MouseMove events from OCX controls' clicchiamo su OK... il prog e' configurato. (grazie ad ALoR per le sue dritte a riguardo :-))

Seconda fase:

Bene, proviamo a caricare un programma (questo tool e' un debugger in real-time e funziona in modo simile a ApySpy...) una volta caricato l'eseguibile da avviare, cliccando sull'iconcina con sopra il simbolo del 'play', il prog viene avviato e ogni sua funzione monitorizzata dal debugger...
Pero' appena avviamo il programma, ci appare una dialog, che ci avvisa che abbiamo a disposizione solo 14 giorni per valutare il programma, e che volendo possiamo acquistarlo.
Selezionando l'opzione 'Purchase' ci appare una finestra di registrazione, in cui vanno inseriti user name, societa' di appartenenza e unlock code.
Le stringhe immesse nel programma sono prelevate dalla finestra mediante la funzione User32!GetWindowText
Quindi, entriamo nel Sice e settiamo un breakpoint sulla funzione in esame: bpx getwindowtexta
usciamo dall'ice, compiliamo i tre campi a disposizione con nome, societa' e un seriale 'fake' (sempre mnemonico).
Diamo OK e Sice dovrebbe 'poppare' fuori...
Premiamo F11 per uscire dalla funzione in esame, poi F12 per tornare all'istruzione immediatamente successiva alla CALL a GetWindowText.
Approdiamo in questo frammento di codice:

:10003E79                       push eax
:10003E7A                      push ebx

* Reference To: USER32.GetWindowTextA, Ord:013Fh
                                        |
:10003E7B                     Call dword ptr [100163DC]

* Possible Reference to Dialog: DialogID_0070, CONTROL_ID:2334, ""
                                        |
:10003E81                     push 00002334         <-- Siamo qui
:10003E86                     push esi
:10003E87                     call edi
:10003E89                     push eax
:10003E8A                    mov ebx, eax

* Reference To: USER32.GetWindowTextLengthA, Ord:0140h
                                       |
:10003E8C                   Call dword ptr [100163D4]         <-- USERNAME
:10003E92                    cmp eax, 00000002              <-- Controllo
:10003E95                    jg 10003EB3              <-- Se USERNAME maggiore di 2 allora salta
:10003E97                    push 00002000
:10003E9C                   push 10013B19
:10003EA1                   push 10014029
:10003EA6                   push 00000000

* Reference To: USER32.MessageBoxA, Ord:0195h
                                      |
:10003EA8                  Call dword ptr [100163A8]     <-- MessageBox
:10003EAE                  jmp 10003FEC

La seconda CALL alla funzione immette in memoria lo user name che abbiamo inserito, se lasciamo il campo vuoto, (o, nel caso specifico, immettiamo meno di tre caratteri) il programma non esegue il salto in :10003E95, vengono passate alla funzione MessageBoxA dei parametri (i quattro PUSH che la precedono) e il prog. ci avvisa mediante una messagebox che dobbiamo immettere uno username, dopo di che, il programma ritorna alla procedura di immissione dello username.
Continuiamo a steppare (evitando di entrare nelle CALL per non complicarci la vita: tasto F10) attraversiamo questa sequenza di codice:

:10003EB3                  push 00000027
:10003EB5                  lea eax, dword ptr [ebp-7C]
:10003EB8                  push eax
:10003EB9                  push ebx

* Reference To: USER32.GetWindowTextA, Ord:013Fh
                                      |
:10003EBA                 Call dword ptr [100163DC]

* Possible Reference to Dialog: DialogID_0070, CONTROL_ID:2335, ""
                                      |
:10003EC0                 push 00002335
:10003EC5                 push esi
:10003EC6                 call edi
:10003EC8                 push 00000031
:10003ECA                push 100144A0
:10003ECF                 push eax

Fino ad arrivare al 'punto caldo' del nostro programma: la genrerazione del corretto 'Unlock Code' ed il confronto con quello da noi immesso.
Analiziamo il codice:

* Reference To: USER32.GetWindowTextA, Ord:013Fh
                                      |
:10003ED0                 Call dword ptr [100163DC]     <-- Codice immesso
:10003ED6                 lea eax, dword ptr [ebp-28]
:10003ED9                 push eax
:10003EDA                call 10002864                  <-- Procedura di calcolo dell'esatto seriale
:10003EDF                 add esp, 00000004
:10003EE2                 lea eax, dword ptr [ebp-14]     <-- Stoccaggio in EAX del contenuto di un address di memoria
:10003EE5                 lea ecx, dword ptr [ebp-28]     <-- Come sopra, solo che l'address va in ECX
:10003EE8                  push eax                               <-- salva EAX
:10003EE9                  push ecx                               <-- salva ECX
:10003EEA                 call 10005680

La CALL in :10003EDA, calcola il codice di sblocco, ora, se andiamo a vedere il contenuto dell'indirizzo puntato da EAX (dopo aver fatto eseguire le due istruzioni in :10003EE2 e :10003EE5) che ci troviamo? Il seriale da noi immesso...
E alla riga immediatamente precente (sempre nel Dumping della memoria)?
Ma il seriale corretto e' ovvio!!!
Non ci credete?
Diffidenti!! Segnatevi il numero, uscite dall'ice, immettetelo al posto del 'fake' che avevamo inserito e vedete che succede... ;-)
Quindi, tutto si e' risolto in un semplice 'Serial Fishing'...

Potrete ora utilizzare lo SmartCheck, per i vostri 'loschi' scopi, a danno dei programmini scritti in VB...
A Presto! ;-)

                                                                                                                 phobos (aka D4rKSP4rr0W)
Note finali 

THANX TO:

* ALoR Per i suoi prestigiosi tute
* Quequero per il suo continuo impegno
* Tutti i membri di RingZ3r0 e della UIC
* La NuMega Technologies per i suoi fantastici Debuggers ;-)
* Tutti coloro che hanno la pazienza di ascoltare un pazzo scatenato come me!   :-)

C U ASAP!!
 

Disclaimer

Vorrei ricordare al lettore che cracking, revers engeenering, hacking, ecc. costituiscono dei reati, nel momento in cui il materiale riguardante uno dei suddetti viene 'ridistribuito'. Se crackate un programma, fatelo solo a fini didattici 

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

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

UIC