A:link { TEXT-DECORATION: underline } A:visited {TEXT-DECORATION: underline } A:active { COLOR: red;TEXT-DECORATION: underline } A:hover { COLOR: #8080ff;TEXT-DECORATION: underline }
|
Mettiamo le mani sul PE e sulla IAT di un programma!!!
|
Data | by "Gz3r" | |
24/04/2001 | UIC's Home Page | Published by Quequero |
| Gz3r
il form è da picchiarti :) ma il resto l'hai spiegato bene :))))) | |
.... | - Home page se presente:
http://gz3r.cjb.net/
- E-mail: gz3r@usa.net
- Nick, UIN, canale IRC/EFnet frequentato
| .... |
Difficoltà | (X)NewBies ( )Intermedio ( )Avanzato ( )Master | |
Andiamo a mettere le mani su uncrackme fatto dal bravo AndreaGeddon per imparare il formato PEche poi è il formato che Winsozzume usa per gli eseguibili dellasua piattaforma.
- Dumpando Nono.exe
- (Mettiamo le mani sul PE e sulla IAT di un programma)
Written by Gz3r
- Ho finito da mezz'ora di fare sto "tute" ma non riesco a pensare ad una ca... di introduzione..AIUTOOOO!!!
- Softice
- Adump
- Ultraedit (oppure un qualsiasi altro editor esadecimale)
- PEditor
- http://quequero.cjb.net
- Innanzitutto eseguiamo il programma per vedere cosa fa esattamente: ci sono 3 pulsanti, il pulsante ABOUT (immaginate a cosa serve...:) ) il pulsante OK che chiude il prog ed il pulsante REGISTER che, se premiamo, dirà naturalmente:"AZZ!!!NON SEI REGISTRATO".Dando un occhiata sommaria con il Softice, mettendo un bel bpx MessageBoxA sulla suddetta Messagebox, si può vedere che basta risolvere un jnz a tempo di esecuzione per arrivare alla finestra delle congratulazioni. Non sto ad approfondire questa parte dato che il target non è questo. La cosa che si può osservare è che se volete andare a variare quel jnz ad esempio in jz aprendo il programma con l'editor esadecimale, scoprirete che a quell'indirizzo non trovate il cod-op dell'istruzione.....quindi la modifica non può essere resa permanente AZZ!!! come mai? perchè il programma in questione è stato criptato.
- Questo cosa vuol dire? Vuol dire che una parte del programma (ed esattamente la prima ad essere eseguita) si preoccuperà di decriptare il programma, e caricarlo in memoria.Quindi in memoria si troverà una copia "PULITA" del programma che noi dovremo "agguantare" (con le maniere gentili che sempre ci hanno contraddistinto...:) ) e copiare sul nostro HD.Beh...per capire meglio la cosa apriamo con il PEditor il programma e vediamo le seguenti sezioni:
Section Virtual Size Virtual Offset Raw Size Raw Offset Characteristics
.text 00000B12 00001000 00000C00 00000400 E0000020
.rdata 00000448 00002000 00000600 00001000 E0000020
.data 00000194 00003000 00000200 00001600 E0000020
.idata 0000060C 00004000 00000800 00001800 E0000020
.rsrc 000016AC 00005000 00001800 00002000 E0000020
.Geddone! 00003000 00007000 00003000 00003800 E0000020
- Osserviamo subito che la sesta sezione è un po strana....ed infatti ha il nome Geddone! se le sezioni hanno un nome un po strano, di solito un packer/cripter ha modificato il programma (ad ex. UPX1 e UPX2, oppure SHRINK, ecc...).Dico "di solito" perchè, i nomi delle sezioni possono essere anche modificate da noi usando per ex. il PEditor, oppure variandole direttamente con un editor esadecimale.Come abbiamo detto poc'anzi,probabilmente la sezione Geddone! conterrà le istruzioni che permetteranno di decriptare le altre sezioni, caricando in memoria una copia "in chiare lettere" del programma.Potremmo utilizzare direttamente il PEditor per fare un dumping del programma, risparmiandoci la fatica di allineare le sezioni, ma, fare le cose a mano, permette di capire molto di più.Apriamo Adump, che mi permette di riservare 1 Mega di memoria RAM per farci quello che voglio.Il processo verrà "DUMPATO", dentro questo spazio, in pratica, anche se spiegato con termini impropri,il file verrà copiato dalla zona di memoria dove è in esecuzione dentro questo spazio.Esisteranno quindi ad un certo punto, DUE copie dello stesso programma sulla RAM:La prima copia è quella del programma in esecuzione la seconda, è la copia che abbiamo fatto noi all'interno dello spazio riservatoci dall'Adump.Ma andiamo alla pratica.All'apertura di Adump battete il comando R. Avrete quindi una schermata simile a questa:
:R
Internal variables
STARTOFFS:0x83CDE000 (questo è ilmio...il vostro sarà probabilmente diverso)
ENDOFFS:0x83DD2240
LIMIT:0xF4240 (1000000)
CUROFFS:0x83CDE000
MAPFN:C:\WINDOWS\TEMP\ADump.log
MAPFSIZE:0xF4240
ANFILTER:A..Z,a..z,0..9
- Il valore STARTOFFS è l'indirizzo a partire dal quale possiamo memorizzare fino ad 1 Mega per i nostri scopi, ed è quello che ci interessa maggiormente.ATTENZIONE! non chiudete Adump, perchè altrimenti la memoria non sarà più riservata e dovremo ricominciare tutto da capo.Possiamo ora utilizzare una bella funzione che ci offre il PEditor:break'n enter che permette di sostituire all'entry point del progr. il codice esadecimale CC (int 3) che permetterà a Softice di brekkare nell'entry point del programma, anzi in quello del cripter, per essere precisi, tutto questo senza mettere mano all'editor esadecimale.Quindi schiacciate break'n enter e poi RUN....noooo! prima aprite Sice, mettete un bel BPINT 03 , poi chiudete Sice ed ora RUN.Softice poppa, e vi dice di scrivere l'istruzione EB EIP 60,(una ficata...ve lo dice lui..grazie all'intervento di PEditor) che serve a sostituire il codice di int 03 (CC) con il codice di pushad (60) che era l'istruzione preesistente.Troviamo quindi queste istruzioni:
-
-
-
- 00407001 pushad <----CODICE APPENA SOSTITUITO IN SICE (ENTRY POINT DEL CRIPTER)
00407002 call 00407007
00407007 pop ebp
00407008 sub ebp, 7
0040700B mov eax, [ebp+148h]
00407011 mov ebx, [ebp+158h] - 00407017 add eax, ebx
00407019 push 0
0040701B call dword ptr [eax]
0040701D mov [ebp+1B0h], eax
00407023 mov eax, [ebp+15Ch]
00407029 mov ecx, [ebp+160h]
0040702F mov ebx, [ebp+158h]
00407035 add eax, ebx
00407037 dec ecx
00407038 mov bl, [eax+ecx]
0040703B not bl
0040703D xor bl, 37h
00407040 rol bl, 3
00407043 mov [eax+ecx], bl
00407046 cmp ecx, 0
00407049 jnz 407037
0040704B mov eax, [ebp+164h]
00407051 mov ecx, [ebp+168h]
00407057 mov ebx, [ebp+158h]
0040705D add eax, ebx
0040705F dec ecx
00407060 mov bl, [eax+ecx]
00407063 not bl
00407065 xor bl, 58h
00407068 rol bl, 5
0040706B mov [eax+ecx], bl
0040706E cmp ecx, 0
00407071 jnz 40705F
00407073 mov eax, [ebp+14Ch]
00407079 add eax, [ebp+158h]
0040707F lea ebx, [ebp+1A3h]
00407085 push ebx
00407086 call dword ptr [eax]
00407088 mov edi, eax
0040708A mov ebx, [ebp+150h]
00407090 add ebx, [ebp+158h]
00407096 mov ecx, [ebp+13Ch]
0040709C add ecx, [ebp+158h]
004070A2 add ecx, 2
004070A5 push ecx
004070A6 push edi
004070A7 mov esi, ebx
004070A9 call dword ptr [ebx]
004070AB mov ebx, [ebp+148h]
004070B1 add ebx, [ebp+158h]
004070B7 mov [ebx], eax
004070B9 mov ecx, [ebp+140h]
004070BF add ecx, [ebp+158h]
004070C5 add ecx, 2
004070C8 push ecx
004070C9 push edi
004070CA call dword ptr [esi]
004070CC mov ebx, [ebp+14Ch]
004070D2 add ebx, [ebp+158h]
004070D8 mov [ebx], eax
004070DA mov ecx, [ebp+144h]
004070E0 add ecx, [ebp+158h]
004070E6 add ecx, 2
004070E9 push ecx
004070EA push edi
004070EB call dword ptr [esi]
004070ED mov ebx, [ebp+150h]
004070F3 add ebx, [ebp+158h]
004070F9 mov [ebx], eax
004070FB mov ebx, [ebp+1B0h]
00407101 mov eax, [ebx+3Ch]
00407104 add ebx, eax
00407106 mov eax, [ebx+80h]
0040710C add eax, [ebp+158h]
00407112 mov ebx, eax
00407114 mov dword ptr [ebx], 0
0040711A mov dword ptr [ebx+0Ch], 0
00407121 mov dword ptr [ebx+8], 0
00407128 mov eax, [ebp+154h]
0040712E mov ebx, [ebp+158h]
00407134 add eax, ebx
00407136 jmp eax <----SALTO ALL'ENTRY POINT REALE DEL PROGRAMMA CHE E' ALL'INDIRIZZO 4017D0
- Questo è il corpo del cripter, dopodichè si salta all entry point del programma vero e proprio.Noi dobbiamo arrivare fino all'entry point originale (anche qualche istruzione dopo..non c'è problema).Quando siamo arrivati il programma è stado decriptato, quindi abbiamo una copia pulita in memoria.Facciamo quindi un:
- MAP32 NONO
- che ci fa rivedere le sezioni come sopra.Noi dovremo dumpare dall' RVA 1000(Virtual offset della sezione.text) al 7000(Virtual offset della sezione.Geddone!) + 3000 (che è la Vsize dell'ultima sezione Geddone!)+1000 che è il Base of Code, quindi in tutto 7000+3000=A000 bites.prima però bisogna vedere se le pagine del prog.sono tutte presenti in memoria: quindi digitiamo
- page 400000 L A
- dove A è calcolato dividendo A000h (grandezza del file) per FFFh (grandezza di una pagina) Le pagine che risultano NON PRESENTI (hanno una NP davanti ) possono essere richiamate in memoria con il comando PAGEIN. Digitiamo sempre in sice il comando:
- M400000 L 1A000 83CDE000.
- Questo copierà nella memoria riservataci da Adump il processo.Dobbiamo ora copiare dalla RAM al nostro disco il file, quindi, chiudiamo Sice e sulla riga comando di adump (che avete lasciato aperto veroooooo?) scrivete:
- w c:\dmp.exe A000 83CDE000
- ed avremo quindi il nostro programma sul disco c(finalmente!!).Il bello inizia adesso però.infatti se voi osservate, nel file dumpato l'icona non c'è più, e comunque, nemmeno il programma funziona.Questo perchè le sezioni sono disallineate.in pratica,essendo il file dmp.exe salvato secondo il section alignment che è 1000h anzichè 200h che è il file alignment è logico che gli offset all'interno delle sezioni risulta spostato.in questo caso, bisogna utilizzare il Procdump oppure il PEditor che utilizza il comando DUMPFIXER che allinea automaticamente il VSIZE con il PSIZE e l'RVA con l'OFFSET.Dopodichè l'icona ritornerà visibile dato che tutti i riferimenti alla Resource Table saranno corretti.Ma il programma non funziona ancora..porc....!Confrontiamo la Import table prima del dump:
DllName OriginalFirstTk TimeDateStmp FrwrderChain Name FirstThunk
MFC42.dll 00004074 00000000 00000000 0000442C 00004258
MSVCRT.dll 000041D8 00000000 00000000 00004462 000043BC
KERNEL32.dll 00004064 00000000 00000000 00004560 00004248
USER32.dll 00004220 00000000 00000000 000045F4 00004404
E dopo il dump:
DllName OriginalFirstTk TimeDateStmp FrwrderChain Name FirstThunk
MZ| 00000000 36F80F55 00000000 00000000 00004258
MSVCRT.dll 000041D8 362CB4B2 78000000 00004462 000043BC
KERNEL32.dll 00004064 3546ABB0 BFF70000 00004560 00004248
USER32.dll 00004220 356E38A3 BFF50000 000045F4 00004404
-
- Vedete qualcosa di strano?intanto non c'è più la MFC42.dll, ma al suo posto una MZ| che non so cosa sia...poi i campi TimeDateStmp e ForwarderChain sono sporchi (questo perchè il file è stato dumpato dalla memoria dove quei valori vengono riempiti a runtime) e nella prima dll dal nome sconosciuto i campi OriginalFirstThunk e Name sono a zero.quindi la IT è stata manomessa.La cosa da fare è quella di ricopiare i valori dell' OriginalFirstThunk e Name della prima dll (in maniera che ritorni ad essere puntata la MFC42.dll)ed azzerare i valori di TimeDateStamp e ForwarderChain per tutte le dll in maniera che il programma vada a ricalcolare ad ogni esecuzione i FirstThunk, utilizzando gli OriginalFirstThunk, altrimenti il programma funzionerebbe solamente sul vostro computer dato che il programma userebbe gli entry point alle funzioni delle dll dumpati dalla memoria che per il vostro computer vanno bene,ma per un'altro quasi sicuramente no....bissognerebbe che tutte le dll fossero mappate agli stessi indirizzi....una cosa alquanto improbabile!!!:-).Apriamo quindi l'editor esadecimale ed andiamo all'indirizzo RVA 4000(inizio della IT,offset 4000 nell'editor esadecimale) dove inizia la IT e dove troveremo i valori da variare. Ah dimenticavo...non serve utilizzare in questo caso un offset calculator o la funzione FLC di PEditor, perchè quando i programnmi vengono dumpati, l'allineamento è perfetto(tutto viene allineato secondo il section alignment, compreso il size of Headers).Ora clicchiamo sul prog...ancora non funziona.L'ultima cosa da mettere a posto è l'entry point del programma...infatti, se lasciamo l'entry point del prg originale, viene rieseguito il decripting, ma sul codice corretto, quindi il programma dumpato con le istruzioni corrette, viene caricato in memoria di nuovo scombussolato!!!Andiamo quindi con il PEditor nella sezione ENTRY POINT e sostituiamo al valore preesistente il valore 17D0 corrispondente all'EntryPoint reale del programma.Ora il programma funzionerà perfettamente.adesso si può andare finalmente a variare quel famoso jnz in maniera che compaia la MsgBox di complimenti.....ma non era questo l'importante.Sono stato forse più veloce sul finale ma questa pagina la ho scritta in 2 orette tutta d'un fiato....spero di essere stato sufficientemente capace di esprimermi con chiarezza e di non essermi scordato qualcosa e spero di capire come mai quando ricopio il form e ci scrivo le mie cazzate lo sfondo diventa bianco...Que...bisogna forse craccarlo o reversarlo??????.CIAUUUUUUUUUZ A TODOS!!!!
- Gz3r
Un ringraziamento a tutti
coloro che, direttamente o indirettamente, si interessano a questa nobiledisciplina.
Questo è un crackme per cuinon sto facendo perdere soldi a nessuno!!!E comunque questitutorials vengono fatti per accrescere il bagaglio culturale ditutti quelli a cui interessa.Non vi interessa accrescere ilvostro bagaglio culturale?Liberi di non leggere!! Noi reversiamoal solo scopo informativo e di miglioramento del linguaggioAssembly.Chiaro?