
HAL [/hel/] è un framework completo per il reverse engineering e la manipolazione di netlist.
Praticamente tutta la ricerca disponibile sull'analisi di netlist opera su una rappresentazione basata su grafi della netlist sotto esame. Al suo nucleo, HAL fornisce esattamente questo: Un framework per analizzare netlist di fonti arbitrarie, ad esempio FPGA o ASIC, in una rappresentazione di netlist basata su grafi e per fornire gli strumenti integrati necessari per la navigazione e l'analisi dei gate e delle connessioni inclusi.
La nostra visione è che HAL diventi l'equivalente per il reverse engineering hardware di strumenti come IDA o Ghidra. Vogliamo che HAL fornisca una base comune per ricercatori e analisti per migliorare la riproducibilità dei risultati di ricerca e astragga dai compiti di base ricorrenti come il parsing di netlist, ecc.
HAL è attivamente sviluppato dal gruppo Embedded Security del Max Planck Institute for Security and Privacy. Oltre a molteplici progetti di ricerca, viene utilizzato anche nella nostra lezione universitaria "Einführung ins Hardware Reverse Engineering" (Introduzione al Reverse Engineering Hardware) presso la Ruhr University Bochum (RUB).
Nota che disponiamo anche di un set di circuiti benchmark moderni e all'avanguardia per la valutazione delle tecniche di reverse engineering di netlist, disponibile in un repository separato.
Questo repository contiene una selezione di plugin curati:
libertyUna documentazione completa delle funzionalità di HAL dal punto di vista dell'utente è disponibile nel nostro Wiki. Inoltre, forniamo una documentazione completa dell'API C++ e dell'API Python.
Per le istruzioni su come compilare HAL, fare riferimento alla pagina dedicata nel nostro Wiki.
Installa HAL o compila HAL e avvia la GUI tramite hal -g. Puoi elencare tutte le opzioni disponibili tramite hal [--help|-h].
Abbiamo incluso alcuni progetti di esempio nella sottodirectory examples. Per iniziare con un progetto di esempio è necessario importarlo
tramite Import Project dal menu principale o trascinando il file zippato nell'area OPEN PROJECT della schermata di benvenuto.
In questo modo apparirà un popup che richiede una directory con permessi di scrittura dove HAL creerà la directory del progetto e decomprimerà
i file. Non utilizzare strumenti esterni per decomprimere poiché vengono apportati adattamenti in modo che la netlist e la libreria di gate
vengano trovate la prossima volta che il progetto viene aperto.
Nel caso in cui tu voglia aprire la tua netlist Verilog o VHDL, devi eseguire Import Netlist invece. Funzionerà solo se
è presente una libreria di gate corrispondente in plugins/gate_libraries/definitions o se fornisci manualmente la libreria di gate.
Per le istruzioni su come creare la tua libreria di gate e altri tutorial utili, dai un'occhiata al wiki.
Il seguente codice di esempio si riferisce all'esempio fsm.
Utilizza la shell Python integrata o la finestra dello script Python per interagire. Entrambe dispongono di funzionalità di completamento automatico (limitate).
Elenchiamo tutte le lookup table e stampiamo le loro funzioni booleane:
for gate in netlist.get_gates():
if "LUT" in gate.type.name:
print("{} (id {}, type {})".format(gate.name, gate.id, gate.type.name))
print(" {}-to-{} LUT".format(len(gate.type.input_pins), len(gate.type.output_pins)))
boolean_functions = gate.boolean_functions
for name in boolean_functions:
print(" {}: {}".format(name, boolean_functions[name]))
print("")
Per la netlist di esempio fsm.vhd questo stampa:
FSM_sequential_STATE_REG_0_i_3_inst (id 4, type LUT6)
6-to-1 LUT
O: (!I1 & !I2 & I3 & !I4 & I5) | (I0 & !I2) | (I0 & I1) | (I0 & I3) | (I0 & I4) | (I0 & I5)
FSM_sequential_STATE_REG_0_i_2_inst (id 3, type LUT6)
6-to-1 LUT
O: (I2 & I3 & I4 & !I5) | (I1 & !I5) | (I1 & !I4) | (I1 & !I3) | (I0 & I1) | (I1 & I2)
FSM_sequential_STATE_REG_1_i_3_inst (id 6, type LUT6)
6-to-1 LUT
O: (!I1 & I4 & !I5) | (!I1 & !I3 & I4) | (I0 & I4 & !I5) | (I0 & !I3 & I4) | (!I1 & I2 & I4) | (I0 & I2 & I4) | (!I2 & !I5) | (!I2 & !I4) | (!I2 & !I3) | (!I0 & !I4) | (!I0 & !I2) | (!I0 & !I1) | (I1 & !I4) | (I1 & !I2) | (I0 & I1) | (I3 & !I5) | (I3 & !I4) | (!I0 & I3) | (I1 & I3) | (I2 & I3) | (!I4 & I5) | (!I3 & I5) | (!I0 & I5) | (I1 & I5) | (I2 & I5)
FSM_sequential_STATE_REG_1_i_2_inst (id 5, type LUT6)
6-to-1 LUT
O: (!I0 & I1 & !I2 & I3 & I4 & !I5) | (I0 & !I2 & I3 & I4 & I5)
OUTPUT_BUF_0_inst_i_1_inst (id 18, type LUT1)
1-to-1 LUT
O: !I0
OUTPUT_BUF_1_inst_i_1_inst (id 20, type LUT2)
2-to-1 LUT
O: (I0 & !I1) | (!I0 & I1)