Zoom Icon

Soluzione Crackme 18

From UIC Archive

Crackme n.18 : Stone's Cryptor 1.13

Contents


Soluzione Crackme 18
Author: ValerioSoft
Email: ValerioSoft(AT)tin.it
Website:
Date: 03/03/2007 (dd/mm/yyyy)
Level: Some skills are required
Language: Italian Flag Italian.gif
Comments: Il contadino nel suo campo impara sempre ciò che ancora non sà, ricostruisce ciò che nell’inverno ha perduto, cosicchè egli aiuta la natura senza per questo volersi intromettere.



Introduzione

Ciaoooooooooo, quinto tuteeeee??? SIIIIIIII
Allora si parteeeeee


Tools


Notizie sul CrackMe N.18

Questo è un crackme scritto da wIN-TRek, lo trovate qui.


Essay

Bene Bene Bene...fino ad ora abbiamo avviato i programmi in moda da individuare i suoi punti deboli ma questa volta dobbiamo prima effettuare un'altra operazione!!!

...come prima cosa avviamo il PEID 0.94 ed apriamo il file eseguibile del CrackMe,senza portarla per le lunghe questo bel programmillo ci dice che il file del CrackMe è crittato con Stone's Cryptor 1.13!!!

Cosa significa??? Beh significa che il CrackMe in questione è protetto e quindi non possiamo disassemblarlo con W32Dasm e non possiamo patcharlo con HIEW.Quindi si intuisce che prima di poter smanettare sul file come abbiamo sempre fatto occorre decrittare il file, abbiamo 2 strade:

  1. Scaricare da Internet Stone's Encryptor 1.13 e rimuovere la protezione ( senza imparare un bel niente :-P )
  2. fare un DUMP della memoria
  3. ...oppure decrittare il programma a mano

Io preferisco la terza via (quella più lunga o quasi), quindi apriamo il nostro CrackMe con Ollydbg!!! La prima cosa che ci fa notare e che il file è automodificante ovvero la prima cosa che il programma fa prima di partire e mettere tutto al posto giusto, questa parte di codice che viene eseguita all'inizio serve a decrittare il file prima del suo avvio vero e proprio!!!
Provo a spiegarlo ancora meglio: Prendiamo un file eseguibile qualsiasi, lo crittiamo con Stone's Cryptor 1.13 (o qualsiasi altro programma del genere) ed otteniamo un lo stesso file eseguibile che contiene una sezione in più in cui c'è l'algoritmo che serve a decrittare il file prima del suo avvio, se non ci fosse tale algoritmo il file risulterebbe danneggiato e quindi non più eseguibile. Quindi la cosa che dobbiamo fare e capire come l'algoritmo mette a posto le cose.
Abbiamo già aperto il file con Ollydbg, non ci resta che steppare con F7 e capire cosa succede, l'algoritmo è molto semplice quindi io vi mostro il listato con i relativi commenti :

00418000 PUSH EBP 00418001 PUSH EDI 00418002 PUSH ESI 00418003 PUSH EDX 00418004 PUSH ECX 00418005 PUSH EBX 00418006 CALL 0040800B 0041800B POP EBP 0041800C MOV EDX,EBP 0041800E SUB EBP,00403B97 00418014 SUB EDX,SS:[EBP+403C2D] 0041801A SUB EDX,0B 0041801D MOV SS:[EBP+403C36],EDX 00418023 ADD SS:[EBP+403C24],EDX 00418029 ADD SS:[EBP+403C28],EDX 0041802F CMP BYTE PTR SS:[EBP+403C2C],0 // All'inizio la locazione contiene 0 // quindi non salta

00418036 JNZ SHORT 00408082 00418038 MOV BYTE PTR SS:[EBP+403C2C],1 // carica nella locazione il valore 1 0041803F LEA ESI,SS:[EBP+403C35] 00418045 MOVZX ESI,BYTE PTR DS:[ESI] 00418048 MOV EDI,EBP 0041804A LEA EBX,SS:[EBP+403C36] 00418050 MOV EBX,DS:[EBX] 00418052 LEA EAX,DS:[EDI+403C3A] 00418058 MOV EAX,DS:[EAX] 0041805A ADD EBX,EAX // mette in EBX la locazione 401000

                                             // (Image Base + Virtual Offset di CODE)

// per il CODE il vero punto iniziale del programma // al secondo giro EBX = 402000 per DATA

0041805C LEA ECX,DS:[EDI+403C3E] 00418062 MOV ECX,DS:[ECX] // mette in ECX il valore A00 (Raw Size di CODE) // al secondo giro ECX = 1600

00418064 CMP EBX,SS:[EBP+403C28] // al primo giro confronta // 401000 e 400000

0041806A JG SHORT 00408076 // se il primo è maggiore del secondo salta 0041806C CMP EBX,SS:[EBP+403C24] 00418072 JL SHORT 00408076 00418074 JMP SHORT 00408079 00418076 SUB BYTE PTR DS:[EBX],1 // sottrae 1 al valore contenuto alla // locazione 401000, al primo giro 67 = g // diventa 66 = f // al primo giro si arriva fino a 4021FF

00418079 INC EBX // incrementa di 1 il valore di EBX // al primo giro 401000 diventa 401001

0041807A ^ LOOPD SHORT 00408064 // decrementa ECX e salta se è diverso da 0 // il loop finisce quando ECX = A00 // diventa ECX = 0 0041807C ADD EDI,8 0041807F DEC ESI // decrementa ESI da 2 diventa 1 00418080 ^ JNZ SHORT 0040804A // al primo giro salta, al secondo no

00418082 MOV EAX,SS:[EBP+403C31] // mette in EAX 1555 00418088 MOV EBX,SS:[EBP+403C36] // mette in EBX 400000 0041808E ADD EAX,EBX // mette la somma in EAX = 401555 00418090 POP EBX 00418091 POP ECX 00418092 POP EDX 00418093 POP ESI 00418094 POP EDI 00418095 POP EBP 00418096 JMP EAX // va all'inizio vero e proprio del // programma alla riga 00401555

Quindi cosa succede???
Per avere le idee più chiare dobbiamo utilizzare il PEditor 1.7, avviamolo ed apriamo il CrackMe mediante il tasto browse. Poi clicchiamo su sections, queste sono tutte le sezioni che il programma ha, io no mi dilungherò molto su questo argomento dato che alla UIC c'è un bel tutorial scritto da Andreageddon che può esservi utile come del resto lo è stato per me!!! (category:Staff)
Un normale programma ha tutte quelle belle sezioni tranne una ovvero la sezione .Stone questa infatti è stata inserita dallo Stone's Cryptor 1.7 ed è la sezione che si occupa di decrittare il file, guardate il Virtual Size, se li sommate tutti ottenete il valore 18000 che corrisponde proprio al suo Virtual Offset che sommato all' Image Base 00400000 ci da l'indirizzo 00418000 che corrisponde alla prima istruzione che eseguiamo quando apriamo il file con Ollydbg.

Vi dico di più, la stessa tabella ve la mostra anche Ollydbg se andate al menù Plugins->OllyDbg PE Dumper->Make dump of process. Quindi sempre tenendo a mente questa tabella guardate alla riga 0041805A viene messo in EBX il valore 00401000 che deriva dalla somma di 400000 (Image Base) e 1000 (Virtual Offset della sezione CODE), questa è la prima vera istruzione del programma e viene modificata alla riga 00418076 infatti viene sottratto 1 al valore contenuto alla locazione 00401000. Questo è un ciclo che ad ogni giro incrementa di 1 EBX (ad esempio passa da 00401000 a 00401001) ed il suo valore viene poi decrementato di 1 (al primo giro 67 = g diventa 66 = f), questa iterazione continua fino a quando ECX è diverso da 0, per il primo giro ECX viene inizializzato con il Raw Size di CODE cioè 00000A00. Ciò significa che al primo giro verranno decrementati di 1 tutti i valori contenuti nelle locazioni da 00401000 a 004014FF (00401A00 - 1) mentre al secondo giro si parte da 00402000 ( Image Base + Virtual Offset di DATA) e il numero di iterazioni dipende dal Raw Size di DATA ovvero 00001600 quindi vengono decrementati di 1 tutti i valori contenuti dalla locazione 00402000 a 004035FF (00403600 - 1). Dopo di che non succede più nulla, il file è decrittato, si arriva alla riga 00418096 in cui c'è il JUMP che ci porta all'istruzione 00401555, questa istruzione è molto importante e ci servirà più tardi.

Adesso possiamo chiudere Ollydbg dato che per ora non ci serve più, facciamo come al solito una copia del programma da craccare e poi apriamolo con AXE, a cosa ci serve??? Dobbiamo fare ciò che l'algoritmo di decrittazione fa a runtime ovvero sottrarre 1 a tutti i byte inquisiti, l'offset di AXE ha una corrispondenza con il Raw Offset del file visto con il PEditor, la prima sezione che viene modificata dall'algoritmo è la CODE quindi in AXE dobbiamo selezionare tutti i byte che vanno da 800 a 11FF (800 + A00 - 1) dato che poi a 1200 inizia la sezione DATA. Dopo averli selezionati clicchiamo con il tasto destro del mouse e scegliamo l'opzione Mark selected byte, poi andiamo al menù Operations->Arithmetic, vi compare un'altra finestra, voi scegliete Operate on marked areas, Operator: Subtract, 'Operand : 1, mettete la spunta su Hexe Treat data as: byte. Adesso premete il pulsante OK e AXE farà la sottrazione per ogni byte selezionato. Non abbiamo ancora finito!!! Adesso fate l'Unmark Selected Bytes sui byte precedentemente selezionati e poi effettuiamo lo stesso procedimento per la sottrazione dei byte della sezione DATA che va da 1200 a 27FF.

Ora proviamo ad avviare il file modificato e come per magia crasha, secondo voi perchè lo fa???? :-D

Beh se aprite il file con Ollydbg vi accorgete che il programma parte dall'istruzione 00418000 ed esegue l'algoritmo per la decrittazione che a noi non serve più perchè il file è già decrittato quindi cosa si può fare??? Modifichiamo con il PEditor l'Entry Point del programma sostituendo 00018000 con 00001555 (Ricordate l'ultimo JUMP??? 00401555 - Image Base).Applicate i cambiamenti e provate ad eseguire il file...

Abbiamo ottenuto il file decrittato, questa è una protezione molto semplice ma è un buon punto di partenza!!! :-)

Ora che abbiamo capito come stanno realmente le cose proviamo a decrittare il programma con un DUMP della memoria, apriamo il file crittato con Ollydbg e piazziamo un bel breakpoint on execution alla riga 00418096, premiamo F8 o F7 e saltiamo alla riga 00401555, ora andiamo al menù Plugins->OllyDbg PE Dumper->Make dump of process poi premiamo il pulsante Dump, lui ci chiede dove salvare il file e noi lo salviamo nella stessa cartella del CrackMe anche perchè per funzionare il programma ha bisogno di FLAF.DLL. Avviamo il file dumpato e magicamente funziona, in realtà non doveva funzionare dato non abbiamo modificato l'Entry Point con il PEditor ma in questo caso non c'è bisogno perchè l'algoritmo alla riga 0041802F si frega con le sue stesse mani perchè li c'è il confronto tra 0 ed il valore contenuto ad una certa locazione, quel valore inizialmente è 0 quindi all'istruzione successiva non salta e viene eseguito per intero l'algoritmo, ma prima della sua esecuzione nella locazione incriminata viene messo un 1 e quindi dopo il dump il valore rimane quello e quindi anche se il programma da 00418000 non accade assolutamente nulla ed il file non viene più modificato.

Non ci resta che ringraziare Stone per il suo aiuto!!! :-P

Dimenticavo che anche il file FLAF.DLL è crittato con lo stesso algoritmo utilizzato per il file eseguibile ma lascio a voi la decrittazione tanto si utilizza sempre lo stesso procedimento!!!

Il Patching

Adesso che il programma è bello che decrittato possiamo avviarlo e trovare un punto di attacco, il migliore potrebbe essere la stringa nOT cORRECT !!! :-P. Allora apriamo il file con Ollydbg e diamo uno sguardo alle stringhe con il solito metodo. Bene la stringa c'è, clicchiamoci su 2 volte e vediamo quale istruzione la utilizza.

Possible StringData Ref from Data Obj ->"nOT cORRECT !!! :-P"

                                 |

00401857 688B204000 push 0040208B 0040185C 6A00 push 00000000 0040185E 6A0C push 0000000C 00401860 FF353A344000 push dword ptr [0040343A]

...

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

Possible StringData Ref from Data Obj ->"cORRECT !!!!!!  :-)"

                                 |

0040186C 689F204000 push 0040209F 00401871 6A00 push 00000000 00401873 6A0C push 0000000C 00401875 FF353A344000 push dword ptr [0040343A]


La stringa viene utilizzata dall'istruzione 00401857, diamo uno sguardo più su alla ricerca di un salto che ci porti oltre l'errore anzi no è proprio lampante, guardate nel listato sopra la scritta cORRECT !!!!!!  :-) c'è l'indirizzo dell'istruzione che ci porta alle congratulazioni.

Referenced by a CALL at Addresses: |:00401647 , :00401843

00401849 E8CFF8FFFF call 0040111D 0040184E 83F800 cmp eax, 00000000 00401851 7519 jne 0040186C // se salta si registra


Cosa bisogna fare per patchare il programma??? Beh, bisogna fare in modo che salti sempre, ci sono 100 modi possibili per farlo :-D io ne propongo uno senza tanti sforzi, guardate l'istruzione di confronto precedente al JNE, possiamo modificare la costante che viene confrontata con il valore di EAX trasformandola da 0000000 in 00000001.


Registry Attack

Finalmente qualcosa di diverso dal SerialFishing!!!

Riprendiamo dal punto in cui si può patchare il programma, dobbiamo capire chi va ad inserire il valore in EAX prima del confronto alla riga 0040184E. Per poterlo sapere piazziamo un breakpoint alla riga 00401849 ed avviamo l'applicazione, quando Ollydbg prende il controllo steppiamo con F8 e controlliamo se il valore di EAX è cambiato! Come sospettavamo è proprio la Call alla riga 00401849 che modifica il valore contenuto nel registro EAX, quindi riavviamo l'applicazione e questa colta entriamo nella Call con F7 ed arriviamo alla riga 0040111D.Qualche riga più giù ci sono diverse Call che iniziano con Reg ciò vuol dire che in questo CrackMe si dovrà interagire con il Registro di WinZoz.

0040112C 6890214000 push 00402190 // pHandle = AXE_PE_C.00402190 00401131 680700003C push 3C000007 // Access = KEY_QUERY_VALUE|KEY_SET_VALUE

                                                       // |KEY_CREATE_SUB_KEY|3C000000

00401136 6A00 push 00000000 // Reserved = 0 00401138 683B214000 push 0040213B // Subkey = "SOFTWARE\\Netscape

                                                       // \\Netscape Navigator\\Users"

0040113D 6802000080 push 80000002 // hKey = HKEY_LOCAL_MACHINE

Reference To: ADVAPI32.RegOpenKeyExA, Ord:0000h

                                 |

00401142 E83A070000 Call 00401881 // Controlla se nel registro c'è // la suddetta chiave e setta EAX = 0 // se la trova

00401147 83F800 cmp eax, 00000000 // confronta EAX con 0 0040114A 0F8519010000 jne 00401269 // salta all'errore se sono diversi


Cosa fa questa bella funzioncina??? Beh, controlla nel registro di WinZoz se esiste la chiave HKEY_LOCAL_MACHINE\SOFTWARE\Netscape\Netscape Navigator\Users con le seguenti autorizzazioni settate : Query valore, Impostazione valore e Creazione sottochiave. Se la chiave viene trovata allora in EAX mette il valore 0 = Error Success altrimenti mette in EAX un valore più grande di zero a seconda dell'errore riscontrato. Secondo voi ci sarà questa chiave nel registro :-)???? Sicuramente NO quindi dovremo crearcela, allora con START->Esegui...->regedit si dovrebbe aprire l'Editor del Registro di Sistema, andiamo in HKEY_LOCAL_MACHINE\SOFTWARE\ e controlliamo se c'è la chiave Netscape. A me non c'è :-D e quindi clicco su SOFTWARE con il tasto destro del mouse e seleziono Nuovo->Chiave e creo dentro SOFTWARE la chiave Netscape, dentro Netscape la chiave Netscape Navigator e dentro Netscape Navigator mi creo Users. Non abbiamo ancora finito perchè dobbiamo settare le autorizzazioni giuste quindi clicchiamo con il tasto destro del mouse sulla chiave Users e scegliamo la voce Autorizzazioni->Avanzate, poi seleziono Valerio(UFFICIO\Valerio) (a voi sarà un pò diverso :-D ), poi faccio Modifica e poi nego Controllo Completo e faccio OK. Dopo questa operazione vi comparirà nella lista un'altra occorrenza di Valerio(UFFICIO\Valerio) ma questa volta speciale, clicchiamoci su e poi facciamo modifica, mettiamo la spunta su Consenti per Query valore, Impostazione valore e Creazione sottochiave. Facciamo OK ed il gioco è fatto!!! Chiudiamo il registro e riavviamo l'applicazione con Ollydbg, arrivati alla riga 00401142 richiamiamo la Call e guardiamo il valore che ci ha messo nel registro EAX. EAX = 5 Nooooooooooooooooo?!?!?!?! Cosa è andato storto??? Non vi nascondo che ci ho perso la testa per un bel pò, poi ho cominciato a modificare le autorizzazioni ed ho capito che il problema è il 3C che viene passato insieme alle autorizzazioni. Sono andato al sito http://msdn2.microsoft.com/en-us/library/ms724878.aspx per saperne di più su queste benedette autorizzazioni ma di 3C neanche l'ombra quindi secondo me è un'errore di programmazione e la cosa più semplice è patchare il programma sostituendo definitivamente il 3c con 00. Quindi per chi non lo avesse capito la riga 00401131 680700003C diventa 00401131 6807000000 e la riga 0040119F 680700003C diventa 00401131 6807000000. Questo per mantenere una coerenza logica con il CrackMe altrimenti avremmo potuto sostituire 680700003C con 683F000F00 che corrisponde a KEY_ALL_ACCESS.

Dopo queste modifiche con AXE o qualsiasi altro programma similare siamo pronti a riaprire il CrackMe con Ollydbg, arriviamo alla riga 00401142, eseguiamo la Call e guardiamo il valore di EAX che questa volta è 0. Quindi possiamo proseguire...

00401150 68B2214000 push 004021B2 // a questa locazione verrà messo il // numero di byte del valore

00401155 6894214000 push 00402194 // a questa locazione verrà messo il // contenuto di CurrentUser

0040115A 6A00 push 00000000 // tipo non specificato 0040115C 6A00 push 00000000

Possible StringData Ref from Data Obj ->"CurrentUser"

                                 |

0040115E 6884214000 push 00402184 // nome del valore

00401163 FF3590214000 push dword ptr [00402190]

Reference To: ADVAPI32.RegQueryValueExA, Ord:0000h

                                 |

00401169 E81F070000 Call 0040188D // Controlla se la chiave precedentemente // aperta contiene un valore chiamato

                                                       // CurrentUser

// in questo caso di tipo non specificato // se il valore c'è allora setta EAX = 0


Cosa fa quest'altra funzione??? Controlla se nella chiave Users c'è il valore (ad esempio tipo stringa) chiamato CurrentUser e se lo trova mette in EAX il valore 0, poi mette alla locazione 00402194 la stringa contenuta in CurrentUser e mette alla locazione 004021B2 il numero di byte della stringa letta. Allora cosa dobbiamo fare prima di eseguire la funzione???? Dobbiamo creare nella chiave Users il valore CurrentUser, io lo creo di tipo stringa e poi inserisco ovviamente ValerioSoft.

Dopo averlo creato riavviamo l'applicazione ed eseguiamo l'istruzione 00401169, bene come ci aspettavamo avremo EAX = 0, poi alla locazione 00402194 ci sarà ValerioSoft e alla locazione 004021B2 ci sarà il valore esadecimale B (numero di caratteri).

00401177 FF3590214000 push dword ptr [00402190] // passa l'handle del chiave

Reference To: ADVAPI32.RegCloseKey, Ord:0000h

                                 |

0040117D E805070000 Call 00401887 // chiude la chiave aperta

00401182 8B0DB2214000 mov ecx, dword ptr [004021B2] // mette in ECX il numero di // caratteri letti

00401188 BE94214000 mov esi, 00402194 // mette in ESI la locazione // che contiene la stringa letta

0040118D BF65214000 mov edi, 00402165 // mette in EDI la locazione che // la fine della stringa di SubKey

00401192 B05C mov al, 5C // mette in AL il valore 5C 00401194 AA stosb // mette il valore 5C alla // locazione puntata da EDI

00401195 F2 repnz // Sposta una per volta i caratteri // contenuti alla locazione puntata // da ESI in EDI 00401196 A4 movsb 00401197 B000 mov al, 00 // mette in AL il valore 0 00401199 AA stosb // mette il valore 0 alla // locazione puntata da EDI


Cosa è successo??? Beh alla locazione 0040213B prima c'era HKEY_LOCAL_MACHINE\SOFTWARE\Netscape\Netscape Navigator\Users mentre adesso c'è HKEY_LOCAL_MACHINE\SOFTWARE\Netscape\Netscape Navigator\Users\ValerioSoft.

0040119A 6890214000 push 00402190 0040119F 680700003C push 3C000007 004011A4 6A00 push 00000000 004011A6 683B214000 push 0040213B // SOFTWARE\Netscape\Netscape Navigator

                                                   // \Users\ValerioSoft

004011AB 6802000080 push 80000002

Reference To: ADVAPI32.RegOpenKeyExA, Ord:0000h

                                 |

004011B0 E8CC060000 Call 00401881 004011B5 83F800 cmp eax, 00000000 004011B8 0F85AB000000 jne 00401269


Cerca di aprire la nuova chiave che noi dobbiamo creare nel registro (con le giuste autorizzazioni). Facciamolo!!! Occhio che i permessi non ve lo permettono quindi rimuoveteli momentaneamente. :-D poi però rimetteteli al loro posto prima di eseguire la Call. Se è andato tutto bene il salto non viene eseguito!

004011BE 680E224000 push 0040220E 004011C3 68BE214000 push 004021BE 004011C8 6A00 push 00000000 004011CA 6A00 push 00000000

Possible StringData Ref from Data Obj ->"DirRoot"

                                 |

004011CC 68B6214000 push 004021B6 004011D1 FF3590214000 push dword ptr [00402190]

Reference To: ADVAPI32.RegQueryValueExA, Ord:0000h

                                 |

004011D7 E8B1060000 Call 0040188D 004011DC 83F800 cmp eax, 00000000 004011DF 0F8584000000 jne 00401269 // se EAX è diverso da zero // salta all'errore


Ora nella chiave ValerioSoft cerca il valore DirRoot, e noi lo creiamo.Vi dico di più, già dal nome ci accorgiamo che la stringa che deve contenere questo valore è quanto meno una directory, allora inserisco la directory del CrackMe che nel mio caso è D:\CrackMe\crackme19, guardiamo il codice seguente :

004011F0 8B0D0E224000 mov ecx, dword ptr [0040220E] // mette in ECX il numero di

                                                               // caratteri che compongono
                                                               // la directory

004011F6 49 dec ecx // decrementa di 1 ECX

004011F7 BFBE214000 mov edi, 004021BE // mette in EDI la locazione che // contiene la directory letta

004011FC 03F9 add edi, ecx // si posiziona alla fine della

                                                               // stringa

// (directory) sommando il numero

                                                               // di char. 


004011FE BE12224000 mov esi, 00402212 // mette il ESI la locazione che

                                                               // contiene la stringa
                                                               // \bookmark.htm

00401203 B90E000000 mov ecx, 0000000E 00401208 F2 REPNE MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]

                                                            // Sposta una per volta i caratteri
                                                            // contenuti alla locazione puntata

// da ESI in EDI


Cosa fa??? La nostra directory ora ha anche un nome di un file!!! D:\CrackMe\crackme19\bookmark.htm.

0040120A 6A00 push 00000000 // hTemplateFile = NULL 0040120C 6880000000 push 00000080 // Attributes = NORMAL 00401211 6A03 push 00000003 // Mode = OPEN_EXISTING 00401213 6A00 push 00000000 // pSecurity = NULL 00401215 6A03 push 00000003 // ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE 00401217 68000000C0 push C0000000 // Access = GENERIC_READ|GENERIC_WRITE 0040121C 68BE214000 push 004021BE // FileName = "D:\\CrackMe

                                               // \\crackme19\\bookmark.htm"

Reference To: KERNEL32.CreateFileA, Ord:0000h

                                 |

00401221 E891060000 Call 004018B7 00401226 83F8FF cmp eax, FFFFFFFF 00401229 743E je 00401269 // salta all'errore se EAX = FFFFFFFF


Dal nome della Call si intuisce che verrà creato un file bookmark.htm nella directory specificata ma in realtà non è proprio così infatti se guardate più su c'è Mode = OPEN_EXISTING che invece dice di aprire un file già esistente, quindi prima di eseguire la Call andiamo a creare il file bookmark.htm nella directory.Se tutto va per il verso giusto EAX viene inizializzato con il valore dell'handle del file altrimenti con FFFFFFFF.

0040122F A320224000 mov dword ptr [00402220], eax // salva l'handle del file 00401234 6824224000 push 00402224 // passa la locazione in

                                                                  // cui viene memorizzata
                                                                  // la grandezza del file

00401239 FF3520224000 push dword ptr [00402220] // passa l'handle alla funzione

Reference To: KERNEL32.GetFileSize, Ord:0000h

                                 |

0040123F E84F060000 Call 00401893

Prima di eseguire la Call, modifico il file bookmark.htm inserendo al suo interno la stringa ValerioSoft e vediamo cosa succede!!!Bene la funzione inizializza EAX con il numero di caratteri letti nel file bookmark, nel mio caso 11 ovvero 0B (in esadecimale).

00401244 8BD8 mov ebx, eax // mette in EBX il numero di char letti 00401246 C1E810 shr eax, 10 // se i caratteri letti sono pochi // dopo lo shift a destra EAX = 0

00401249 668BD0 mov dx, ax // salva in DX il contenuto di AX 0040124C 668BC3 mov ax, bx // li risposta in EAX 0040124F E826FEFFFF call 0040107A // esegue la Call che inizializza EAX // per il confronto 00401254 83F801 cmp eax, 00000001 00401257 7510 jne 00401269 // salta all'errore se EAX è diverso da 1

Quindi ci tocca andare a vedere cosa succede alla Call 0040107A, entriamo con F7.

0040107C 6689151A204000 mov word ptr [0040201A], dx // dopo lo shift a destra

                                                                  // probabilmente

// in DX ci sarà 0000 quindi

                                                                  // azzera la locazione 0040201A

00401083 6689151C204000 mov word ptr [0040201C], dx 0040108A 6633C0 xor ax, ax // azzera AX 0040108D A222204000 mov byte ptr [00402022], al 00401092 66833D1A20400000 cmp word ptr [0040201A], 0000 0040109A 7440 je 004010DC // se i char letti sono pochi

                                                                  // allora salta

Nel nostro caso i caratteri letti sono 11 e quindi salta!!!

Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040109A(C)

004010DC 6659 pop cx // estrae dallo stack il numero di // caratteri letti 004010DE 81E1FFFF0000 and ecx, 0000FFFF 004010E4 6A00 push 00000000 // pOverlapped = NULL 004010E6 6818204000 push 00402018 // BytesRead = AXE_PE_C.00402018 004010EB 51 push ecx // BytesToRead = B (11.) 004010EC 6826224000 push 00402226 // Buffer = AXE_PE_C.00402226 004010F1 FF3520224000 push dword ptr [00402220] // handle File = 00000080 (window)

Reference To: KERNEL32.ReadFile, Ord:0000h

                                 |

004010F7 E8B5070000 Call 004018B1 // Call ReadFile 004010FC E8FFFEFFFF call 00401000

Dopo la Call alla locazione 00402226 viene inserita la stringa letta. Bisogna notare una cosa importante, a noi interessa il valore di EAX quando si esce da questa funzione ovvero se EAX = 0 allora si salta all'errore mentre se EAX = 1 allora vuol dire che il CrackMe è risolto. Chi inizializza EAX prima di approdare sul RET??? La locazione 00402220!!! Ma chi è che la inizializza??? Probabilmente la inizializza la Call 00401000 che si trova dopo la chiamata a ReadFile quindi dobbiamo entrarci e vedere cosa succede!!!

0040101A 8B3523204000 mov esi, dword ptr [00402023] // mette in ESI la locazione che

                                                               // contiene la stringa
                                                               // http://phrozencrew.org

00401020 AC lodsb // mette in EAX il numero di char // della scritta

00401021 8AD8 mov bl, al // copia il valore in BL 00401023 8B0D18204000 mov ecx, dword ptr [00402018] // mette in ECX il numero di char

                                                               // letti dal file bookmark.htm

00401029 BF26224000 mov edi, 00402226 // mette in EDI la locazione che

                                                               // contiene la stringa letta dal
                                                               // file			

Senza portarla troppo alla lunga, la Call 00401000 controlla se la stringa http://phrozencrew.org è uguale a quella letta dal file bookmark.htm!!! Se sono uguali allora alla riga 0040105D viene incrementato il valore alla locazione 00402022 altrimenti il suo valore resta zero!!! Quindi per registrare il programma possiamo andare a scrivere nel file bookmark.htm la scritta http://phrozencrew.org oppure possiamo patchare il programma sostituendo la scritta http://phrozencrew.org che si trova alla riga 00402001 con ValerioSoft!!!

cORRECT !!!!!!  :-)

Il Nag Screen

Oggi mi sento proprio in vena e non mi basta la registrazione del programma!!! A voi non scoccia il fatto di dover premere il pulsante CONTINUE??? A me si e dato che è molto semplice eliminare il Nag Screen mi metto subito a lavoro....

Secondo voi come si può procedere??? Beh o guardiamo con Ollydbg nelle stringhe oppure guardiamo nella finestra delle Intermodular Calls, non cambia assolutamente nulla, io ho utilizzato la seconda strada infatti ho piazzato un bel breakpoint su tutte le Call ShowWindow ed ho avviato il programma. La prima Call viene effettuata alla riga 00401309 e se premiamo F8 ci compare il Nag Screen, abbiamo individuato senza tanti sforzi il punto in cui viene richiamata la finestra che vogliamo eliminare, ma proseguiamo alla riga 004015F3 viene invece mostrata la vera schermata del programma.

Ora apriamo il disassemblato di W32dasm e andiamo alla riga 004015F3, ci accorgiamo subito che questa istruzione è molto vicina all'Entry Point del programma e che non c'è nessun JUMP che ci porta li quindi è l'altra istruzione che viene richiamata in qualche modo. Andiamo quindi alla riga 00401309 e diamo uno sguardo alle istruzioni che la precedono alla ricerca di un JUMP o qualcosa di simile che ci porta li. Gurdate cosa c'è!!!

Referenced by a CALL at Address: |:00401561

00401275 50 push eax


Quindi il Nag Screen viene richiamato da una Call alla riga 00401561, andiamo a vedere!!! Come si può intuire questa istruzione precede quella che mostra la vera finestra del programma, prima di patchare il file andiamo a fare una prova con Ollydbg a runtime in modo tale che se ci siamo sbagliati non compromettiamo il file originale. Apriamo il CrackMe e andiamo alla riga 00401561, bisogna noppare tutta la riga quindi clicchiamoci su con il tasto destro e poi scegliamo Binary->Edit e sostituiamo le cifre esadecimali E80FFDFFFF con 9090909090 e premiamo il tasto OK. Avviamo il programma e..................

PERFETTO ANCHE QUESTA E' ANDATA!!!


Note Finali

Beh questa volta i miei ringraziamenti vanno ad AndreaGeddon per il meraviglioso saggio sul PEditor!!! Ciaoooooooooooooooooo alla proximaaaaaaaaa

ValerioSoft


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.