| Titolo |
||
| Data |
by "Pnluck" |
|
| 13/05/2004 |
Published by Quequero |
|
|
|
Grazie tante pnluck |
|
| .... |
E-mail: pnluck@virgilio.it Nick, UIN, canale IRC/EFnet frequentato |
.... |
| Difficoltà |
(X)NewBies ( )Intermedio ( )Avanzato ( )Master |
|
Inziamo ad imparare il reversing solo con Ollydbg e Hiew
Newbie n°2
Written by Pnluck
| Introduzione |
Impariamo a poppare finestre ed a scovare password
| Tools usati |
Tools usati: Ollydbg (dugurger), Hiew (editor hex), manuale di api ,di codici ascii, di asm.
| Notizie sul programma |
Nel primo programma, dovremo far apparire direttamente la finestra con “About”, nel secondo dovremo scovare la password
| Essay |
1 Parte)
Lanciamo il primo crackme e vedremo la scritta che ci dice di crackare il programma, quindi noi dovremo fa apparire direttamente la finestra successiva. Apriamo con l’Ollydbg il crackme1, dopo averlo caricato notiamo subito il codice in 401013, nel quale appare in chiaro (non vi ci abituate) “Plz etc…”, ora notiamo la parentesi graffa a destra, la quale indica, che nel suo interno c’è una chiamata ad una api di windows. La chiamata in questo caso è a MessageBoxA, la quale fa apparire una finestra. Ecco il templare
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
Nell’Olly li vedrete al contrario xchè, nello stack l’ultimo ad entrare è il primo ad uscire, quindi se nel codice sorgente avete messo prima ‘style’, disassemblando il programma ‘style’ apparirà x ultimo.
Ora alla riga 40101E c’è una ‘call’ a MessageBoxA. Ora facciamo un ‘esperimento’ cliccateci sopra e pigiate ‘F2’ x metteteci un breakpoint (il breakpoint è il punto in cui si dice al deburger di fermare il programma). Ora clicchiamo su F9 x far partire il programma, e tatah, l’Olly si ferma proprio a 40101E. Ora premiamo F8 x farlo steppare (andare avanti), e subbito ci esce la la finestra con “Plz etc…”. Il nostro scopo è quello di non far apparire questa finestra, e per far ciò utilizziamo sempre l’Olly, premiamo ‘Crtl+F2’ x far riavviare il programma e clicchiamo sulla chiamata a MessabeBoxA, pulsante destro ‘Binary/Fill with NOPs’ e al posto di
0040101E E8 DA010000 CALL <JMP.&USER32.MessageBoxA>
Troveremo
0040101E 90 NOP
00401020 90 NOP
00401021 90 NOP
00401022 90 NOP
I ‘NOP’ significa ‘vai avanti xchè io non faccio niente’, ora clicchiamo F9, e come x magia abbiamo risolto il crackme1 solo in memoria, xkè l’Olly non salva direttamente sul file ma in memoria. Ora apriamo con Hiew crackme1 e premiamo 2volte ‘Invio’ x far apparire il codice asm, ora dobbiamo andare a 40101E e x farlo clikiamo su F5 e scriviamo ‘.40101E‘, il punto serve xchè esso indica a Hiew che quello è l’indirizzo della memoria da aprire, ora clicchiamo su F3 x editare, e poi scriviamo 5volte 90 (90 è il codice esadecimale di NOP). Premete F9 x salvare il file modificato ed F10 x uscire. Ora apriamo il file così modificato x “scoprire” che l’abbiamo reversato(sinonimo di Crackato)
2 Parte)
Apriamo Crackme2 con Olly e facciamolo partire, inseriamo un serial a caso e ammeno che non abbiate un grande culo, vi appare un messaggio di errore. Ora chiudiamo e facciamo ripartire il programma,clickiamo col pulsante destro “Search for/Intermodular calls”, che farà apparire tutte le chiamate alle api presenti nel programma. Notiamo subbito le 3 call a MessageBoxA, clikiamoci 2volte sopra sulla prima, ed l’Olly ci fa apparire la schermata col file disassemblato sulla riga :
004011CA CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
Notiamo che la prima call è x l’psw inserita corretta, la seconda è quella che ci è apparsa prima e la terza è quella in cui si inserisce la psw.
Vediamo che le ultime due call a MessageBoxA finiscono con RET ( Il RET fa ritornare il programma al suo corso cormale ad esempio: in un programma c’è una call ad un’istruzione che alla fine ha un RET che fa tornare il programma all’indirizzo successivo alla call). Clikiamo all’inizio del MessageBoxA dell’errore (dove compare ‘style’ , sotto la finestra del decompilatore ci appare “jump from indirizzo”, ora lì facciamo pulsante destro e “Go to …”. L’ Olly ci porta sopra la MessageBoxA con la finestra dei complimenti, ora saliamo finche troviamo GetWindowTextLenght
int GetWindowTextLength(
HWND hWnd // handle of window or control with text
);
GetWindowTextA restituisce il numero decimale di una stringa, nel nostro caso di quella inserita da noi, ora analizziamo il periodo dal RET a MessageBoxA:
004011A7 CALL <JMP.&USER32.GetWindowTextLengthA> ; \GetWindowTextLengthA
004011AC MOV DWORD PTR DS:[4020E9],EAX ; \mette in EAX il risultato di GetWindowTextLenghta
004011B1 MOV ESI,EAX \Mette EAX in ESI
004011B3 CMP ESI,0C
\compara ESI con x0C(
004011B6 JNZ SHORT CRACKME2.004011D6 \se non è uguale salta fino alla finestra d’errore, se no vai alla finestra della psw esatta.
Quindi il CRACKME2 si può risolvere in 2modi:
1)Cambiano il jnz in je (in questo caso se la psw è i 12 caratteri va alla finestra di errore)
2)Inserendo qualsiasi psw di 12 caratteri
3 Parte)
Il crackme3 è simile a CRACKME2, solo che controlla la psw. OK, facciamo come prima, apriamo il crackme con l’Olly, vediamo tutte le call con tasto destro: “Search for/All intermodular calls”, apriamo il primo MessageBoxA e cerchiamo il RET. Vediamo qui due call: una già vista: GetWindowTextLenghtA, l’altra è nuova: GetWindowText
int GetWindowText(
HWND hWnd, // handle of window or control with text
LPTSTR lpString, // address of buffer for text
int nMaxCount // maximum number of characters to copy
);
GetWindowTextA fa caricare in memoria la stringa inserita. Ora mettiamo un breakpoint su 4011a1, cioè sulla call a GetWindowTextA, ora fate partire il programma:
004011A1 CALL <JMP.&USER32.GetWindowTextA> ; \GetWindowTextA: cioè prende la stringa inserita
004011A6 MOV EBX,crackme3.00402098
004011AB PUSH DWORD PTR DS:[40204C]
004011B1 CALL <JMP.&USER32.GetWindowTextLengthA> ; \GetWindowTextLengthA restituisce in EAX il numero di caratteri
004011B6 MOV ESI,EAX \sposta EAX in ESI
004011B8 CMP ESI,12 \compara ESI con x12 (
004011BB JNZ SHORT crackme3.004011FE \ salta se sbagliato
004011BD CMP BYTE PTR DS:[EBX],46 \compara 1° carattere con F(x46)
004011C0 JNZ SHORT crackme3.0040121C \salta se sbagliato
004011C2 CMP BYTE PTR DS:[EBX+1],69 \compara 2° car. con i (x69)
004011C6 JNZ SHORT crackme3.0040121C \salta se errato
004011C8 CMP BYTE PTR DS:[EBX+3],72 \compara 4° car. con r (x72)
004011CC JNZ SHORT crackme3.0040121C \salta se errato
004011CE CMP BYTE PTR DS:[EBX+4],65 \compara 5° car. con e (x 65)
004011D2 JNZ SHORT crackme3.0040121C \salta se errato
004011D4 CMP BYTE PTR DS:[EBX+6],57 \compara 7° car. con W (x57)
004011D8 JNZ SHORT crackme3.0040121C \salta se errato
004011DA CMP BYTE PTR DS:[EBX+7],6F \compara 8° car. con o (x6f)
004011DE JNZ SHORT crackme3.0040121C \salta se errato
004011E0 CMP BYTE PTR DS:[EBX+8],72 \compara 9° car. con r (x72)
004011E4 JNZ SHORT crackme3.0040121C \salta se errato
004011E6 CMP BYTE PTR DS:[EBX+A],78 \compara 11° car. con x (x78)
004011EA JNZ SHORT crackme3.0040121C \salta se errato
004011EC CMP BYTE PTR DS:[EBX+C],53 \compara 13° car. con S (x53)
004011F0 JNZ SHORT crackme3.0040121C \salta se errato)
004011F2 CMP BYTE PTR DS:[EBX+D],75 \compara 14° car. con u (x75)
004011F6 JNZ SHORT crackme3.0040121C \salta se errato
004011F8 CMP BYTE PTR DS:[EBX+10],78 \compara ‘16+1’° car. con x (x78)
004011FC JNZ SHORT crackme3.0040121C \salta se errato
Quindi la password ha 18 caratteri, dei quali 5 non vengono comparati, così procedendo la password può essere
“Fi-re-Wor-x-Su--x-“ che “Fi re Wor x Su x “
Pnluck
| Note finali |
Spero di essere abbastanza chiaro wul ciò da fare con Olly nella parte 2° e 3°, xkè ho spiegato il necessario nella 1° parte, volendo, potreste imparare meglio Olly con l’ottima guida di Bender0.
| Disclaimer |
Ringrazio Quequero,AndraGeddon, Bender0 e tutti gli altri che mi hanno aiutato nel forum e in #crack-it
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.