
Storico del firmware solo binario che impara a localizzare funzioni in binari grezzi estraendo funzioni note da binari simili, consentendo un rapido abbinamento di funzioni senza disassemblaggio per l'analisi del firmware embedded.
Polypyus impara a localizzare funzioni in binari grezzi estraendo funzioni note da binari simili. Pertanto, è uno storico del firmware. Polypyus funziona senza disassemblare questi binari, il che è un vantaggio per binari complessi da disassemblare e dove gli strumenti comuni perdono funzioni. Inoltre, l'approccio solo binario lo rende molto veloce e funziona in pochi secondi. Tuttavia, questo approccio richiede che i binari siano per la stessa architettura e abbiano opzioni del compilatore simili.
Polypyus si integra nel flusso di lavoro di strumenti esistenti come Ghidra, IDA, BinDiff e Diaphora. Ad esempio, può importare funzioni precedentemente annotate e imparare da esse, e anche esportare funzioni trovate per essere importate in IDA. Poiché Polypyus usa soglie piuttosto rigorose, nei nostri esperimenti ha trovato solo corrispondenze corrette. Sebbene ciò porti a meno risultati rispetto agli strumenti esistenti, è un buon punto di partenza per caricare queste corrispondenze in IDA per migliorare i suoi risultati di analisi automatica e poi eseguire BinDiff sopra.
Quando si lavora con binari di firmware grezzi, in particolare varie versioni del firmware Bluetooth Broadcom e Cypress, abbiamo scoperto che l'analisi automatica di IDA spesso identificava gli inizi di funzione in modo errato. In IDA Pro 6.8 l'analisi automatica è un po' più aggressiva, portando a più risultati ma anche a più falsi positivi. In generale, IDA Pro 7.2 era più pessimista, ma ha perso molte funzioni. Questo ha portato a solo poche corrispondenze BinDiff tra i nostri firmware in IDA Pro 6.8 e nessuna corrispondenza utile in IDA Pro 7.2.
È interessante notare che BinDiff spesso non riusciva a identificare funzioni che, a parte i rami, erano identiche byte per byte. Nota che Polypyus cerca esattamente queste funzioni identiche byte per byte. Supponiamo che BinDiff fallisca su queste funzioni a causa di un grafo delle chiamate diverso prodotto da funzioni mancanti e falsi positivi. A volte, queste funzioni erano già riconosciute da IDA, ma spesso IDA non le riconosceva come codice o non le marcava come funzione. Nota che Diaphora ha problemi simili, poiché esporta funzioni identificate da IDA prima di elaborarle ulteriormente. Il seguente mostra un benchmark sul binario del firmware Bluetooth CYW20735B1 che confronta vari disassemblatori e come i fallimenti del disassemblatore portino a problemi di diffing successivi.
Inoltre, mentre abbiamo scoperto che Amnesia trova molte funzioni, trova anche molti falsi positivi. Tuttavia, molte funzioni hanno una configurazione dello stack frame simile all'inizio. Pertanto, Polypyus ha un'opzione per apprendere gli inizi di funzione comuni dai binari di input annotati e applicarla ad altri binari per identificare funzioni senza abbinare il loro nome. Questo passaggio opzionale viene applicato solo alle regioni in cui non sono state precedentemente individuate funzioni, in questo modo il metodo degli inizi di funzione comuni e la ricerca della funzione principale non entrano in conflitto.
Poiché questi matcher lavorano sul binario grezzo, non dipendono da un disassemblatore. Questo ha anche uno svantaggio importante: se ci fossero opzioni del compilatore diverse o un'architettura target diversa, Polypyus non rileverà funzioni simili. Inoltre, mentre le corrispondenze identificate sono molto affidabili, l'identificazione dell'inizio della funzione è un po' meno affidabile, quindi usa quest'ultima con cautela. Nel seguente, puoi vedere che i kit di valutazione Cypress sono molto simili tra loro, ma il firmware del MacBook è molto diverso.
Polypyus crea matcher binari fuzzy confrontando funzioni comuni in una raccolta di binari di firmware annotati.
Attualmente, sono supportate le seguenti annotazioni:
patch.elf, che è un file ELF speciale contenente solo definizioni di simboli..symdefs come prodotto dalla maggior parte dei compilatori ARM..csv con un formato documentato nella cartella firmware.Queste annotazioni contengono l'indirizzo, la dimensione e il nome delle funzioni note. Più somiglianze hanno i binari di input nella raccolta storica, meglio è per le prestazioni e i risultati di Polypyus. Date diverse funzioni leggermente differenti, Polypyus crea matcher molto buoni.
Polypyus richiede Python 3 >= 3.6. Consigliamo l'uso di un virtualenv per la seguente installazione. Clona questo repository e in questa cartella esegui:
pip install .
Dopo l'installazione sono disponibili i seguenti comandi:
polypyus-guipolypyus-cliPolypyus è disponibile tramite un'interfaccia grafica e una a riga di comando.
Sia la GUI polypyus-gui che la CLI polypyus-cli accettano questi argomenti durante l'invocazione:
--verbose is the verbosity level. By default, it shows warnings -v shows info -vv show debug information.
--project sets the location of the project file. This is either a file path or ":memory:".
--help Show help message.
L'opzione project ti permette di salvare il tuo lavoro per diversi contesti in file diversi e anche di riaprirli.
Il flusso di lavoro generale della GUI va dal lato sinistro della finestra a destra.
Prima, i binari vengono aggiunti alla cronologia. Poi, seguono le annotazioni dei simboli per le voci
nella cronologia.
Successivamente, è possibile aggiungere binari target.
Per l'abbinamento, premi Create matchers from history. Una volta creati i matcher, è possibile selezionare
singoli target, o abbinare tutti i target selezionando batch match.
Infine, i risultati possono essere esportati in un file .csv.
Nel seguente puoi vedere un video demo in cui Polypyus impiega solo pochi secondi per apprendere da due binari di input, annotarli, creare matcher e applicare le corrispondenze a un nuovo binario.
Il vantaggio di usare la CLI è la sua capacità di essere automatizzata. Al momento, il formato di output della CLI è soggetto a modifiche. Tuttavia, ecco un esempio di chiamata:
polypyus-cli --history firmware/history/20819-A1.bin --annotation firmware/history/20819-A1_patch.elf --history firmware/history/20735B1.bin --annotation firmware/history/20735B1_patch.elf --project test.sqlite
polypyus-cli --target firmware/history/20739B1.bin --project test.sqlite
Il primo comando crea test.sqlite come nuovo file di progetto e importa 20819-A1.bin e 20735B1.bin
con i rispettivi file patch.elf.
La seconda invocazione riutilizza lo stesso file di progetto e abbina al binario 20739B1.bin.
Per ogni comando, il numero di --history e --annotation deve corrispondere.
Questi due comandi potrebbero anche essere combinati in uno aggiungendo l'argomento --target al primo comando.