NuMega SmartCheck 5.0 Reversing |
|
|
26/01/2000 |
|
|
|
Published by Quequero |
|
|
Wellaaaaaa bravo buon tute....Cmq mi stupisco che i programmatori numega abbiamo creato una così semplice protezione....chissà, erano ubriachi? :) |
|
UIC's form |
|
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...
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 |
URL o FTP del programma |
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 |
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! ;-)
|
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 |
Home
Anonimato Assembly
CrackMe ContactMe Forum
Iscrizione Lezioni Links NewBies News Playstation
Tools Tutorial Search
UIC Faq