Manual Unpacking
for Newbies |
Data |
by
"Jumperplus" |
|
Febbraio 2003 |
UIC's Home
Page |
Published
by Quequero |
....
|
Dire che sei stato
esaustivo e' dir poco, grazie mille, il tutorial e' scorrevolissimo
oltre che visivamente pulito, bravo jumper
|
.... |
.... |
- Home
page se presente: http://jumperplus.cjb.net/
- E-mail: jumperplus@yahoo.it
|
.... |
Difficoltà |
(x)NewBies ( )Intermedio (
)Avanzato ( )Master |
|
Questo tutorial è rivolto principalmente ai newbies
ai quali cercherò di spiegare nel modo più semplice possibile la tecnica del
manual unpacking, facendo dei cenni sul formato PE, spiegando alcuni campi
modificabili tramite il PEditor e concludendo il tutorial con un esempio pratico
di decrypting.
Manual Unpacking for
Newbies
Written by Jumperplus
- Ultimamente i programmatori utilizzano sempre
più frequentemente i vari crypter/packer per proteggere i loro software in
modo da impedire che questi possano essere modificati, infatti se aprite con
un disassemblatore un eseguibile cryptato noterete che è praticamente
illeggibile, quindi per poterlo modificare dobbiamo prima
decryptarlo.
INDICE TUTORIAL:
-
Vai a Struttura dell'eseguibile
cryptato
-
Vai a Cenni sul formato PE e su alcuni campi modificabili dal PEditor
- Vai a Le
sezioni
-
Vai a La Import Table
-
Vai a Come modificare l'Import
Table
- Vai a Come trovare l'Original Entry Point
-
Vai a Dumping con icedump
-
Vai a Dumping con il PEditor
-
Vai a Esempio di decrypting/unpacking
(Petite 2.2)
- Softice 4.05
- Icedump
- PEditor 1.7
- HexEdit (o qualsiasi
altro editor esadecimale)
- W32Dasm 8.93 (non
indispensabile)
- Import REConstructor 1.4.2+
- Lo troverete allegato al tutorial
- Il programma che utilizzo come esempio di
decrypting non è altro che il notepad del mio Windows Me cryptato con Petite
2.2
STRUTTURA DELL’
ESEGUIBILE CRYPTATO:
PE
Header |
Sezione
1 |
Sezione
2 |
Sezione
n |
Loader |
Se provate
ad aprire con il PEditor un crypter noterete che tra le varie sezioni standard
comunemente inserite dal compilatore (.text, .data, .rsrc etc...) alcune avranno
dei nomi strani (generalmente si trovano dopo l'ultima sezione), queste sono
state aggiunte dal crypter e si chiamano "loader" e servono per decryptare
l'eseguibile in memoria in modo tale che possa essere eseguito in modo corretto.
Infatti il programma per poter funzionare parte l'esecuzione dalla sezione
loader per auto decryptarsi a runtime, una volta che il file è stato decryptato,
esce dalla sezione loader e salta all'entry point del programma originale (da
ora in poi: original entry point o "OEP"), andando esattamente sulla prima
sezione, ora pronto all'esecuzione. A questo punto avremo il programma
decryptato su ram e non dobbiamo far altro che farne una copia su hard disk,
questo procedimento si chiama "Dumping" e può essere fatto ad esempio da softice
utilizzando icedump oppure con il PEditor.
Esempio di crypter (petite
1.2):
Section |
Virtual Size |
Virtual Offset |
Raw Size |
Raw Offset |
Characteristics |
.text |
00008000 |
00001000 |
00005000 |
00001000 |
E0000020 |
.rdata |
00001000 |
00009000 |
00001000 |
00006000 |
40000040 |
.data |
00005000 |
0000A000 |
00000000 |
00000000 |
C0000040 |
.rsrc |
00009000
|
0000F000 |
00009000 |
00007000 |
40000040 |
.madmat |
0000D258 |
00018000 |
0000160C |
00010000 |
E2000060 |
Nell'esempio
che vedete sopra la sezione .madmat è il loader che servirà a decryptare
l'eseguibile in memoria.
Dalle varie
sezioni e dal nome del loader a volte si può capire quale crypter è stato
adoperato, la sezione ".madmat" viene aggiunta da petite 1.2, questo oltre a
essere un crypter è anche un packer ecco la differenza:
Crypter: crypta le sezioni di un eseguibile ma
non ne altera la grandezza
Packer: oltre a cryptare le sezioni ne
riduce anche la grandezza
CENNI SUL FORMATO PE E SU ALCUNI CAMPI MODIFICABILI DAL
PEDITOR:
Tra i tools
necessari per modificare gli eseguibili troviamo il PEditor e poichè dopo il
dumping l'eseguibile generalmente non funziona, questo ci tornerà utile per
mettere a posto un pò di cose. Per far questo però è fondamentale conoscere la
struttura del PE (Portable Executable, formato standard degli eseguibile della
piattaforma win32), ed i campi che il Peditor ci consente di modificare, di
seguito spiegherò solo i fondamentali prendendo come esempio il W32Dasm 8.93
(vorrei sottolineare che questo disassemblatore non è cryptato, non ho scelto un
programma cryptato in quanto al momento mi interessa solo spiegare come leggere
i vari campi del PEditor):
-
Entry point : indirizzo da cui il programma inizia l’esecuzione,
questo dopo il dumping andrà modificato in quanto l'eseguibile avrà ancora
l'entry point nella sezione loader
-
Image base : quasi sempre
400000 per gli eseguibili, indirizzo a partire dal quale viene messo il file
in memoria
-
Base of Code : quasi sempre 1000, la sezione di codice di un
eseguibile generalmente inizia all’indirizzo 401000 = Image Base + Base of
Code
-
Base of Data : come
sopra però per la sezione di dati, questo valore non è fisso ma
varia
-
Size of Image : indica al loader quanto spazio deve essere allocato
in memoria per il caricamento dell'eseguibile, questo valore è soggetto ad
allineamento (ne parlerò meglio più avanti)
-
Size of
Headers : indica la dimensione degli headers, se questa è uguale a 1000
avremo l'allineamento perfetto e quindi Virtual Offset = Raw
Offset
-
Section
Alignment : indica il valore dell'allineamento delle sezioni in memoria,
le sezioni vengono mappate in memoria a multipli di questo valore (quasi
sempre 1000)
-
File
Alignment : indica il valore dell'allineamento delle sezioni nel file
fisico, nel file le sezioni iniziano a multipli di questo valore (di solito
200 ma può variare)
E'
importante non far confusione fra offset RVA e VA, in softice infatti tutti gli
offset sono scritti in VA mentre nel PEditor in RVA:
-
RVA (Relative Virtual
Address): sono tutti gli indirizzi del tipo 7000, 3B34C
ecc...
-
VA (Virtual
Address): sono tutti gli indirizzi che
troviamo in memoria ad esempio 407000 43b34C ecc...
LE
SEZIONI:
Sezioni del
W32Dasm 8.93
-
Section
: qui troviamo i nome della sezione, ".text" o ".code" è la sezione che
contiene il codice, ".data" (o simile) contiene i dati, ".rsrc" contiene le
risorse (icone, puntatori) ecc...
-
Virtual
Size : dimensione reale della sezione in memoria, si solito non rispetta
alcun allineamento
-
Virtual
Offset : indirizzo a partire dal quale viene mappata la sezione, rispetta
un allineamento che quasi sempre è 1000
-
Raw
Size : dimensione della sezione su file, non è una dimensione reale poiché
rispetta un allineamento che di solito è 200
-
Raw
Offset : indirizzo a partire dal quale si trova la sezione sul file, il
suo valore sarà sempre multiplo di un valore di allineamento (di solito
200)
-
Characteristics : dà notizie sul contenuto della sezione. Nota,
se dopo il dumping non riuscite a disassemblare il file probabilmente si deve
modificare il campo "Characteristics" settandolo a E0000020, per far questo
andate in "sections" e cliccate con il tasto destro del mouse sopra la prima
sezione (.text o .code) e scegliete l'opzione
E0000020
Le sezioni
degli
eseguibili devono rispettare dei valori di allineamento, sia in memoria che su
file, infatti queste iniziano e finiscono sempre ad un indirizzo che è un
multiplo del valore di allineamento, questo valore è dato da
"Section Alignment" per gli indirizzi in memoria e da "File Alignment" per
gli indirizzi su file. Un altro tipo di allineamento, diverso da quello tra le
sezioni, è l'allineamento nel file, questo si avrà quando VirtualOffset =
RawOffset. Una cosa che spesso faremo nel tutorial sarà quella di cercare un
determinato offset nel file partendo da un RVA o VA, se il file è allineato
avremo:
VA = Offset
Fisico e RVA - Image base = Offset Fisico
diversamente
dobbiamo convertirli con l' FLC (File Location
Calculator) del PEditor.
LA IMPORT
TABLE:
Una delle
operazione più fastidiose che dobbiamo fare per far funzionare l'eseguibile
dumpato è senza dubbio ricostruire la Import Table (IT), di seguito spiegherò i
campi relativi alla IT:
IMPORT TABLE
del W32Dasm 8.93:
Esistono due
differenti tipi di struttura della IT, questa varia in funzione del compilatore
adoperato:
-
OriginalFirstThunk
TimeDateStamp ForwarderChain Name FirstThunk
-
TimeDateStamp ForwarderChain Name
FirstThunk
Come potete
vedere nella seconda struttura non abbiamo gli OriginalFirstThunk, potrete
riconoscere questa struttura dalla prima dword, in questo caso infatti questa
sarà settata a 0.
-
OriginalFirstThunk: punta alla struttura degli indirizzi dei
nomi delle funzioni importate. Possiamo schematizzare
come
segue:
OriginalFirstThunk (OFFSET)
----> OFFSET1 ----> NOME FUNZIONE1
OFFSET2 ----> NOME FUNZIONE2
OFFSET3 ----> NOME FUNZIONE3
Se apriamo il W32Dasm 8.93 con
un editor esadecimale e guardiamo all'offset 000D408C non
troveremo
la struttura degli indirizzi
che puntano ai nomi delle funzioni importate in quanto il file non è
allineato
(vi ricordo che per sapere
se l'eseguibile è allineamento basta guardare tra le sezioni, solo se
VirtualOffset =
RawOffset si ha l'allineamento), quindi dobbiamo
convertire con l'FLC l'offset 000D408C da
RVA a Offset Fisico:
(RVA) 000D408C = (Offset Fisico) 000D1C8C,
adesso cercando a questo indirizzo
troveremo:
48 20 0D
00
5A 20 0D 00 68 20
0D 00 7C 20 0D 00 88 20 0D 00
9E 20 0D 00 AE 20
0D 00 ECC...........
tutti questi byte non sono altro che indirizzi che puntano
ai nomi delle funzioni importate, quindi
solita
conversione: (RVA) 000D2048 = (Offset Fisico) 000D0448, a questo indirizzo
troveremo:
000D0448 00 00 47 65 74
50 72 6F 63 41 64 64 72 65 73 73 00 ..GetProcAddress.
dove i primi due byte sono la
word Hint (0000), dopo avremo il nome della funzione
ed infine avremo lo 0
per terminare. Come potete
notare gli offset trovati sono identici a quelli presenti sul PEditor,
(li ho colorati in blu) ecco
spigata anche l'area "RVA OFFSET HINT
NAME".
-
TimeDateStamp: dword con data e ora di creazione della IT,
dopo il dumping va sempre azzerata insieme a
ForwarderChain.
-
ForwarderChain: questo campo va sempre azzerato in quanto
dopo il dumping la IT non è più la stessa, il PE Loader infatti avrà
sovrascritto la IAT con i valori degli entry point delle funzioni importate e
avrà assegnato un valore a ForwarderChain. Se questo non viene azzerato il
file funzionerà solo sul vostro pc in quanto il Pe Loader non andrà più a
ricalcolare gli entry point delle funzioni, nel caso in cui questi non fossero
più gli stessi, ma utilizzerà sempre quelli calcolati in precedenza, ne
parlerò meglio più avanti quando parlerò della
IAT.
-
Name:
questa punta al nome della dll importata:
(RVA)
000D2000 = (offset fisico) 000D0400 cercando questo indirizzo
troveremo:
000D0400 4B 45 52 4E 45 4C 33 32 2E 64 6C 6C
00 KERNEL32.DLL.
l'ultimo byte sarà sempre zero
per terminare
-
FirstThunk: chiamata anche IAT (Import Address Table),
punta alla struttura degli indirizzi degli entry point delle funzioni
importate per ogni dll:
FirstThunk (OFFSET)
----> ENTRY POINT FUNZIONE 1
ENTRY POINT FUNZIONE 2
ENTRY POINT FUNZIONE 3
la solita conversione:
(RVA) 000D45E4 = (Offset Fisico) 000D21E4, a questo indirizzo
troveremo:
48 20 0D 00 5A 20 0D 00 68 20 0D
00
7C 20 0D 00 88 20
0D 00 9E 20 0D 00 ECC...........
Nella IAT possiamo trovare o
gli indirizzi degli entry point delle funzioni importate oppure la copia degli
OriginalFirstThunk. In questo
caso abbiamo la copia degli OriginalFirstThunk infatti:
(RVA) 000D2048 = (Offset
Fisico) 000D0448 che non è altro che l'OriginalFirstThunk trovato
prima.
Si deve a
questo punto fare una precisazione importante: non sempre le dll caricano in
memoria il loro codice allo stesso indirizzo, nello stesso pc generalmente si,
ma in pc diversi non è detto, quindi se il PE Loader trova nella IAT un
indirizzo sbagliato se lo ricalcola in base agli OriginalFirstThunk. Stessa cosa
accade nel
W32dasm dove non abbiamo gli entry point, il PE Loader li calcolerà in base
agli OriginalFirstThunk. Naturalmente nella seconda struttura, dove questi
sono settati a zero, dobbiamo avere per forza nella IAT la copia degli
OriginalFirstThunk in quanto se una dll decidesse di caricare in memoria il suo
codice ad un altro indirizzo avremmo gli entry point sbagliati ed il PE Loader
non potrebbe ricalcolarli in nessun modo. Un problema analogo nasce sempre in
presenza della seconda struttura, dopo il dumping la IAT viene sempre
sovrascritta con i valori degli entry point delle funzioni importate,
quindi se questi dovessero cambiare il PE Loader non potrebbe più
ricalcolarli visto che non abbiamo gli OriginalFirstThunk e
non abbiamo neanche una sua copia nella IAT.
Seconda
struttura:
FirstThunk
(copia OriginalFirstThunk) (OFFSET) ----> OFFSET1
----> NOME FUNZIONE1
OFFSET2 ----> NOME
FUNZIONE2
OFFSET3 ----> NOME
FUNZIONE3
Ho segnato in rosso gli offset che vengono sempre sovrascritti dopo il
dumping. Come potete notare i nomi delle funzioni sono ancora presenti nel
file
(non sono presenti solo se il crypter li ha cancellati) di
conseguenza basterebbe modificare l'array in modo tale da farlo
ripuntare sui nomi delle funzioni. Questa modifica
potete farla o manualmente con un editor esadecimale (più avanti vedremo come
modificare la IT) o più semplicemente utilizzando il rebuilder automatico del
Peditor. Quello che vi ho appena spiegato è ciò che avviene se provate a dumpare
un file non cryptato dove gli OriginalFirstThunk sono
settati a zero (naturalmente questo serve solo a scopo didattico), con
i crypter però non è detto che sia così semplice, questi infatti spesso distruggono
la IT intenzionalmente, alcuni ad esempio modificano i nomi di alcune funzioni e
li sovrascrivono con i nomi di altre, in questo modo
la IT sembrerà perfettamente funzionante quando in realtà non lo è, altri
cancellano completamente i nomi delle funzioni, altri ancora cancellano il campo
"name" che punta al nome della dll importata.... insomma i crypter potrebbero
distruggere la IT in mille modi diversi. Per ovviare a questo dobbiamo cercare
nel loader le istruzioni che alterano la IT e nopparle oppure dobbiamo
farci aiutare da un IAT rebuilder (ad esempio revirgin o Import REConstructor)
per ricostruire la IAT, più avanti vedremo come fare.
COME MODIFICARE L' IMPORT
TABLE:
Per
modificare la IT di un eseguibile dobbiamo prima trovare la
sua esatta posizione nel file e successivamente intervenire con un editor
esadecimale (il Peditor
non ci permette di modificarla). Se ad esempio volessimo
modificare la IT del nostro buon vecchio W32Dasm dovremmo operare nel seguente
modo: Apriamo
il
Peditor e guardando in "Directory" e nella seconda riga possiamo leggere
subito l'offset della IT e la sua dimensione:
RVA |
SIZE |
000D4000 |
00000B3C |
quindi
dobbiamo convertirlo da RVA in offset fisico con l' FLC, ottenendo come
risultato l'offset 000D1C00.
Se andiamo a
cercare con un HexEditor questo indirizzo troveremo i seguenti
byte:
8C 40 0D 00 00 00 00 00 00 00 00
00 00 20 0D 00
E4 45 0D 00 F0 41 0D
00 00 00 00 00 00 00 00
00
0D 20 0D 00 48 47 0D 00 ETC..........
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00
00
00 00 00 00
(I
bytes sono colorati alternatamene a gruppi di 5 per distinguere i
descrittori)
Le ultime 5
dworld sono sempre uguali a 0 ed indicano la fine della import
table.
Come potete
notare abbiamo trovato gli stessi indirizzi che avevamo trovato prima con il
PEditor ma invertiti, quindi se con il PEditor abbiamo OriginalFirstThunk
000D408C nell'editor esadecimale avremo i byte 8C400D00, è importante ricordarsi
di questo tutte le volte che dobbiamo modificare la IT scrivendo quindi
in ogni dword i singoli byte
invertiti.
COME TROVARE L'ORIGINAL ENTRY
POINT:
COMANDO BPR:
Sintassi del
comando BPR di softice:
BPR
StartAddress EndAddress [R|W|RW|T|TW] [IF espressione] [DO
Sice-Action]
Per trovare
l'OEP ci viene in aiuto il comando bpr di softice (nota: non esiste nella
versione di softice per NT), questo non fa altro che settare un break point di
lettura/scrittura in un blocco di memoria compreso tra "StartAddress" ed
"EndAddress" e poiché sappiamo che l'OEP si trova nella prima sezione dovrete
settare il bpr proprio in quest'area (nota: non è detto
che al primo pop di softice hai trovato l'OEP). In genere i
crypter/packer per saltare dal loader all'OEP usano il classico jmp eax, quindi
se il crypter non vi dovesse consentire di settare il BPR un alternativa sarebbe
steppare il loader e non appena trovate il jmp eax che vi porta sulla prima
sezione dumpate (nota: nessuno vieta che possiate finire all'oep anche tramite
un ret o qualsiasi altra istruzione).
Per sapere
in quale sezione vi trovate basterà guardare la linea sotto la CodeWindow di
softice, finché sarete nel loader troverete:
nome
processo.nome loader
quando
sarete nella sezione del codice avrete:
nome
processo.nome prima sezione (.text o .code)
A volte le
API "GetModuleHandleA" e "GetVersion" ci vengono in aiuto in quanto si trovano
spesso poche istruzioni dopo l'OEP.
COMANDO TRACEX:
Tracex è un
comando di icedump simile al bpr di softice utile anche questo per trovare
l'OEP, ecco la sua sintassi:
/TRACEX
<low EIP> <high EIP>
ad
esempio:
/TRACEX
401000 409000
DUMPING CON
ICEDUMP:
Di seguito
spiegherò passo passo tutte le operazioni da seguire per decryptare un
eseguibile:
Esempio di
crypter (petite 1.2)
Section |
Virtual Size |
Virtual Offset |
Raw Size |
Raw Offset |
Characteristics |
.text |
00008000 |
00001000 |
00005000 |
00001000 |
E0000020 |
.rdata |
00001000 |
00009000 |
00001000 |
00006000 |
40000040 |
.data |
00005000 |
0000A000 |
00000000 |
00000000 |
C0000040 |
.rsrc |
00009000
|
0000F000 |
00009000 |
00007000 |
40000040 |
.madmat |
0000D258 |
00018000 |
0000160C |
00010000 |
E2000060 |
-
Caricate IceDump
(per visualizzare i comandi digitate in softice /)
-
Aprite con il
PEditor l’eseguibile e su “section” appuntate il primo, il secondo e l’ultimo
“Virtual offset” cioè 1000, 9000 e 18000 e l’ultimo “Virtual size” cioè D258
(è possibile visualizzarle anche in softice scrivendo “map32 nome
file”)
-
Per trovare
l’OEP scrivete in softice:
bpr 401000
409000 r if eip < 409000 (la sua
sintassi: bpr limit1 limit2 r if eip
< limit2)
(non è detto che
al primo pop di softice avete trovato l'OEP)
-
Arrivati all’OEP
sommate l’ultimo “virtual offset” con l’ultimo “Virtual size” tenendo presente
che le sezioni hanno quasi sempre l'allineamento a 1000 (questo valore è dato
da Section Alignment), quindi dovete considerare il multiplo di 1000 superiore
più vicino a “Virtualsize”. Il multiplo di 1000 superiore più vicino a
D258 è E000 quindi 18000 + E000 =
26000 (che è il valore di "Size of Image") in softice
scrivete:
/dump 400000 26000 c:\dump.exe (la sua sintassi: /dump
indirizzo lunghezza file_disco)
dovete dumpare da 400000 (image base) perché si deve includere anche il
“PE header”
-
Se l’eseguibile non ha l’icona devete “riallinearlo”, per far questo
con il PEditor andate nella “Section Table”, cliccate con il tasto destro del
mouse e scegliete “DumpFixer”
-
Con il PEditor correggete l’entry
point con quello trovato (va scritto in
RVA)
-
Aprite con il peditor il file e andando in "rebuilder" selezionate
l'opzione "rebuild Import
Table" e cliccate su
"Do", se
l'eseguibile funziona è bene controllare se i valori di TimeDateStamp
e ForwarderChain siano stati azzerati dal rebuilder in modo da permettere al
Pe Loader di ricalcolare gli entry point delle funzioni nel caso in cui questi
non siano più gli stessi. Un altra cosa
che dovete controllare è se compaiono i nomi delle funzioni importate, se così
non fosse l'eseguibile potrebbe funzionare solo sul vostro PC e poiché il
rebuilder non è riuscito a far ripuntare la IAT sui nomi delle funzioni
importate probabilmente il crypter ha alterato intenzionalmente la
IT, più avanti vedremo come risolvere
questo inconveniente.
DUMPING CON IL
PEDITOR:
In
alternativa al dumping con icedump potete dumpare con il
Peditor:
-
Arrivati
all'OEP appuntate l'opcode della prima istruzione, in particolare ci
interessano i primi 2 byte, per visualizzare gli opcode scrivete in softice:
code on
-
Modificate
la prima istruzione con jmp eax, per far questo scrivete in
softice:
a
(invio)
jmp
eax (invio 2 volte) (il suo opcode è
FFE0)
-
A questo
punto uscite da softice con F5 e andate a cercare nel tasks viewer del PEditor
il processo, quindi cliccandogli con tasto destro del mouse sopra scegliete
dump (full). Abbiamo sostituito l'istruzione all'OEP con jmp eax in modo tale
che il programma non potesse continuare l'esecuzione rimanendo alluppato in
memoria, se non avessimo fatto in questo modo l'eseguibile continuando
l'esecuzione avrebbe modificato la sezione .data e dumpando adesso avremmo
ottenuto un file inutilizzabile.
-
Adesso
dovete rimettere al suo posto con un editor esadecimale l'opcode originale
all'OEP.
ESEMPIO DI
DECRYPTING/UNPACKING (PETITE 2.2):
In questa
parte del tutorial spiegherò come decryptare petite 2.2 (il notepad cryptato è
allegato al tutorial).
Notepad
petite_2.2
Section |
Virtual Size |
Virtual Offset |
Raw Size |
Raw Offset |
Characteristics |
|
00006000 |
00001000 |
00002C00 |
00000800 |
E0000060 |
.petite |
00006000 |
00007000 |
00001E71 |
00003400 |
C0000040 |
|
00001000 |
0000D000 |
00000000 |
00000000 |
C2000040 |
|
000003CA |
0000E000 |
00000400 |
00000400 |
E2000060 |
Come potete
notare le sezioni sono tutte senza nome tranne una. L'entry point è all'offset
40E042 quindi il loader che decrypterà l'eseguibile è nell'ultima sezione.
Vorrei farvi notare una cosa, petite non è solo un crypter ma è anche un packer
(compressore), tutte le volte infatti che Raw Size < Virtual Size e questo
non è dovuto ad un normale allineamento delle sezioni allora si tratta di un
packer, nel nostro caso il valore di Virtual Size della prima sezione è grande
più del doppio del corrispondente Raw Size. Fatta questa brevissima analisi,
dobbiamo trovare l'OEP, scrivete in softice:
bpr 400000
407000 r if eip < 407000
Se adesso
premete F5 si bloccherà tutto e sarete costretti a resettare il pc, questo
accade perché petite si accorge che è stato settato il bpr e manda tutto in
crash. Un'altra alternativa sarebbe steppare tutto il loader in cerca del jmp
eax ma con petite vi perdereste sicuramente nei meandri del codice. L'unica
soluzione valida è trovare un'api sulla quale agganciarvi in modo da superare
una buona parte del codice, così facendo non sarete costretti a
steppare tutto il loader, io vi consiglio LoadLibratyA (va bene anche
per molti altri crypter). Su quest'api softice poppa 6 volte quindi settategli un
break point e dopo il 6° pop iniziate a steppare e non molte istruzioni dopo
troverete 40E042 jmp 4010CC, dove 4010cc sarà l'OEP in quanto si trova sulla
prima sezione. Bene, arrivati a questo punto potete dumpare scrivendo in
softice:
/dump 400000 F000 c:\dump.exe
Adesso riallineate l'eseguibile e
correggere l'entry point con quello appena trovato. Se andate a guardare la IT
noterete subito che non ci sono i nomi delle funzioni importate, la causa è
senza dubbio il crypter che altera intenzionalmente la IT (in questo caso il
rebuilder automatico del PEditor non ci verrà in aiuto), potete a questo punto
operare in due modi:
-
Cercate nel loader le istruzioni che alterano la IT e le
dumpate
-
Vi fate
aiutare da un IAT rebuilder per ricostruire la
IAT
Io spiegherò
solo il secondo metodo utilizzando Import
REConstructor:
-
Eseguite il notepad
cryptato e cercate nel tasks viewer il suo
processo
-
Scrivete nel campo "OEP"
l'original entry point in RVA
-
Cliccate su
"IAT
AutoSearch" in modo tale da consentire al programma di inserire nell'apposito
campo l'indirizzo della IAT e la sua grandezza
-
Cliccate
su "Get Imports"
-
Import
REConstructor non riuscirà a risolvere alcune funzioni, se
cliccate però su "Auto Trace" nel log comparirà la scritta: "Congratulations!
There is no more invalid pointer, now the questions is: Will it work? :-)",
bene questo vuol dire che il tool ha risolto tutte le
funzioni
-
Cliccate
su "Fix Dump" e selezionate il file dumpato, adesso l'eseguibile
funziona!!!
Jumperplus
Un saluto a Quequero, a tutta la UIC e alla ML e ...
alla prossima!!!
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 ;))))