13
Alla scoperta di lARP64Pro Sommario Introduzione .............................................................................................................................................................1 lARP64 Pro ................................................................................................................................................................1 Tools .........................................................................................................................................................................1 Codeflow Obfuscation ..............................................................................................................................................2 TLS Callbacks .............................................................................................................................................................3 CRC Checks & Code En/Decryption ..........................................................................................................................4 Antis ..........................................................................................................................................................................5 Anti-Attach Hooks.................................................................................................................................................5 Misc Anti-Debug ...................................................................................................................................................6 VMed Antidbg.......................................................................................................................................................8 Anti-API hooking ...................................................................................................................................................9 API Redirection ...................................................................................................................................................... 10 Simple ................................................................................................................................................................ 10 Advanced ........................................................................................................................................................... 10 Misc tricks .............................................................................................................................................................. 11 Stolen OEP ............................................................................................................................................................. 11 Saluti e ringraziamenti ........................................................................................................................................... 12

Alla scoperta di lARP64Pro

Embed Size (px)

DESCRIPTION

Autore : SmilingWolf[ITA] - Alla scoperta di lARP64Pro

Citation preview

  • Alla scoperta di lARP64Pro

    Sommario Introduzione .............................................................................................................................................................1

    lARP64 Pro ................................................................................................................................................................1

    Tools .........................................................................................................................................................................1

    Codeflow Obfuscation ..............................................................................................................................................2

    TLS Callbacks .............................................................................................................................................................3

    CRC Checks & Code En/Decryption ..........................................................................................................................4

    Antis ..........................................................................................................................................................................5

    Anti-Attach Hooks.................................................................................................................................................5

    Misc Anti-Debug ...................................................................................................................................................6

    VMed Antidbg .......................................................................................................................................................8

    Anti-API hooking ...................................................................................................................................................9

    API Redirection ...................................................................................................................................................... 10

    Simple ................................................................................................................................................................ 10

    Advanced ........................................................................................................................................................... 10

    Misc tricks .............................................................................................................................................................. 11

    Stolen OEP ............................................................................................................................................................. 11

    Saluti e ringraziamenti ........................................................................................................................................... 12

  • 1

    Introduzione Ad alcuni reverser piace giocare insieme ai compagni a guardie e ladri, sfidandosi a colpi di unpackme e crackme. in questo contesto che nel 2008 lena151, che certo non ha bisogno di presentazioni, ha deciso di creare la sua creatura pi temuta: lARP64 Pro, un protector per programmi a 64bit rimasto imbattuto per pi di tre anni. Nel 2012 lena151, delusa dalla scarsa quantit di tentativi fatti per sbaragliare le protezioni implementate in lARP64, dichiar interrotto lo sviluppo del software per sempre perch "non c' mai stato un vero bisogno di mantenersi avanti rispetto alla community", aggiungendo inoltre di aver perso la fede nel reversing. Spero quindi, con questo paper, di mostrarle che la community tutt'altro che morta e che lo spirito del reversing vive anche nella nuova generazione, una generazione che lei stessa ha contribuito a fare crescere

    lARP64 Pro "Remark that lARP64Pro is not just like 'any' commercial product but it is merely a 64bit project to

    prove it is indeed possible to create uncrackable software. To that extent, we have sent lARP64Pro itself as well

    as a software protected by lARP64Pro to the cracking community in september of 2008, requesting to crack

    either. Till this day, the cracking community have not succeeded and our conviction is that lARP64Pro will

    remain uncracked at least for a significant time. The project has been made available for commercial purposes

    and a trial version is freely downloadable from this site, however this does not mean it is sold to everyone or for

    every purpose. Yet, contact us in case your x64 software really needs to be super-protected."

    Ecco la presentazione di lARP64 cos come la si poteva leggere sul sito ufficiale. Viene promesso un engine di

    protezione estremamente potente, forte del fatto che nessun dump funzionante del primo unpackme rilasciato

    e nessuna copia crackata di lARP64 stesso siano mai comparsi in rete.

    Ma esattamente, che protezioni sono state implementate? Con questa domanda in mente ho tracciato per due

    settimane il codice del protector e in questo documento voglio condividere con voi ci che ho scoperto.

    Tools x64_dbg (http://x64dbg.com/);

    Multiline Ultimate Assembler (plugin per x64_dbg, usato per assemblare alcuni snippet di codice ASM);

    ScyllaHide (plugin per x64_dbg, usato per patchare i byte BeingDebugged1 e NtGlobalFlag2 e la

    funzione NtQueryInformationProcess usata da CheckRemoteDebuggerPresent3);

    Scylla (https://forum.tuts4you.com/files/file/576-scylla-imports-reconstruction/).

    1 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 83-84

    2 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 5-8

    3 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 62-63

  • 2

    Codeflow Obfuscation Aprendo l'unico unpackme a disposizione della community la prima cosa che si nota la quantit di

    codice incomprensibile che ci si trova davanti. Tuttavia, grazie ad un'analisi pi approfondita e con un po' di

    tracing si arriva facilmente ad una conclusione: il codice perfettamente lineare e la redirezione avviene per

    mezzo di CALL e JCC che fanno saltare in avanti di 1-4 byte l'esecuzione (saltando le istruzioni spazzatura),

    sufficienti a far perdere il controllo del programma al debugger la prima volta che un BP viene settato nel

    punto sbagliato4.

    Nell'immagine si pu vedere il codice prima della pulizia (tracciare all'interno delle prime CALL per capire di quanto spostino in avanti l'esecuzione e assegnare ad esse una label adeguata semplificher moltissimo il lavoro).

    Ed ecco che noppando i byte spazzatura il codice assume un senso.

    Altra caratteristica che concorre nel renderci il tracing difficile il modo in cui vengono effettuate le API calls:

    nella quasi totalit dei casi gli indirizzi delle API ritrovati con GetProcAddress sono stati diminuiti di 1 o 2.

    Quando servono vengono PUSHati e viene usato un JCC salterino per aggiustare l'indirizzo e finire sull'API

    desiderata.

    4 Da qui in avanti mi riferir a questi "redirector" come CALL o JCC salterini per il fatto che incrementano l'indirizzo

    presente in [RSP] mentre saltellano qua e la nel codice del protector.

  • 3

    TLS Callbacks Il primo codice eseguito dal debuggee consiste in 5 TLS Callbacks che si occupano di sistemare gli

    indirizzi delle varie CALL salterine al posto giusto e di determinare la presenza di un debugger.

    Ecco una breve descrizione di ognuna, nell'ordine di esecuzione:

    Procedura 1:

    Sistema gli indirizzi dei jump al posto giusto.

    Procedura 2:

    Calcola il checksum dei primi 270h bytes dall'EP.

    Il checksum calcolato in questo modo risulter ovviamente sballato nel caso in cui un debugger abbia messo un

    BP in quella posizione.

    Il risultato viene poi usato per decryptare dei dati.

  • 4

    Procedura 3:

    Preleva il byte BeingDebugged leggendolo dal Process Environment Block (PEB) passando dal Thread

    Environment Block (TEB).

    Procedura 4:

    Preleva il byte BeingDebugged leggendolo dal PEB. Da notare che l'indirizzo al quale viene aggiunto RAX lo

    stesso che viene messo in RDI durante la procedura 2.

    Procedura 5

    Preleva la NtGlobalFlag leggendola dal PEB passando dal TEB.

    CRC Checks & Code En/Decryption Il codice viene controllato abbastanza frequentemente per mezzo di chiamate a procedure che

    calcolano il CRC di porzioni fisse o di indirizzo e dimensioni arbitrarie di codice. Quasi mai, per, il risultato del

    calcolo del checksum viene verificato in maniera diretta. Molto pi spesso viene semplicemente messo da

    parte e controllato pi tardi o, peggio, usato come chiave per decryptare altre porzioni di codice. In caso di

    check o decryptazioni fallite le conseguenze possono essere varie, ma in ogni caso ci obbligheranno a riavviare

    il debuggee.

    Il controllo non avviene solamente sul codice dello stub: una volta decompresso il codice della codesection

    viene a sua volta verificato.

    Intere regioni dello stub, inoltre, sono racchiuse tra funzioni che ne decryptano il codice, lo eseguono e poi lo

    cryptano nuovamente, rendendo impossibile la ricerca diretta di pattern e riferimenti a indirizzi che potrebbero

    interessarci.

  • 5

    Antis

    Anti-Attach Hooks La prima cosa che il buon reverser fa, una volta accortosi che far girare il processo sotto debugger sar

    un processo molto lungo, tentare di individuare almeno una zona nel codice vicina all'OEP attaccandosi al

    processo in esecuzione e cercando pattern familiari o esaminando lo stack. lARP64 cerca di ovviare a questo

    problema usando un paio di trucchi: il primo consiste nel posizionare un hook sulla funzione

    DbgUiRemoteBreakin - ovvero la funzione che viene chiamata quando un debugger cerca di attaccarsi ad un

    processo gi in esecuzione. Per complicarci la vita lARP64 arriva addirittura ad usare direttamente una System

    Call!

    Fermi tutti, ora mi serve un attimo per parlare di come funzionino le syscalls su Windows a 64bit: per passare

    dal codice in ring3 (user mode) al codice in ring0 (kernel mode) viene usato il comando "SYSCALL" (opcode 0x0F

    0x05). Le funzioni eseguite in kernel mode sono contenute in ntoskrnl.exe e le loro export non sono disponibili

    in user mode, quindi per chiamarle viene usato un ID (si pu pensare a questo ID come all'ordinal di una

    normale funzione) che va messo in EAX5; gli argomenti vengono passati secondo la fastcall calling convention

    con una sola differenza: il primo argomento va messo in R10 anzich in RCX.6

    Ok, torniamo al nostro hook: , all'atto pratico, un BlockInput "fatto in casa" (l'ordinal 1283h corrisponde alla

    funzione NtUserSetSystemCursor che chiamata con arg1 == 1 (xor r10, r10; inc r10) blocca gli input provenienti

    dalle periferiche attaccate al PC)7. Per fortuna non si tratta di qualcosa di particolarmente grave: gli input non

    sono veramente bloccati, bens filtrati e la combinazione Ctrl+Alt+Canc ci permetter di riottenere il controllo

    del nostro PC. Il problema ci che viene dopo: effettuata la SYSCALL il controllo passer al protector che, nel

    tentativo di mostrare una MessageBox recante la criptica scritta "Unregistered Stack" (questo il

    comportamento standard quando uno qualsiasi dei controlli fallisce o qualcosa va storto), crasher

    inesorabilmente.

    L'aspetto dell'hook una volta che stato posizionato

    5 Non si tratta di un errore di battitura: i 4 byte "pi a sinistra" di RAX non vengono toccati, l'operazione eseguita

    sempre MOV EAX, ID 6 Qui ho dovuto semplificare parecchio per non rendere il discorso troppo lungo, per maggiori informazioni sul

    funzionamento delle syscalls su Windows vedere "Windows Internals Part 1 6th Edition", di Mark Russinovich, David A. Solomon e Alex Ionescu, pp. 132 e seguenti 7 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 118-119

  • 6

    Se compare questo messaggio qualcosa andato terribilmente storto

    Usare direttamente l'ID delle funzioni del kernel non affatto flessibile come approccio e non supportato da

    Microsoft (, anzi, fortemente sconsigliato): le funzioni possono cambiare ordinal non solo tra due sistemi

    operativi differenti, ma anche tra service pack differenti dello stesso S.O.

    Il secondo trick che il codice ci riserva molto pi semplice: viene scritto un RETN (0xC3) al posto dell'INT3

    (0xCC) che si trova all'inizio di DbgBreakPoint (altra funzione chiamata nel momento in cui un debugger si

    attacca ad un processo in esecuzione) di fatto impedendo che il Debug Event venga sollevato e catturato dal

    debugger, che cos perde il controllo dell'applicazione.

    Misc Anti-Debug La maggior parte di questi sono dei classici:

    NtClose chiamato con un handle non valido8;

    Execution timing9 usando RDTSC e una copia "in locale" di GetTickCount (la funzione viene copiata

    nella sezione del protector e da quel momento in avanti l'API non viene pi usata, prediligendo

    ovviamente la copia fatta). Per individuare possibili modifiche fatte sul valore restituito dalla funzione

    locale una volta viene eseguito anche uno SleepEx tra due call a GetTickCount ed il risultato della

    sottrazione dei valori restituiti dai GetTickCount viene confrontato con uno fisso: se questo risulta

    minore di quello atteso (di poco inferiore al parametro passato a SleepEx) vuol dire che un reverser sta

    manomettendo i risultati;

    Controllo dei byte BeingDebugged e delle NtFlags, come gi visto nel paragrafo dedicato alle TLS

    Callbacks;

    CheckRemoteDebuggerPresent;

    Cerca file *.nam nella stessa cartella dell'eseguibile usando FindFirstFileA: si tratta dell'estensione di

    uno dei file creati da IDA quando gli si d in pasto un programma;

    8 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 44-48

    9 Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 57-62

  • 7

    GetAsyncKeyState usato per verificare se sono stati premuti i tasti F5, F7, F8 o F9 (comunemente usati

    nei debugger per restituire l'esecuzione al programma debuggato in vari modi, dallo step-in alla ripresa

    dell'esecuzione del programma).

    Curiosit: se viene tenuto premuto uno dei tasti tenuti sotto controllo e si fa partire un programma

    lARPato questo penser di essere sotto un debugger e terminer indignato :P

    DebugActiveProcess chiamato con dwProcessId == -1. Si tratta di un anti-stepping trick che ho trovato

    descritto dal buon @waleedassar in un suo tweet10;

    Cicla con FindWindowA attraverso una serie di nomi di finestre e classi che ritiene essere pericolosi11; nello specifico FindWindowA viene chiamato con i seguenti parametri:

    1. ClassName == "TIdaWindow"

    2. ClassName == "fasm_win64_AMD64_debugger" e WindowName == "FDBG - Win64 AMD64 Debugger written in FASM"

    3. ClassName == "WinDbgFrameClass";

    CreateFileA con FileName == "\\.\fdbg"12;

    Un ciclo a base di CreateToolhelp32Snapshot/Process32First/Process32Next/lstrcmpA 13 per

    controllare che in memoria non siano presenti processi che ritiene essere pericolosi, nello specifico:

    idag64.exe, windbg.exe, dbgsrv.exe, dsrsvc.exe, fdbg.exe e win64_remotex64.exe;

    Usando CsrGetProcessId ottiene il PID del processo csrss.exe, poi tenta di ottenerne l'accesso usando

    OpenProcess con dwDesiredAccess == 1f0fffh == PROCESS_ALL_ACCESS14. Se la chiamata ha successo

    vuol dire che il processo del programma lARPato fornito del "debug privilege"; questo succede in due

    occasioni: stato avviato da un debugger che ha attivato il debug privilege o l'account dal quale

    l'eseguibile protetto stato lanciato fa parte del gruppo Administrator e ha tale privilegio attivo;

    impossibile distinguere un caso dall'altro ed il processo terminer in entrambi;

    EnumWindows che punta ad una funzione che usa GetWindowTextA per controllare che non siano

    aperte finestre con titoli propri di applicazioni nefaste, nello specifico: "remotex6", "IDA - " e

    "WinDbg";

    10

    https://twitter.com/waleedassar/status/257056312494530560 11

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 100-101 12

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 48-53 13

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 65-78 14

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 41-44

  • 8

    VMed Antidbg Forse una delle parti pi carine del lARP64: i trick anti-debugging eseguiti usando una VM. Quando

    giungiamo al VM handler in un registro presente l'indirizzo di una tabella di opcodes con relativi dati

    aggiuntivi (byte che specificano il registro sul quale operare, VA o valori con i quali operare). Questa VM in

    particolare ha una struttura molto semplice e un po' atipica: esiste solo un grande handler che esegue compiti

    specifici a seconda dello stato interno e degli opcodes da processare15; in pi, la maggior parte delle operazioni

    eseguite all'interno di ciascun "pezzo" dell'handler servono per bilanciare e alterare lo stato interno della VM

    (Fig. 1), mentre le poche che fanno effettivamente qualcosa di rilevante per il programma (Fig. 2) lavorano

    direttamente sui registri e sullo stack del processore reale16, rendendo molto semplice intuire la funzione di

    ciascun opcode virtuale e la realizzazione di un software per la devirtualizzazione.

    Fig. 1: un tipico blocco di codice che ha il solo scopo di modificare lo stato

    interno della VM

    Fig. 2: un blocco di codice contenente l'istruzione che ci interessa (MOV

    RAX, QWORD PTR GS:[30])17

    .

    I trick virtualizzati sono i seguenti:

    Lettura del byte BeingDebugged dal PEB passando dal TEB;

    Lettura del byte BeingDebugged dal PEB;

    Execution timing usando la copia "in locale" di GetTickCount;

    NtSetInformationThread con THREADINFOCLASS == ThreadHideFromDebugger18;

    NtQuerySystemInformation con SystemInformationClass == SystemKernelDebuggerInformation19;

    CheckRemoteDebuggerPresent;

    NtClose chiamato con un handle invalido.

    I primi tre vengono eseguiti prima di arrivare agli stolen bytes dell'OEP e ogni volta che va risolta un'import

    nascosta con l'API Redirection avanzata, mentre gli ultimi quattro vengono eseguiti una sola volta prima di

    arrivare ai byte dell'OEP.

    15

    In implementazioni pi diffuse ogni handler una procedura a s stante 16

    In molte altre implementazioni lo stack e i registri sono anch'essi virtualizzati: lo stack risiede in un'area di memoria allocata per l'occasione, mentre i registri sono memorizzati come variabili 17

    Il mio DeVirtualizer hostato all'indirizzo https://bitbucket.org/SmilingWolf/larp64-devirtualizer insieme alla documentazione della maggior parte dei virtual opcodes e del formato delle VM Entries 18

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 121-122 19

    Peter Ferrie, The Ultimate Anti-Debugging Reference, pp. 105-106

  • 9

    Anti-API hooking lARP64 controlla i primi n bytes di ogni API che sar usata nell'immediato futuro per controllare che non siano

    presenti INT3 (0xCC) o loop infiniti (0xEB 0xFE).

    La funzione procede cos: mediante l'uso di un length disassembler determina la lunghezza (in numero di bytes)

    dell'istruzione all'indirizzo dato; se l'istruzione ha lunghezza == 1 allora controlla se il byte 0xCC, se l'istruzione

    ha lunghezza == 2 controlla se i due bytes sono 0xEB 0xFE; in caso di risposta affermativa ci porta sulla strada

    del messaggio di errore, altrimenti la lunghezza trovata viene aggiunta ad un contatore che verr confrontato

    con n e aggiunta all'indirizzo da controllare, ciclando in questo modo finch il contatore < n.

    Indirizzo dell'API in RDI, n in RBX, contatore in RSI

    Viene anche avviato un thread che si occupa esclusivamente di controllare tutte le API in un ciclo infinito.

    Curiosit: lARP64 non controlla solo le API che verranno usate di l a poco, ma anche quelle che vengono

    caricate durante il setup dell'API redirection semplice e prima di saltarci sopra nell'API redirection avanzata

    (vedi sotto): questo perch uno dei precedenti unpackme rilasciati da lena151 (nello specifico, quello protetto

    con lARP 2.0 Ultra) stato spacchettato da Quosego usando una DLL modificata perch si bloccasse alla prima

    chiamata a HeapCreate (chiamata che in quello specifico unpackme avveniva molto vicino all'OEP).

  • 10

    API Redirection

    Simple Passati i vari trick anti-qualunquecosa lARP64 carica le DLL che serviranno al programma per funzionare

    e imposta degli hook al livello della IAT - ovvero mette in un'area di memoria allocata dallo stub del codice

    offuscato che salter all'API giusta, poi ne mette l'indirizzo nella IAT del programma (dove invece dovrebbero

    stare gli indirizzi delle API). Il codice offuscato relativamente difficile da tracciare a mezzo di scripts et similia,

    ma stato commesso un grosso errore: prima di mettere gli indirizzi delle procedure offuscate al loro posto

    vengono scritti tutti gli indirizzi giusti (riempiendo la IAT nel modo corretto) e solo DOPO questi vengono

    rimpiazzati, rendendo possibile il dump della IAT, che potr poi essere ripristinata quando preferiamo (magari

    quando siamo vicini all'OEP ).

    Advanced Seconda tipologia di API redirection usata: alcune CALL [addr] sono state sostituite con un CALL

    VMHandler.

    Vengono usati un array e due tabelle:

    DLLVAs: un array contenente i VA delle DLL usate dal programma;

    VMedIT

    DWORD RVA

    WORD hashesIndex

    WORD isRETN

    Dopo aver eseguito del codice antidebug all'interno della VM si esce da questa per mezzo di un JMP (sempre

    virtualizzato) e si atterra su una procedura che:

    1. legge l'indirizzo di ritorno della CALL dallo stack, ci sottrae 5 e poi l'imagebase (cos ottiene l'RVA della CALL);

    2. cerca questo indirizzo nella VMedIT (Virtualized Imports Table), che contiene gli RVA delle CALLs gestite in questo modo;

    3. trovata l'entry giusta legge hashesIndex (che contiene l'indice da usare in HashesTable);

    4. viene usato l'index trovato per leggere DLLVAsIndex, che funger da indice per DLLVAs;

    5. il nome della prima export tra quelle contenute nella Export Table della DLL cos trovata viene passato alla funzione di hashing ed il risultato confrontato con quello memorizzato nella HashesTable. Se i due hash coincidono allora l'export della DLL coincide con l'import da risolvere e si passa al punto 6, altrimenti si calcola l'hash della seconda e si va avanti cos finch non si trova l'hash corrispondente;

    6. viene letto l'indirizzo al quale si trova la funzione esportata desiderata;

    HashesTable

    DWORD Hash

    WORD DLLVAsIndex

    WORD NLoops1

    WORD NLoops2

  • 11

    7. se la WORD isRETN all'interno della VMedIT contiene 0x20 allora lo stack viene aggiustato per emulare la presenza di un RETN dopo la CALL che ci ha fatti giungere all'API redirection, altrimenti questo passo viene saltato;

    8. si esegue un JMP sull'API voluta e l'esecuzione riprende normalmente.

    Le WORD NLoops1 e NLoops2 vengono riempite con il numero di iterazioni del ciclo del punto 5 che sono state

    necessarie per trovare l'hash giusto; questo pu quindi essere saltato la prossima volta che la stessa import

    deve essere risolta velocizzando il processo.

    Misc tricks Una volta che il codice stato decompresso lARP64 ci giocherella un po' per confondere le acque:

    gli 0xCC che alcuni compilatori usano per allineare le funzioni in fase di compilazione vengono sostituiti

    con byte spazzatura per rendere il codice della codesection meno leggibile;

    viene usato un loop per esaminare uno per uno un certo numero di byte della codesection. Ogni volta

    che il byte == 0xC3 (RETN) viene eseguita una CALL REG64 (dove REG64 il registro che contiene

    l'indirizzo del byte). Penso che lARP64 faccia questo allo scopo di "fregare" alcuni strumenti automatici

    per il ritrovamento dell'OEP (una delle tecniche usate da questi programmi consiste infatti nel

    controllare quando viene eseguito del codice contenuto nella codesection; appena questo avviene

    fermano il programma ed allertano l'utente).

    Numero di byte da controllare in RCX, indirizzo del byte in RDI

    Stolen OEP Nella fase di packing lARP64 ruba i byte dell'OEP mettendoli nella sua sezione e cancellandoli dalla codesection

    seguendo nel mentre anche i JMP (come quelli presenti vicino all'OEP delle applicazioni compilate con MS

    Visual C++). Le istruzioni rubate vengono eseguite dopo che tutti i trick antidebug sono stati usati, poi il

    protector passa il controllo all'applicazione. Contrariamente a quanto succede con altri protector per il codice

    dell'OEP non viene offuscato, virtualizzato o modificato in alcun modo.

  • 12

    Per riconoscere i byte dell'OEP serve un po' di occhio: si tratta di quelle istruzioni circondate da codice che

    lavora con variabili contenute nella sezione del protector.

    Le istruzioni evidenziate sono i nostri stolen bytes

    Saluti e ringraziamenti Whooohooo finito!!! Avete presente il detto "non si pu apprezzare un lavoro finch non lo si svolge

    in prima persona"? No? Allora evidentemente me lo sono inventato sul momento :P

    L'unico modo per capire quanto lavoro ci sia dietro ogni singolo paragrafo di un paper scriverne uno, quindi

    vorrei salutare tutti gli autori passati, presenti e futuri di paper e tutorial perch hanno tutti il mio rispetto.

    D'altro canto, questo paper non avrebbe mai visto la luce senza il contributo di alcune persone e gruppi che

    quindi voglio ringraziare:

    lena151: la "zietta" di un'intera generazione di reverser e l'autrice del packer trattato qui, con il quale mi hai

    insegnato molto senza scrivere una riga... se fare il miglior metodo per imparare, direi che con questo hai

    colto nel segno persino meglio di quanto avresti mai potuto fare con cento tutorial. Grazie

    Mr. eXoDia: forse non lo sai (e se lo sai non lo ripeter comunque mai abbastanza), ma i tuoi tutorial su

    Armadillo, le tue ricerche ed il tuo approccio al reversing in generale (oltre che le grandi abilit) mi hanno

    sempre colpito tantissimo... se non fosse stato per te e per l'ispirazione che mi hai sempre dato (e per il

    supporto fornito ogni volta che mi trovavo bloccato durante i miei primi approcci al protector della Silicon

    Realms) a quest'ora non so dove sarei (ma di certo non sarei qui :P)

    tonyweb: per il tempo dedicato alla revisione di questo paper anche se di tempo non ne hai. Gente, lui ha il

    documento "pre-revisione" e credetemi, grazie ai suoi consigli questo che state leggendo non neanche

    lontanamente paragonabile alla copia che gli avevo mandato.

    Tuts4you (tutta la community): siete grandiosi tutti quanti. Fra di voi ci sono persone ad un livello che mi posso

    solo sognare ed fantastico che esista ancora una community attiva e capace come questa con persone

    disposte ad aiutare gli altri. Greets! :D

    Tu: gi, tu che non ti sei addormentato a met e che hai continuato a leggere fin qui. Spero che questa mia

    produzione ti sia piaciuta e che ti abbia lasciato qualcosa di pi di un vago senso di torpore