Soluzione all 8° corso newbies
Enabling!


05/12/2000

by "AndreaGeddon"

 

 

UIC's Home Page

Published by Quequero

Dont blame the lame :-)

Qualche mio eventuale commento sul tutorial :))) :-P

uff...

arr...

Beh, mi duole ammetterlo ma hai fatto un bel lavoro brutto animale :)))

Just flame the blame >:-9

UIC's form
Home page: www.andreageddon.8m.com   /  www.andreageddon.com
E-mail: andreageddon@hotmail.com
IRC:  irc.azzurra.it / irc.tin.it      #crack-it
UIC's form

Difficoltà

(x)Homer(aka Andrea) ( )Intermedio ( )Avanzato ( )Master

 

Mi avete fatto due palle così con queste maledette funzioni disabilitate, ora beccatevele.


Soluzione all 8° corso newbies

Enabling!

Written by  AndreaGeddon

 

Introduzione

Vediamo come si abilitano pulsanti e voci di menù.

Tools usati

SoftIce

WDasm32

-  Un hexedit (ehi, stavolta si può patchare!)

-  Mouse e tastiera

-  Un editor di risorse? Nope, non servirà a nulla :-P

 

URL o FTP del programma

quequero.cjb.net  oppure   www.andreageddon.8m.com  

Notizie sul programma 

3 pulsanti, 1 voce di menu e 1 item di menù da abilitare.

Essay

Eccoci giunti ad un nuovo capitolo di corsi per la Uic. Questa volta si tratta di funzioni disabilitate. Potete scordarvi da subito di modificare con un editor di risorse i controlli disabilitati, tanto nella creazione sono attivi, vengono disabilitati a runtime. Anche il Customiser non sarà di aiuto più di tanto, visto che per ogni controllo abilitato ci sarà poi una verifica a runtime che ri-disabiliterà il controllo se non darà esito positivo. E non serve andare a cercare "Registered" tra le string reference del wdasm. Saremo soli soletti col nostro amato softice! Non è meraviglioso??? Via!

 

LIVELLO 1: IL PRIMO PULSANTE

Ebbene, dopo tante ciance vi accorgerete che il primo pulsante basta abilitarlo col Customiser per registrarvi. Ora prima che diciate "ma vaffanculo andrè" vi dico che per gli altri non sarà così facile. Tuttavia a noi piace l'approccio da reverser e non da lami che usano il customiser. Quindi vediamo di dare uno sguardo un pò più approfondito alla faccenda. Abbiamo il pulsante disabilitato, sappiamo che viene disabilitato a runtime, quindi la prima cosa che mi viene in mente è di intercettare la funzione che mi disabilita il pulsante per annichilarla. Come fare? Di solito per abilitare/disabilitare un controllo standard si usa EnableWindow che ha la seguente sintassi:

 

BOOL EnableWindow(
HWND hWnd,                       // handle della finestra/controllo
BOOL bEnable                     // flag per abilitare/disabilitare
);

 

se però mettete un break su EnableWindow il sice popperà in continuazione. Per ovviare a questo piccolo inconveniente basta prendere il loader del softice, caricare come modulo il crackme e premere il pulsante 'run'. Il softice popperà sull'entry point. A questo punto abilitiamo il bpx EnableWindow ed iniziamo a steppare (solo con F10 mi raccomando!). Dopo aver passato GetModuleHandle vedremo che eseguendo la riga 00401E71 il softice ci sparerà nel modulo USER32 dicendoci di essersi imbattuto nel break. Premiamo UNA volta F12 e torneremo nel processo di MFC42, quindi eseguiamo il ret su cui ci troviamo (con F10 e non F12!) e torneremo al processo del crackme, sotto la call che ha chiamato EnableWindow tramite MFC. Ecco dove arriviamo:

 

:004014CC   push 00000000      push da tenere d'occhio

:004014CE   lea ecx, dword ptr [esi+000000E0] carica l'handle del bottone 1

:004014D4   mov byte ptr [00404208], 52   ma cosa sono tutti questi mov???? :-)

:004014DB   mov byte ptr [00404209], bl

:004014E1   mov byte ptr [0040420A], 67

:004014E8   mov byte ptr [0040420B], 69

:004014EF   mov byte ptr [0040420C], 73

:004014F6   mov byte ptr [0040420D], dl

:004014FC   mov byte ptr [0040420E], bl

:00401502   mov byte ptr [0040420F], al

:00401507   mov byte ptr [00404210], bl

:0040150D   mov byte ptr [00404212], 00

:00401514   mov byte ptr [004041F8], 55

:0040151B   mov byte ptr [004041F9], 6E

:00401522   mov byte ptr [004041FA], al

:00401527   mov byte ptr [004041FB], bl

:0040152D   mov byte ptr [004041FC], 67

:00401534   mov byte ptr [004041FD], 69

:0040153B   mov byte ptr [004041FE], 73

:00401542   mov byte ptr [004041FF], dl

:00401548   mov byte ptr [00404200], bl

:0040154E   mov byte ptr [00404201], al

:00401553   mov byte ptr [00404202], bl

:00401559   mov byte ptr [00404204], 00

* Reference To: MFC42.Ordinal:0A52, Ord:0A52h

:00401560  Call 00401C7C      chiamata a EnableWindow (via MFC però)

:00401565   push 004041F8       pusha il puntatore a Unregistered

:0040156A   push 000003EE       pusha l'handle del controllo di testo

:0040156F   mov ecx, esi

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:00401571   Call 00401C76       call a SetDlgItemText per scrivere Unregistered

:00401576   push 00000000       di nuovo un push 00!! La puzza di flag si fa più forte!

:00401578   lea ecx, dword ptr [esi+000000A0]  di nuovo carica l'handle

* Reference To: MFC42.Ordinal:0A52, Ord:0A52h

:0040157E   Call 00401C7C       chiama EnableWindow

:00401583   push 004041F8       come prima

:00401588   push 000003EF       come prima

:0040158D   mov ecx, esi

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:0040158F  Call 00401C76      altra call SetDlgItemText

:00401594   push 00000000       ormai siamo sicuri che questo è il flag di abilitazione

:00401596   lea ecx, dword ptr [esi+60]     carica l'handle

* Reference To: MFC42.Ordinal:0A52, Ord:0A52h

:00401599   Call 00401C7C       Terza call a EnableWindow, corrisponde al terzo pulsante.

 

abbiamo tre call a EnableWindow. Dalla sintassi vediamo che prima viene passato l'handle del controllo, e poi una variabile booleana (1 = TRUE, 0 = FALSE). Come scriviamo in ogni tutorial, i parametri vengono passati in ordine inverso a causa dello stack, quindi l'ultimo parametro passato è l'handle del controllo con le righe:

004014CE     lea   ecx, dword ptr [esi+xxx]

00401578                       "

00401596                       "

e il penultimo parametro passato è il parametro booleano (si, i tre PUSH 00!). Con quei push viene passato di volta in volta il valore FALSE, ed EnableWindow quindi disabilita i pulsanti. Ora da qui sappiamo come abilitare tutti e tre i pulsanti! Possiamo tranquillamente pathcarci il file cambiando i 6A00 in 6A01 (Push 01), così ogni volta ci ritroveremo i pulsanti abilitati. Bene, ora il primo livello è registrato. Ah, dimenticavo... Siamo passati anche sopra i tre SetDlgItemText che ci scrivono Unregistered, quindi potevamo cambiare il puntatore alla stringa per far scrivere Registered, ma questa non sarebbe stata una vera soluzione! Insomma, se lo scopo del crackme è di abilitare i controlli......

 

LIVELLO 2: IL SECONDO PULSANTE

Bene, dopo aver patchato il programma per attivare tutti e tre i pulsanti, abbiamo cliccato sul primo e ci siamo registrati! Ora clikkiamo sul secondo e sul terzo... Strunz! Si disabilitano!

Evidentemente c'è qualche operazione (nella funzione associata alla pressione del pulsante) che ci disabilita il pulsantino caro! Possiamo riciclare il metodo precedente e breakare su EnableWindow, però visto che siamo reversers (o almeno proviamo ad esserlo...) scegliamo un altro attacco! Stavolta l'idea è di esaminare tutto ciò che avviene a partire dalla pressione del pulsante in poi. Per farlo dovremo usare un break sul messaggio che viene inviato dopo la pressione del pulsante. Tale messaggio è WM_COMMAND. Però non possiamo settare un bpx WM_COMMAND, ma dobbiamo usare l'apposito BMSG. Per usare bmsg ci servirà l'handle del controllo che vogliamo esaminare. Come si ottiene?? Col crackme in esecuzione andiamo in softice, battiamo "hwnd ottavo" ed otterremo la lista degli handle per tutti i controlli e cavoli vari riguardanti il processo dell'ottavo:

 

Window Handle       HQueue      Class Name

0220(1)                      2C3F              Dialog

  07A4(2)                   2C3F               Button

  07B0(2)                   2C3F               Button

 

e così via. Beh, visto che non c'è un bottone solo nell'applicazione, dovremmo cercare a culo qual'è l'handle del pulsante che ci interessa (tutti gli handle della classe button sono buoni candidati). Per esempio facendo un paio di prove il secondo handle-button mi risulta relativo al pulsante del livello 1, mentre l'handle del pulsante del livello 2 è il 3°. Come facciamo a saperlo? Basta che usiamo in softice il comando

bmsg  handle   WM_COMMAND

e di volta in volta proviamo su handle il valore dell'handle che ci siamo ricavati con hwnd. Gli handle cambiano ad ogni esecuzione, quindi se riavviate il programma non riusate gli handle settati prima! Settiamo di volta in volta un break su un x handle e premiamo il pulsante del livello 2. Se il sice poppa, abbiamo azzeccato l'handle, altirmenti proviamo il prossimo. Quindi trovato l'handle del pulsante del secondo livello breakeremo nel kernel.Premete F12 finchè non sarete tornati al processo della libreria MFC42, quindi steppate qualche riga fino al RET e tornerete nel processo dell'ottavo a questo punto (00401846):

 

:0040180A   mov ecx, dword ptr [00404058]

:00401810   mov byte ptr [esp+10], al

:00401814   mov eax, dword ptr [00404020]

:00401819   mov dword ptr [esp+08], ecx

:0040181D   cmp eax, 0001E240  questa deve essere la condizione che cerchiamo

:00401822   mov dword ptr [esp+0C], edx

:00401826  je 00401839         questo ci fa saltare alla call da dove siamo venuti

:00401828   mov al, 20

:0040182A   mov [esp+06], 52

:0040182F   mov byte ptr [esp+04], al

:00401833   mov byte ptr [esp+05], al

:00401837   jmp 00401846     questo invece ci fa evitare la call da dove siamo venuti

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

:00401839   push 00000000

:0040183B   lea ecx, dword ptr [esi+000000A0]

* Reference To: MFC42.Ordinal:0A52, Ord:0A52h

:00401841   Call 00401D2C

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

:00401846   lea ecx, dword ptr [esp+04]    ARRIVIAMO QUI!

:0040184A   push ecx            il pulsante qui è già disabilitato

:0040184B   push 000003EF

:00401850   mov ecx, esi

 

è chiaro che basta noppare il jump alla riga 00401826 per evitare di incappare nella call a MFC che si occupa di disabilitare il pulsante. Il compare alla linea 0040181D è il responsabile della funzione disabilitata: confronta eax con 1E240 e se sono uguali disabilita il bottone. Ovviamente per lo scopo del crackme tale valore non è modificabile esternamente (tipo cambiando la data o una chiave del registry), ma in un programma è importante capire cos'è che ha disabilitato la funzione. Bene, hurry to the next!

 

LIVELLO 3: IL TERZO PULSANTE

Anche qui dopo aver abilitato il terzo pulsante con il metodo descritto per il primo, notiamo che in seguito alla pressione otteniamo solo la sua disabilitazione. Come prima ci cerchiamo l'handle tramite HWND e mettiamo un bel bmsg per beccare la routine associata al pulsante. Nella lista degli handle del processo "Ottavo" dobbiamo prendere il quarto handle. Ora premiamo sul pulsante, e come prima arriveremo nel kernel. Premiamo F12 fino ad arrivare al processo di MFC, quindi steppiamo sul ret e torniamo al processo dell'ottavo alla riga 004018E2:

 

:0040188D   cmp eax, 000003DB    questa è la condizione per la registrazione

:00401892   mov dword ptr [esp+0C], edx

:00401896  je 004018D8     questo ci fa saltare alla non-registrazione

:00401898   mov al, byte ptr [00404214]

:0040189D   test al, al

:0040189F   jne 004018AD    questo ci mette al sicuro

:004018A1   cmp dword ptr [00404028], 0000029A  anche questa è una condizione

:004018AB  je 004018D8     e questo ci ributta ad unregistered

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

:004018AD   mov ecx, dword ptr [00404208]

:004018B3   mov edx, dword ptr [0040420C]

:004018B9   mov ax, word ptr [00404210]

:004018BF   mov dword ptr [esp+04], ecx

:004018C3   mov cl, byte ptr [00404212]

:004018C9   mov dword ptr [esp+08], edx

:004018CD   mov word ptr [esp+0C], ax

:004018D2   mov byte ptr [esp+0E], cl

:004018D6   jmp 004018E2         saltiamo la disabilitazione e registriamoci!

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

:004018D8   push 00000000        pusha il flag bool per EnableWindow

:004018DA   lea ecx, dword ptr [esi+60]  carica l'handle

* Reference To: MFC42.Ordinal:0A52, Ord:0A52h

:004018DD   Call 00401C7C        call EnableWindow

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

:004018E2   lea edx, dword ptr [esp+04]  ARRIVIAMO QUI

:004018E6   mov ecx, esi                 la festa è già finita...

:004018E8   push edx                     ...torniamo su a vedere cosa dobbiamo fare

:004018E9   push 000003F0

 

la situazione è quasi uguale a prima, solo che la condizione non è una sola, ma dai tre compare:

0040188D   cmp eax, 000003DB

0040189D   test al, al

004018A1    cmp dword ptr [00404028], 0000029A

 

che sono legati da un'operazione di and e una di or. Potete patchare a piacimento, la via più pigra è quella di noppare tutti e tre i jump seguenti ai relativi compare e buonanotte. Anche qui ci siamo registrati. Ora per fortuna si cambia scena: passiamo ai menù!

 

LIVELLO 4: ITEM DI MENU

Spesso capita che un prog possa avere un menù disabilitato. Se il programma è stato scritto con il menù già disabilitato, allora basterà un editor di risorse per attivarlo. Se invece il programma disattiva il menù a runtime (ad esempio in seguito al controllo della data), allora dobbiamo cercare di intercettare la disabilitazione per fregarla. E' il caso del crackme in questione. Stavolta non possiamo usare EnableWindow, ma dobbiamo cercare qualche funzione che ha a che fare con i menu. Basta dare una occhiata alla fida guida API e troviamo le funzioni tipo EnableMenuItem, ModifyMenu, SetMenuItemInfo, e qualcun'altra. Possono tutte essere usate per disabilitare i menu. Per scegliere quella giusta basta conoscere la pigrizia e lamanza dell'autore, e salta subito agli occhi che la funzione usata sarà EnableMenuItem (la più semplice da usare :-). Basta anche guardare nelle import del programma e la trovavamo bella bella in USER32. Ora che sappiamo dove colpire, colpiamo! Settate un bpx EnableMenuItem e lanciate il programma. Breakerete immediatamente. Premete F12 e finirete nel processo SHELL32, che non è quello che ci interessa, quindi premete F5 per continuare l'esecuzione. Ri-Break! Anche stavolta premiamo F12 e di nuovo incapperemo in SHELL32. Che palle. Continuate con F5 e poi F12 finchè dopo il quarto/quinto break circa premendo F12 vi ritrovate nel processo dell'ottavo. Arriverete nel seguente codice:

 

:004015DD   mov ebx, dword ptr [00405498] mette in ebx l'address di EnableMenuItem

:004015E3  mov edi, eax

:004015E5  push 00000001     flag "GRAYED" per il menu item

* Possible Ref to Menu: MenuID_0083, Item: "Abilitami!"

:004015E7  push 00008003     ID della voce di menu da disabilitare

:004015EC  push edi          pusha l'handle del menu

:004015ED  call ebx           Chiama EnableMenuItem (per il livello 5)

:004015EF  push 004041F8          ARRIVIAMO QUI!

:004015F4  push 000003F2

:004015F9  mov ecx, esi

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:004015FB  Call 00401C76

:00401600  push 00000001     di nuovo il flag GRAYED

* Possible Ref to Menu: MenuID_0083, Item: "Livello 4"

:00401602  push 00008004     ID dell'item da disabilitare

:00401607  push edi          handle del menu

:00401608  call ebx          di nuovo richiama EnableMenuItem (per il livello 4)

 

facile no? Bastava seguire le string reference, ma noi non vogliamo essere lami giusto? La call ebx è quella che ci disabilita il menu. Vediamo la sintassi della funzione:

 

BOOL EnableMenuItem(

HMENU hMenu,             // handle to menu
UINT uIDEnableItem,     // menu item to enable, disable, or gray
UINT uEnable                  // menu item flags
);

 

quindi entrambe le volte abbiamo un bel PUSH 01, che pusha il flag che determina il grigiore dei menu. Per inciso, il campo uEnable della funzione può contenere i seguenti parametri costanti:

MF_BYCOMMAND    =  0

MF_BYPOSITION        =  400

MF_DISABLED            =  2

MF_ENABLED             =  0

MF_GRAYED               =  1

 

possiamo quindi sostituire i due PUSH   01 con  PUSH  00  per fargli arrivare il flag ENABLED. Quindi con un colpo solo abbiamo abilitato il livello 4 e 5. Ora però dobbiamo registrarci. Per il livello 4 la cosa sarà semplice. Anche i menù utilizzano il messaggio WM_COMMAND per notificare la selezione di un menu o di un item di menu, quindi di nuovo ricorriamo al bmsg. Avendo il crackme in esecuzione, andiamo in softice e ricaviamoci la lista degli handle con "hwnd ottavo", questa volta ci interessa il primo handle, quello che ha come class name "Dialog". Preso l'handle adesso settiamo il

bmsg  handle_appena_preso WM_COMMAND

questo è un break più generico, breakerà su ogni wm_command dell'applicazione, compresi quelli dei menu. Ora che il break è attivo andiamo nel crackme e premiamo il menu del livello 4. Apparirà il softice e vi ritroverete nel kernel. Per tornare al crackme dobbiamo fare parecchia strada, dobbiamo premere circa 13 volte il tasto F12, cioè fino a che non arriviamo nel processo delle MFC42. Una volta arrivati lì ci troveremo sopra un ret, non premete F12, ma F10, cioè steppate il ret e tornerete al processo dell'ottavo sulla riga 004019FD. Eccovi il listato della routine:

 

:004019C0    sub esp, 00000010   aggiusta lo stack

:004019C3    mov eax, dword ptr [00404054]   carica "Unre"

:004019C8    push esi            salva esi

:004019C9    mov edx, dword ptr [0040405C]   carica "ered"

:004019CF    mov esi, ecx

:004019D1    mov ecx, dword ptr [00404058]   carica "gist"

:004019D7    mov dword ptr [esp+04], eax     metti i pezzi di stringa in esp+4

:004019DB    mov al, byte ptr [00404060]     carica in al il terminatore

:004019E0    mov dword ptr [esp+08], ecx     metti i pezzi di stringa in esp+4

:004019E4    lea ecx, dword ptr [esp+04]

:004019E8    mov dword ptr [esp+0C], edx     metti i pezzi di stringa in esp+4

:004019EC    push ecx

:004019ED    push 000003F0                    ID del testo dove scrivere unregistered

:004019F2    mov ecx, esi

:004019F4    mov byte ptr [esp+18], al       aggiungi il terminatore alla stringa

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:004019F8    Call 00401C76                    call a setdlgitemtexta (setta Unregistered)

:004019FD    cmp dword ptr [004041F0], 0000000A  torniamo QUI!

:00401A04    jge 00401A17                     questo ci fa evitare una call

:00401A06    push 00404208                    pusha il puntatore alla stringa Registered

:00401A0B    push 000003F1                    ID del testo dove scrivere registered

:00401A10    mov ecx, esi

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:00401A12    Call 00401C76                   call a setdlgitemtexta (setta registered)

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

:00401A17    pop esi

:00401A18    add esp, 00000010

:00401A1B    ret

 

la routine è semplicissima, c'è un solo jump che ci rompe le scatole. Se lo noppiamo incappiamo in un'altra call a setDlgItemTextA e verremo registrati.

 

LIVELLO 5: VOCE DI MENU

Ci rimane l'ultimo pezzo di questo borioso crackme. Analogamente al precedente livello, settiamo il bmsg sull'handle del dialog, premiamo la voce di menu "Abilitami", e il softice popperà, e come prima ci ritroviamo nel kernel. Notiamo però che stavolta non è facile tornare al processo dell'ottavo. Se premiamo sempre F12 scorreremo i processi Kernel e User fino a tornare nel processo delle MFC. Ora se premiamo F12 usciamo da softice, se invece steppiamo fino al ret più vicino rimaniamo sempre impantanati nel processo delle MFC. Più precisamente dopo un pò di tracing arriviamo ad un ciclo, quello formato da PeekMessage, GetMessage, SendMessage, TranslateMessage etc. Questo è il ciclo vitale della finestra, cioè è il ciclo che rimane in continuo in esecuzione per processare e gestire i messaggi dell'applicazione. La fregatura è proprio questa, che i messaggi vengono gestiti da quelle katz di mfc e non dall'applicazione stessa, il che ci crea qualche problema nel tracing. Ora a prima vista sembra che non si possa tornare al processo dell'ottavo, però secondo logica ci deve tornare per forza. Insomma, le mfc gestiscono i messaggi, quindi ricevono il messaggio wm_command, capiscono quale controllo ha mandato il messaggio (nel nostro caso la voce di menu) e redirigono l'esecuzione alla funzione associata alla selezione della voce di menu. Tale funzione deve necessariamente trovarsi nel processo dell'ottavo, tutto sta a capire come arrivarci. Tale funzione viene processata da CallProc32W (la trovate tracciando un pò di kernel dal punto in cui breakate in poi), e poi anche in CallProc32w cercare di tracciare il codice che ci riporta alla funzione dell'ottavo è un incubo. Per tagliare le palle al toro ci inventiamo qualche trucco che ci permette di risparimare tempo (e fatica mentale :-). Visto che il processo dell'ottavo viene eseguito, e a quanto pare proprio sotto il nostro naso, allora settiamo un bel

bpr  00401000  00403000  RW

e vaffanculo. Che vor dì? BPR è un BreakPoint on Memory Range. gli indirizzi 00401000 e 00403000 delimitano la sezione di codice del crackme. Per vedere le sezioni usate il comando

map32 ottavo

e avrete una cosa di questo genere:

Owner     Obj Name    Address

ottavo           .text          00401000

ottavo           .rdata        00403000

etc.

la prima sezione (.text) è quella di codice, e si estende dall'indirizzo 00401000 a 00403000. Quindi, ricapitolando, quello che abbiamo fatto è stato quello di settare un breakpoint su qualsiasi lettura/scrittura di un qualsiasi byte contenuto nella sezione di codice, così appena il controllo tornerà al codice del crackme noi lo taneremo subito. Quindi settiamo prima un bel bmsg sull'handle del dialog, una volta breakato settiamo il bpr appena scritto, quindi cominciamo a premere F5. Ogni volta breakeremo su una riga dell'ottavo, ma principalmente ci ritroveremo o su una lista di JMP, o su un MOV/RET. Questa è tutta robaccia che non ci interessa, quindi premiamo F5 (parecchie volte) finchè arriviamo alla linea 00401980:

 

:00401980    sub esp, 00000014   arriviamo qui.

:00401983    mov eax, ecx        mette in eax il puntatore alla iat (nun ce frega)

:00401985    mov edx, dword ptr [004041F0]  mette in edx un numerello

:0040198B    mov ecx, 00000005    carica 5 nel contatore

:00401990    push esi     salva esi...

:00401991    push edi     ...e edi

:00401992    mov esi, 0040410C    metti in esi la stringa sorgente

:00401997    lea edi, dword ptr [esp+08]   metti in edi il buffer di ricezione

:0040199B    repz         muovi 5 dword...

:0040199C    movsd        ... da esi a edi

:0040199D    movsx ecx, byte ptr [esp+0B]  mette in ecx il 4° char della stringa

:004019A2    cmp ecx, edx    lo confronta con il numerello di prima

:004019A4    jle 004019B7    salta se il char è minore

:004019A6    push 00404208   pusha il puntatore a Registered

:004019AB    push 000003F2   pusha l'id del testo dove scrivere

:004019B0    mov ecx, eax

* Reference To: MFC42.Ordinal:1741, Ord:1741h

:004019B2    Call 00401C76   call a setDlgItemTextA (scrive Registered)

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

:004019B7    pop edi         se abbiamo eseguito il salto siamo qui

:004019B8    pop esi         e siamo ancora non registrati

:004019B9    add esp, 00000014

:004019BC    ret

 

anche questa è una routine banale, c'è un solo jump che decide se registrarci o meno. Per decidere se siamo registrati lui carica la stringa "èInArrivoLoStrainer", prende il 4° char (il carattere A) e lo confronta con un numero in edx. Se questo numero è maggiore, allora riamo unregistrati. Tale valore cambia da esecuzione ad esecuzione, quindi potrebbe in qualche caso essere minore di 41h (A) e registrarci automaticamente? Se andiamo in wdasm e cerchiamo la stringa 004041F0 (la locazione da cui prende il numerello), troviamo le seguenti righe:

 

* Reference To: KERNEL32.GetTickCount, Ord:0145h

:0040161B    Call dword ptr [0040528C]

:00401621    lea ecx, dword ptr [esp+10]

:00401625    mov dword ptr [004041F0], eax

 

quindi il valore del numerello è determinato da GetTickCount. Questa funzione restituisce il valore in millisecondi da quando è partito il windogs, quindi lo possiamo considerare un valore pseudo casuale, ed inoltre siamo sicuri che il crackme non si registrerà mai da solo al 5° livello perchè è difficile che riusciamo ad eseguirlo entro i primi 41h millisecondi dall'avvio del win :-). E con questo abbiamo terminato il crackme. That's all folks!

Byex

AndreaGeddon

 

Note Finali

Ciauz a tutta la ML e a tutti quelli che rompono su crack-it, in particolare Nerds :-). Un salutino a GioCrackino che finalmente è venuto a seguire algoritmi! Poi il Quequerino che ancora non mi dà l'uicCd :-(. Bai bai.

Disclaimer

Queste informazioni sono solo a scopo puramente didattico. Avete a disposizione un periodo di 15 giorni per provare il crackme, dopodichè dovete comprarlo. L'autore si riserva il diritto di mandarvi la GdF a casa se un je mandate li sordi. AndreaGeddon®© is a registered TradeMark. Byeeeeee