"Soluzione del 7° CORSO TOTALLY NEWBIES"

Keyfile


25/10/2000

by "Spin0ne"

UIC's Home Page

Published by Quequero



Un uomo, un ottusangolo......No, volevo dire: un uomo, un tutorial, e bravo spin0 che come sempre ci presenta una soluzione ottima (ottimo anche il form stavolta :) ordinatissimo e dettagliatissimo, un tutorial che IMHO rispecchia la personalità del nostro simpatico amico, bravo di nuovo spin0, hai fatto un'ottimo lavoro.

UIC's form
E-mail: spin0ne@libero.it
IRC chan : #crack-it su irc.azzurra.it
UIC's form

Difficoltà

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

Eccoci quà.....Andrea ormai è diventato il nostro Tutor e ci prepara questi esercizi "Newbies" peraltro molto simpatici ed istruttivi.


7° corso "Totally NewBies"

Written by Spin0ne

Introduzione

Come dicevo...continua la saga degli esercizi multilivello di Andreageddon (bravo André anche questa volta mi sei piaciuto). L'altra volta ci ha fatto divertire con le chiavi del registro di windows, questa volta dovremo districarci con con gli accessi ai file che a volte i programmi vogliono per la propria registrazione.

Tools usati

Softice

URL o FTP del programma

Il file lo trovate sulla UIC

Notizie sul programma 

E' uno smazzolamento di palle, a quattro livelli di intensità (l'ultimo cominciava a fare un po' male), per farci capire gli accessi ai file attraverso le Api di Windows.  

Essay

Ormai finisce sempre cosi. Quando arriva un nuovo corso, è irrefrenabile l'istinto di aprirlo e vedere di cosa si tratta. Mi dico...azz...gli do' solo un'occhiata è poi riprendo a lavorare ed invece.........Ma veniamo a noi, cosa ci ha preparato Andrea questa volta? Lanciamo il file e subito ci appare una bella finestrella. Analizzandola scopriamo subito di cosa si tratta.......Keyfile...hummm...bene; inoltre dalla lettura delle info di ogni singolo livello intuiamo anche quali fregature il "furbastro" ci vuole rifilare. Apriamo il Sice e, come suggerisce l'autore colto da un raptus di magnanimità (troppo buono André....grazie), settiamo un breakpoint sull'Api "CreatefileA". Clicchiamo sul pulsante del 1° livello e brekkiamo all'interno dell'Api.... F12 per uscire e...........

:00401574 mov [ebp-04], 00000000
:0040157B push 00000000
:0040157D push 00000080
:00401582 push 00000003
:00401584 push 00000000
:00401586 push 00000000
:00401588 push 80000000
:0040158D push 00404154
:00401592 call dword ptr [004052AC]..............> Chiamata all'Api "CreateFileA"
:00401598 mov dword ptr [ebp-3C], eax............> Atterriamo qui all'uscita dell'Api
:0040159B cmp dword ptr [ebp-3C], -01............> Verifica se il file è stato trovato
:0040159F je 00401661............................> Se non trovato salta al mex "Errore apertura Keyfile"

Dunque, come ormai sappiamo, le istruzioni prima delle chiamate all'Api sono parametri passati alla funzione per il suo corretto svolgimento. In questo caso l'informazione basilare è il nome ed il path del file da ricercare. Questo viene fatto attraverso il push dell'ultimo indirizzo prima della call. Infatti l'istruzione push 404154 dice all'Api che in quella locazione risiedono le informazioni relative al file da cercare. Sarà sufficiente in Sice digitare "D 404154" e nella finestra dati potremo vedere: C:\KeyFile.And. Creamo questo file mettendo una manciata di byte e potremo vedere che di ritorno dall'Api, eax assumerà un valore positivo, il jz 401661 non verrà eseguito ed il programma continuerà verso l'Api "GetFileSize"

:004015A5 push 00000000
:004015A7 mov eax, dword ptr [ebp-3C]
:004015AA push eax
:004015AB Call dword ptr [004052A8]............> Chiamata all'Api "GetFileSize"
:004015B1 mov dword ptr [ebp-00AC], eax........> In eax la lunghezza in bytes del file trovato
:004015B7 cmp dword ptr [ebp-00AC], -01
:004015BE je 0040164F..........................> salta a "Errore file size" se la funzione fallisce

Ovviamente il programma proseguirà verso la lettura dei byte immessi nel file, attraverso l'Api "ReadFile"

:004015C4 push 00000000
:004015C6 lea ecx, dword ptr [ebp-00A8]
:004015CC push ecx....................> In ecx l'indirizzo dove verrà messo il n° di bytes che verranno letti
:004015CD mov edx, dword ptr [ebp-00AC]
:004015D3 push edx....................> In edx la lunghezza del file
:004015D4 lea eax, dword ptr [ebp-00A0]
:004015DA push eax....................> Qui viene pushato l'indirizzo dove verranno messi i byte letti
:004015DB mov ecx, dword ptr [ebp-3C]
:004015DE push ecx
:004015DF Call dword ptr [004052A4]...> Chiamata all'Api "ReadFile"
:004015E5 test eax, eax
:004015E7 je 0040163D
:004015E9 cmp dword ptr [ebp-00A8], 00..> Verifica se il file contiene byte
:004015F0 je 0040163D...................> Se vuoto salta al mex "keyfile vuoto"

Beh...qui mi sembra sufficientemente intuitivo. Durante la funzione vengono letti i bytes del nostro file. Vengono in seguito messi nella locazione che viene mossa in eax all'offset 4015D4. Il quantitativo di bytes (o la lughezza del file se preferite) letti dall'Api viene messo in ebp-A8. Qualora fosse zero il salto al mex "keyfile vuoto" è inevitabile. Altrimenti il proggyllo continua:

:004015F2 mov edx, dword ptr [ebp-00A8].......> In edx la lunghezza del file letto
:004015F8 mov byte ptr [ebp+edx-00A0], 00.....> Mette il "terminatore" alla stringa (o sequenza di byte letti)
:00401600 xor ecx, ecx
:00401602 lea esi, dword ptr [ebp+ecx-00A0]...> In esi il puntatore alla nostra stringa
:00401609 lea edi, dword ptr [ebp+ecx-0038]...> In edi il puntatore alla stringa da confrontare
:00401610 mov ecx, 0000002B...................> Contatore
:00401615 repz................................> Ripeti il ciclo
:00401616 cmpsb...............................> Confronta il byte puntato in esi ed edi
:00401617 jz 0040162B.........................> Se tutto ok salta a "Registered"

Allora... i bytes letti vengono messi in esi, mentre in edi ci sono quelli esatti che il programma confronterà con i nostri. Se i bytes sono uguali il salto avviene. Non appena il confronto di un singolo byte fallisce, il programma continua giustamente verso il mex "Codice sbagliato". Che fare allora x registrare questo 1° livello....beh semplice digitiamo in sice "d edi" e vediamo nella data windows qual'è la stringa contenuta (peraltro già intuita xchè esi ed edi sono due locazioni molto vicine..... magari fosse sempre cosi!!). Mettiamola con un editor esadecimale nel nostro Keyfile ed il 1° livello sarà..........."Registered".

Vediamo il secondo

Utilizziamo lo stesso breakpoint..... e questa volta:

:0040176C push 0040420C
:00401771 Call dword ptr [004052AC]..............> Chiamata all'Api "CreateFileA"
:00401777 mov dword ptr [ebp-20], eax............> Atterriamo qui all'uscita dell'Api
:0040177A cmp dword ptr [ebp-20], -01............> Verifica se il file è stato trovato
:0040177E je 00401865............................> Se non trovato salta al mex "Errore apertura Keyfile"
Bene è praticamente identico al 1° livello ;-), ma questa volta alla locazione 40420C viene salvato: C:\Windows\Andrewz.UIC. Anche qui mettete qualcosa nel keyfile.......io nel mio keyfile ho messo "Spin0ne the Best". Vediamo come si comporta il prog:
 
:004017BE Call dword ptr [004052A4]............> Chiamata all'Api "ReadFile"
:004017C4 test eax, eax........................> Verifica e..
:004017C6 je 00401841..........................> Salta se non è riuscito a leggere il file
:004017C8 cmp dword ptr [ebp+FFFFFF74], 00.....> Verifica se il file contiene byte
:004017CF je 00401841..........................> Se vuoto salta al mex "keyfile vuoto"
:004017D1 mov eax, dword ptr [ebp-008C].........> In eax il n° di bytes letti
:004017D7 mov byte ptr [ebp+eax-00000084], 00...> Mette il terminatore alla nostra stringa
:004017DF xor ecx, ecx
:004017E1 xor eax, eax
:004017E3 mov byte ptr [ebp+ecx-00000084], al..> Muove il byte puntato (della nostra stringa) in al
:004017EA cmp al, 00...........................> Verifica se il ciclo è terminato
:004017EC je 004017FC..........................> Salta se finito
:004017EE xor al, AA...........................> Altrimenti prendi il byte e lo xora con AA
:004017F0 mov al, byte ptr [ebp+ecx-00000084]..> Il risultato viene rimesso nella stessa locazione
:004017F7 inc ecx
:004017F8 xor eax, eax
:004017FA jmp 004017E1.........................> Riprendi il ciclo

Mi sembra abbastanza chiaro su cosa il nostro programma faccia dei bytes che abbiamo messo nel nostro keyfile: ogni byte viene xorato con il valore AA ed il risulytato è rimesso allo stesso posto. Vediamo come il prog utilizza la stringa risultante:

:004017FC mov byte ptr [ebp+ecx-00000084], 00
:00401804 xor ecx, ecx
:00401806 lea esi, dword ptr [ebp+ecx-00000084]..> In esi la locazione della nostra stringa
:0040180D lea edi, dword ptr [ebp+ecx-0000001C]..> In edi la locazione della stringa che viene confrontata
:00401814 mov ecx, 0000000F......................> Contatore dei cicli
:00401819 repz...................................> Ripeti il ciclo
:0040181A cmpsb..................................> Confronta il byte puntato in esi ed edi
:0040181B je 0040182F............................> Se alla fine dei confronti è tutto ok, salta a "Registered"
 
Bene il panorama è molto simile al 1° livello ma la difficoltà questa volta consiste in uno xor precedente dei nostri bytes con il valore AA e successivamente il risultato viene confrontato con i byte della stringa che viene messa in edi (ebp+ecx-1C). Quindi nel nostro keyfile dobbiamo mettere dei byte che xorati con il valore AA, diano come risultato i valori della locazione in edi. Beh sappiamo che per la particolarità dell'istruzione xor, il risultato xorato con lo stesso valore ritorna il valore originario, (es. 75 xor AA=DF se xoriamo il risultato sempre per AA otteremo: DF xor AA=75). Questo vuol dire che se mettessimo nel nostro keyfyle i bytes della stringa che vengono utilizzati per il confronto, otteremo il valore di origine. Quanti bytes?...be il ciclo di confronto viene ripetuto F volte (15 decimale), questa è la lunghezza della nostra stringa. Mettiamo nel nostro keyfile i primi 15 byte della stringa di confronto (DF C3 C9 F8 FF E6 EF F0 CC C5 D8 CF DC CF D8), apriamo il Sice e andiamo a vedere come cambia ogni singolo byte dopo lo xor con AA alla locazione ebp+ecx-0084. Vedremo che alla fine dell'iterazione del ciclo di xor, i nostri bytes sono cambiati risultando una stringa di senso compiuto: "uicRULEZforever". Sarà sufficiente mettere questa stringa nel nostro keyfile per passare il 2° livello.

3° livello

Ecco qua, cominciano le fregature!!! ci eravamo abituati troppo bene.....il Sice non poppa +. Sintomo che qualcosa è cambiato. Vediamo un po....trattandosi di un esercizio basato sui keyfile, potremo andare per tentativi e cercare di brekkare su Api che manipolano i file. A questo punto potremmo chiamare in aiuto altri tools.... magari usare il filemon oppure disassemblare il programma e darci un'occhiata. Ecco...proprio dal disassemblato possiamo riconoscere tanti passaggi che abbiamo percorso negli scorsi livelli ed ovviamente tante nuove informazioni interessanti. Approcciando le cose con metodo, vediamo che dopo il codice relativo al livello precedente, c'è una chiamata all'Api GetSystemDirectoryA che potrebbe far parte del nuovo livello. Proviamo a settare un breakpoint e vediamo se pigiando il 3° pulsante poppa.......Si!! avevamo visto giusto:

:00401929 push 00000104
:0040192E lea eax, dword ptr [ebp-0138]
:00401934 push eax.........................> Locazione dove verrà messa il nome della directory risultante
:00401935 Call dword ptr [004052B4]........> Chiamata all'Api "GetSystemDirectoryA"
:0040193B push 00000000
:0040193D lea ecx, dword ptr [ebp-0228]
:00401943 push ecx
:00401944 push 004042D0...................> Locazione dove risiede il nome del file da aprire
:00401949 Call dword ptr [004052B0].......> Chiamata all'Api "OpenFile"
:0040194F mov dword ptr [ebp-013C], eax...> In eax il risultato della ricerca
:00401955 cmp dword ptr [ebp-013C], -01...> Verifica se eax è negativo (file non trovato)
:0040195C jne 00401973....................> Se no salta e continua. Altrimenti vai in errore e carica.....
:0040195E push 004042AC...................> locazione del mex "Errore nell'apertura keyfile"
 
Dunque abbiamo visto che viene ricercato un file ed il suo nome lo si trova (viene passato all'Api) nella locazione 4042D0. Il nome del file é "Avelletri.fra" e la sua posizione viene data dalla chiamata all'Api precedente "GetsystemdirectoryA" che controlla la posizione della directory di sistema. La posizione viene salvata nella locazione dell'ultimo push eax all'indirizzo 401934, che in questo caso è C:\windows\system. Creamo questo file e mettiamoci un po' di bytes... i miei sono "53 70 69 6E 30 78" ( Spin0x). Steppiamo fino ad incontrare le Api che leggono il nostro file:
 
:00401A29 Call dword ptr [004052A8]..........> Chiamata a "GetFileSize"
:00401A2F mov dword ptr [ebp-0230], eax......> In eax lunghezza del file
:00401A35 push 00000000
:00401A37 lea edx, dword ptr [ebp-022C]
:00401A3D push edx
:00401A3E mov eax, dword ptr [ebp-0230]
:00401A44 push eax
:00401A45 lea ecx, dword ptr [ebp-1A0]
:00401A4B push ecx
:00401A4C mov edx, dword ptr [ebp-013C]
:00401A52 push edx...........................> Qui viene pushato l'indirizzo dove verranno messi i byte letti
:00401A53 Call dword ptr [004052A4]..........> Chiamata a "ReadFile"
:00401A59 test eax, eax......................> Verifica e...
:00401A5B je 00401AA8........................> Salta se non e riuscito a leggere il file
:00401A5D mov eax, dword ptr [ebp-022C]......> In eax il n° di bytes letti
:00401A63 mov byte ptr [ebp+eax-01A0], 00....> Mette il terminatore alla nostra stringa
:00401A6B xor ecx, ecx
:00401A6D lea esi, dword ptr [ebp+ecx-01A0]..> In esi il puntatore alla nostra stringa
:00401A74 lea edi, dword ptr [ebp+ecx-0034]..> In edi il puntatore alla stringa da confrontare
:00401A7B mov ecx, 00000024................. > Contatore
:00401A80 repz...............................> Ripeti il ciclo
:00401A81 cmpsb..............................> Confronta il byte puntato in esi ed edi
:00401A82 je 00401A96........................> Se alla fine dei confronti è tutto ok, salta a "Registered"

Abbastanza chiaro vero? Questo passaggio ci è ormai noto bastera guardare cosa c'è in memoria alla locazione che viene caricata in edi per capire cosa dovremo mettere nel nostro keyfile. Attenzione!!! quando sbirciate la locazione vedrete scritto: "La mia mente controlla la mia realt" e se la copiate pedestremente nel keyfile non funzionera!. In effetti se contate i bytes noterete che è composta da 35 bytes, mentre i cicli caricati in ecx sono 36 (24 in esadecimale), quindi dovete prendere in considerazione anche il 36° byte (E0) altrimenti...nisba!

Addedum post soluzione -Francamente non avevo capito la difficoltà di questo livello, anzi mi era sembrato più banale degli altri. Poi ho letto il tute di Andrea e ho capito la trappola del filemon........ma Andrea ci fa una pippa con le sue trappole e noi che usiamo il Sice..... non ci siamo cascati ;-).

4° Livello

Bene siamo arrivati all'ultimo livello....dunque cominciamo a vedere cosa succede se clicchiamo sul pulsante relativo al 4° livello..... "codice sbagliato".............heeeiiii, ma cosa è successo!!!?? In chiusura vediamo apparire il file sul desktop "papero.que". Hahahhahahah...grande Andrea (wé occhio al Bonzo che ti banna a vita.....). ...Torniamo seri..allora analizziamo il file...è vuoto. Appare evidente che lo ha creato il programma. proviamo a vedere se riusciamo a capire come. Visto che siamo sulla lezione dei keyfile e quest'ultimi generalmente vengono aperti e letti, mettiamo un bpx sù "OpenFile" e "ReadFile". Klikkiamo il 4° "bottone"...bene brekka sulla chiamata ReadFile ma siamo nel Kernel, pigiamo F12 per uscire e ci ritroviamo in una dll, precisamente la MSVRCT....humm...ancora F12 ancora in una dll..........E' chiaro che il programma si avvale dell'appoggio di funzioni preordinate delle librerie di windows, ma per fare cosa!!???.....Continuiamo e dopo numerosi F12 rientriamo finalmente nel nostro programma:

:00401BA7 push 004043D0
:00401BAC lea ecx, dword ptr [esp+18]
:00401BB0 Call dword ptr [00405444]
:00401BB6 lea edx, dword ptr [esp+08]
:00401BBA lea ecx, dword ptr [esp+0C]
:00401BBE push edx
:00401BBF Call dword ptr [00405440]
:00401BC5 lea ecx, dword ptr [esp+0C].........> Atteriamo qui
:00401BC9 Call dword ptr [00405448]
:00401BCF cmp dword ptr [esp+08], 08311809....> Confronta la la nostra stringa con il valore
:00401BD7 jne 00401BE0........................> Salta se non è uguale..altrimenti
:00401BD9 push 0040412C.......................> scrivi "Registered"...
:00401BDE jmp 00401BE5........................> ...e son finiti i casini!!!

Dunque..all'indirizzo 401BCF vediamo un compare con un valore definito. Dovremo fare in modo che nella locazione esp+08 venga scritto lo stesso valore in modo tale da abilitare il jmp verso il mex "Registered". Proviamo a scrivere "Spinox" in papero.que e vediamo come il proggy si comporta.....Ripercorriamo la procedura di break su readfile e....questa volta nella locazione esp+08, nella data window, vedremo 00 00 00 00..... che strana manipolazione, anzi pare non manipoli affatto :-(. Forse ritorna un risultato nullo xchè fa un ceck di lunghezza del file....Niente non si riesce a trovare traccia di eventuali ceck determinanti. Proviamo a cambiare e raddoppiamo il n° di bytes......niente!! ancora...Incrementiamo il n° di bytes scrivendo "Spin0x the best of UIC" (modesto eh?...ok ok.. .forse avrei fatto meglio a scrivere the oldest of)......azzo non cambia, sempre 00 00 00 00.. ma che succede!!?? (le mie poche conoscenze sull'assembler cominciano a vacillare fortemente)....Proviamo con i numeri mettendo in papero.que il classico "123456789" e......bam!!! è cambiato... vuole dei numeri!!!! Ora il cmp avviene con un valore risultante dalla manipolazione dei numeri immessi. Ora possiamo tentare di capire come vengono manipolati i bytes.

A questo punto devo dire che tutte le tecniche di break bpr bpmd per cercare di beccare l'algoritmo che manipola il serial mi portavano in un dedalo di call all'interno delle DLL dove non venivo a capo di niente. Ho cercato quindi, con metodo, di risalire a qualche indizio interessante.

Provate a seguirmi. Noterete che dopo aver messo i numeri nel file, se tenete d'occhio la locazione esp+08 nella data windows, vi accorgerete che il valore risultante dalla manipolazione viene scritto durante l'esecuzione della porzione di codice dell'ultima DLL MSVCIRT, prima di arrivare nel proggy "Settimo". Di ritorno dall'ennesimo F12 (il 13°) vi ritroverete all'indirizzo 780A5216 se usate windows 98 ( in widows 95 l'indirizzo è leggermente diverso. Cmq non dovrebbe essere difficile identificare i passaggi anche con indirizzi un po' traslati)..........steppate ma occhio ai cambiamenti di esp+8 nella data window!!

:780A5216 mov ecx, esi
:780A5218 push eax.....................> In eax si trova l'indirizzo dove verranno messi i bytes del keyfile
:780A5219 call 780A503B................> Chiamata a Readfile
:780A521E push eax.....................> Al 13° F12 atterate qui
:780A521F lea eax, dword ptr [ebp-10]
:780A5222 push 00000000
:780A5224 push eax
:780A5225 call [780A902C]..............> Call dove vengono manipolati i bytes
:780A522B mov ecx, 7FFFFFFF
:780A5230 add esp, 0000000C
:780A5233 cmp eax, ecx
:780A5235 jle 780A5258
:780A5237 mov eax, dword ptr [ebp+08]
:780A523A mov dword ptr [eax], ecx
:780A523C mov eax, dword ptr [esi]
:780A523E mov eax, dword ptr [eax+04]
:780A5241 or dword ptr [eax+esi+08], 00000002
:780A5246 lea eax, dword ptr [eax+esi+08]|
:780A524A mov ecx, esi
:780A5251 mov eax, esi
:780A5253 pop esi
:780A5254 leave
:780A5255 ret 0004
:780A5258 mov ecx, 80000000
:780A525D cmp eax, ecx
:780A525F jl 780A5237
:780A5261 mov ecx, dword ptr [ebp+08]
:780A5264 mov dword ptr [ecx], eax.........> Qui avviene la scrittura della locazione esp+08
:780A5266 jmp 780A524A

Steppate con molta attenzione e noterete che il valore viene scritto all'esecuzione dell'istruzione: "mov [edx] eax" all'indirizzo 780A5264. Quindi è chiaro che è eax che contiene il valore manipolato e lo passa a esp+08 dal momento che quest'ultimo è puntato dal registro ecx. Dobbiamo scoprire quando in eax viene scritto il valore che ci interessa. In effetti all'indirizzo 780A5225 c'è una call [780A902C], che al ritorno restituisce in eax il risultato che viene poi passato a esp+8. Pigiamo F8 ed entriamo nella call. Subito notiamo che siamo in un'altra DLL, la MSVCRT. Steppiamo e.......

:78011353 push 00000000
:78011355 push [esp+10]
:78011359 push [esp+10]
:7801135D push [esp+10]
:78011361 call 7801136A.............> Arrivati qui, altro F8 e andrete.......
:78011366 add esp, 00000010
:78011369 C3 ret
:7801136A push ebp..................> ...Qui
:7801136B mov ebp, esp
:7801136D sub esp, 0000000C
:78011370 push ebx
:78011371 and dword ptr [ebp-08], 00000000
:78011375 push esi
:78011376 push edi
:78011377 mov edi, dword ptr [ebp+08]........> Mette in edi il puntatore ai nostri bytes
:7801137A mov bl, byte ptr [edi].............> In bl il nostro 1° byte
:7801137C lea esi, dword ptr [edi+01]........> prepara il puntatore al prossimo byte, lo mette in esi e.....
:7801137F mov dword ptr [ebp-04], esi........> ....lo sposta nella locazione puntata da [ebp-04]
:78011382 cmp dword ptr [780371A4], 00000001
:78011389 jle 780113A1
:7801138B movzx eax, bl
:7801138E push 00000008
:78011390 push eax
:78011391 call 7800C897
:78011396 pop ecx
:78011397 pop ecx
:78011398 test eax, eax
:7801139A je 780113B2
:7801139C mov bl, byte ptr [esi]
:7801139E inc esi
:7801139F jmp 78011382
:780113A1 mov ecx, dword ptr [780371A8]
:780113A7 movzx eax, bl
:780113AA mov al, byte ptr [ecx+2*eax]
:780113AD and eax, 00000008
:780113B0 jmp 78011398
:780113B2 cmp bl, 2D
:780113B5 mov dword ptr [ebp-04], esi
:780113B8 jne 780113C6
:780113BA or dword ptr [ebp+14], 00000002
:780113BE mov bl, byte ptr [esi]
:780113C0 inc esi
:780113C1 mov dword ptr [ebp-04], esi
:780113C4 jmp 780113CB
:780113C6 cmp bl, 2B
:780113C9 je 780113BE
:780113CB mov eax, dword ptr [ebp+10]
:780113CE test eax, eax
:780113D0 jl 78011592
:780113D6 cmp eax, 00000001
:780113D9 je 78011592
:780113DF cmp eax, 00000024
:780113E2 jg 78011592
:780113E8 push 00000010
:780113EA test eax, eax
:780113EC pop ecx
:780113ED jne 78011489
:780113F3 cmp bl, 30
:780113F6 je 78011470
:780113F8 mov [ebp+10], 0000000A
:780113FF or eax, FFFFFFFF
:78011402 xor edx, edx
:78011404 div [ebp+10]
:78011407 mov edi, 00000103
:7801140C mov dword ptr [ebp-0C], eax
:7801140F cmp dword ptr [780371A4], 00000001..> 4)
:78011416 movzx esi, bl.......................> 5) Il byte viene messo in esi....
:78011419 jle 780114B6
:7801141F push 00000004
:78011421 push esi
:78011422 call 7800C897
:78011427 pop ecx
:78011428 pop ecx
:78011429 test eax, eax
:7801142B je 780114C6...................> Se tutti i bytes sono stati trattatati, il salto è eseguito e si va fuori routine
:78011431 movsx ecx, bl......................> 6) ...ed anche in ecx
:78011434 sub ecx, 00000030..................> 7) Toglie 30 dal byte (converte il n° in decimale)
:78011437 cmp ecx, dword ptr [ebp+10]........> 8) verifica che sia un numero decimale [ebp+10]=A
:7801143A jnb 7801150B.......................> 9) salta se maggiore altrimenti..
:78011440 mov esi, dword ptr [ebp-08]........> 10) ....metti in esi il risultato delle addizioni precedenti
:78011443 or dword ptr [ebp+14], 00000008
:78011447 cmp esi, dword ptr [ebp-0C]
:7801144A jb 780114FD........................> 11) Salta
:78011450 jne 78011462
:78011452 or eax, FFFFFFFF
:78011455 xor edx, edx
:78011457 div [ebp+10]
:7801145A cmp ecx, edx
:7801145C jbe 780114FD
:78011462 or dword ptr [ebp+14], 00000004
:78011466 mov eax, dword ptr [ebp-04].........> 1) Mette in eax il puntatore al nostro byte
:78011469 inc [ebp-04]........................> 2) Incrementa il contatore e lo prepara al prossimo byte
:7801146C mov bl, byte ptr [eax]..............> 3) In bl il byte puntato da trattare
:7801146E jmp 7801140F
:78011470 mov al, byte ptr [esi]
:78011472 cmp al, 78
:78011474 je 78011486
:78011476 cmp al, 58
:78011478 je 78011486
:7801147A mov [ebp+10], 00000008
:78011481 jmp 780113FF
:78011486 mov dword ptr [ebp+10], ecx
:78011489 cmp dword ptr [ebp+10], ecx
:7801148C jne 780113FF
:78011492 cmp bl, 30
:78011495 jne 780113FF
:7801149B mov al, byte ptr [esi]
:7801149D cmp al, 78
:7801149F je 780114A9
:780114A1 cmp al, 58
:780114A3 jne 780113FF
:780114A9 mov bl, byte ptr [esi+01]
:780114AC inc esi
:780114AD inc esi
:780114AE mov dword ptr [ebp-04], esi
:780114B1 jmp 780113FF
:780114B6 mov eax, dword ptr [780371A8]
:780114BB mov al, byte ptr [eax+2*esi]
:780114BE and eax, 00000004
:780114C1 jmp 78011429
:780114C6 cmp dword ptr [780371A4], 00000001
:780114CD jle 780114F0
:780114CF push edi
:780114D0 push esi
:780114D1 call 7800C897
:780114D6 pop ecx
:780114D7 pop ecx
:780114D8 test eax, eax
:780114DA je 7801150B
:780114DC movsx eax, bl
:780114DF push eax
:780114E0 call 780118CD
:780114E5 pop ecx
:780114E6 mov ecx, eax
:780114E8 sub ecx, 00000037
:780114EB jmp 78011437
:780114F0 mov eax, dword ptr [780371A8]
:780114F5 mov ax, word ptr [eax+2*esi]
:780114F9 and eax, edi
:780114FB jmp 780114D8
:780114FD imul esi, dword ptr [ebp+10]......> 12) Moltiplica il risultato delle addizioni precednti in esi per [ebp+10]=A
:78011501 add esi, ecx......................> 13) Addiziona il byte decimale in ecx al risultato ottenuto
:78011503 mov dword ptr [ebp-08], esi.......> 14) il tutto e posto nella locazione ebp-08
:78011506 jmp 78011466......................> Riprendi il ciclo

Non ho commentato questa lunghissima routine perchè ci sono molti passaggi che non mi sono chiari e molte porzioni di codice mi sembrano solo relative alla preparazione delle locazioni di vari puntatori. Cmq sono abbastanza chiari quelli relativi alla manipolazione dei nostri bytes. Infatti vengono presi di volta in volta e messi in bl ed in seguito anche in ecx dove, al valore esadecimale di ogni byte, viene sottratto 30 convertendo il byte in valore decimale. Se il risultato é inferiore ad A (e lo è visto che sono numeri), il ciclo continua. In esi invece viene caricato il valore accumulato dalle iterazioni precedentementi; valore che viene moltiplicato per A ed al risultato viene aggiunto il valore decimale de byte trattato. Il totale finale viene messo nella locazione puntata da ebp-08; locazione il cui contenuto, come abbiamo visto, è il parametro di uscita per il registro eax. Il valore di eax, come ricordate, viene mosso nella famosa locazione puntata da esp+08, che verrà in seguito confrontata per la registrazione del livello. Spero di esser stato sufficientemente chiaro.

Credo che abbiate ormai capito......i nostri numeri -che il programma recepisce in valore esadecimale- vengono trasformati in numeri decimali e manipolati secondo la routine della dll. Il risultato (la dword che viene messa nella locazione di memoria puntata da ebp-08) nel mio caso é 4E 61 BC 00. Rovesciateli (per via della struttura lifo dello stack) e digitando in Sice "? 00 BC 61 4E" vi verrà svelato che il corrispettivo valore decimale è....123456789 ;-) Con lo stesso metodo potete ora verificare ora che al valore di cmp 08311809, corrisponde il n° 13743145. Aprite il file papero.que con il notepad e metteteci questi numeri.............Registered!!!!!!!!

 

Note finali

Bene è fatta anche questa....passiamo ai saluti....Sicuramente all'autore che mi sta troppo simpatico e poi ai miei compagni di reverse Krios, Socio, e Bieco. Un saluto a tutta la ML ed infine....non puo mancare il nostro caro Bonzo....Ciao Que.

Byez Spin0

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. 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.
Capitoooooooo????? Bhè credo di si ;))))