2010-07-25 15 views
6

Sto lavorando ad un semplice decompilatore per l'architettura MIPS e mentre progredisco devo definire molte regole per l'analisi del codice, per esempio "se questo codice operativo è lui e il prossimo codice operativo è aDDIU poi tornare var = valore "o 'se questo codice operativo è BNE ed è riferita ad affrontare prima che la corrente - creare ciclo definizione nel parsing albero'. Il problema - ci sono tonnellate di tali regole e non riesco a trovare un buon modo per definirle. Ho provato a scrivere funzioni separate per ogni regola, definendo belle classi di logica di base OOP e estendendole per creare regole, persino provato espressioni regolari su codice disassato (con mia sorpresa funziona meglio del previsto) ma non importa quello che ho provato, Il mio codice divenne presto grande e difficile da leggere, non importa quanto sto cercando di documentarlo e strutturarlo.Cercare un buon modo per definire le regole per il decompilatore, ho bisogno di un consiglio

Questo mi porta alla conclusione, che sto cercando di risolvere questo compito utilizzando strumenti sbagliati (per non parlare dell'essere troppo stupidi per un compito così complesso :)), ma non ho idea reale di cosa dovrei provare. Attualmente ho due idee non testate, una sta usando qualche tipo di DSL (non ho assolutamente esperienza in questo, quindi posso sbagliare completamente), e un altro sta scrivendo una sorta di strumenti tipo regexp binario per la corrispondenza opcode.

Spero che qualcuno possa indicarmi la direzione corretta, grazie.

+0

Non penso sia possibile scrivere un decompilatore osservando gli schemi di istruzioni. Il flusso di codice e l'analisi dei dati sono necessari per costruire correttamente blocchi di codice ed espressioni. –

+2

L'osservazione del pattern opcode AFAIK è il modo per ottenere il flusso del codice, come nel mio secondo esempio (si trova un codice operativo che si riferisce all'indirizzo prima di se stesso = questo è un ciclo), ma hai ragione che è solo uno dei passaggi, come Ho bisogno di calcolare le condizioni per questo ciclo, il che significa che ho bisogno di guardare il codice prima e controllare la memoria \ registra le modifiche. Quindi, questa è un'analisi a due passaggi: prima costruire l'albero del flusso, quindi calcolare tutto all'interno. – Riz

+1

Il metodo di regex binario in realtà suona come una buona idea. L'unica altra cosa che posso pensare sarebbe scrivere un frontend MIPS su LLVM, e usare il backend C per ottenere il codice (anche se non ho idea di quanto leggibile sarebbe il codice generato, ad esempio potrebbe usare 'goto's for loops e ricicla le variabili, ecc.) – Zifre

risposta

2

Direi che alcune delle tue regole sono troppo di basso livello, ed è per questo che stanno diventando ingestibili.

Riconoscimento lui seguito da addiu come un carico costante a 32 bit certamente sembra molto ragionevole; ma cercare di derivare il flusso di controllo dalle istruzioni di ramo a livello di singolo codice operativo sembra più sospetto - penso che tu voglia lavorare con blocchi di base lì.

Cifuentes 'Reverse Compilation Techniques è un riferimento che continua a spuntare nelle discussioni sulla decompilazione che ho visto; da una breve scorciatoia, sembra che valga la pena di dedicare del tempo a leggere in dettaglio il tuo progetto.

Alcune delle specifiche x86 non saranno rilevanti - in particolare, la fase che traduce x86 in una rappresentazione intermedia di basso livello non è probabilmente necessaria per MIPS (MIPS è essenzialmente solo una operazione di base per codice operativo già) - ma per il resto gran parte del contenuto sembra dovrebbe essere molto utile.

+0

Oh mio Dio, questa è un'eccellente fonte di carte che legge peggio, non posso esprimere quanto sono grato (per favore, non chiedermi come sono riuscito a mancare questo :)) – Riz

Problemi correlati