
HAL [/hel/] ist ein umfassendes Framework zur Reverse-Engineering und Manipulation von Netlisten.
Nahezu alle verfügbaren Forschungen zur Netlist-Analyse arbeiten mit einer grafbasierten Darstellung der untersuchten Netlist. Im Kern bietet HAL genau das: Ein Framework zum Parsen von Netlisten beliebiger Quellen, z. B. FPGAs oder ASICs, in eine grafbasierten Netlist-Darstellung und die notwendigen integrierten Werkzeuge zur Traversierung und Analyse der enthaltenen Gatter und Netze.
Unsere Vision ist, dass HAL das Hardware-Reverse-Engineering-Äquivalent von Werkzeugen wie IDA oder Ghidra wird. Wir möchten, dass HAL eine gemeinsame Basis für Forscher und Analysten schafft, um die Reproduzierbarkeit von Forschungsergebnissen zu verbessern und wiederkehrende grundlegende Aufgaben wie das Parsen von Netlisten zu abstrahieren.
HAL wird aktiv entwickelt von der Embedded Security Group des Max-Planck-Instituts für Sicherheit und Privatsphäre. Neben mehreren Forschungsprojekten wird es auch in unserer Universitätsvorlesung "Einführung ins Hardware Reverse Engineering" (Introduction to Hardware Reverse Engineering) an der Ruhr-Universität Bochum (RUB) eingesetzt.
Beachten Sie, dass wir auch eine Reihe moderner hochmoderner Benchmark-Schaltungen für die Bewertung von Netlist-Reverse-Engineering-Techniken in einem separaten Repository bereitstellen.
Dieses Repository enthält eine Auswahl kuratierter Plugins:
libertyEine umfassende Dokumentation der HAL-Funktionen aus Benutzersicht ist in unserem Wiki verfügbar. Darüber hinaus bieten wir eine vollständige C++ API und Python API Dokumentation.
Anleitungen zum Bau von HAL finden Sie auf der entsprechenden Seite in unserem Wiki.
Installieren Sie HAL oder bauen Sie HAL und starten Sie die GUI via hal -g. Sie können alle verfügbaren Optionen via hal [--help|-h] auflisten.
Wir haben einige Beispielprojekte im Unterverzeichnis examples beigefügt. Um mit einem Beispielprojekt zu beginnen, müssen Sie es
via Import Project aus dem Hauptmenü importieren oder die gezippte Datei in den Bereich OPEN PROJECT des Willkommensbildschirms ziehen.
Dabei öffnet sich ein Popup, das ein Verzeichnis mit Schreibrechten anfordert, in dem HAL das Projektverzeichnis erstellt und die Dateien
entpackt. Verwenden Sie keine externen Werkzeuge zum Entpacken, da Anpassungen vorgenommen werden, damit Netlist und Gatterbibliothek
beim nächsten Öffnen des Projekts gefunden werden.
Falls Sie Ihre eigene Verilog- oder VHDL-Netlist öffnen möchten, müssen Sie stattdessen Import Netlist ausführen. Dies funktioniert nur, wenn
eine passende Gatterbibliothek in plugins/gate_libraries/definitions vorhanden ist oder Sie die Gatterbibliothek manuell bereitstellen.
Anleitungen zum Erstellen Ihrer eigenen Gatterbibliothek und andere nützliche Tutorials finden Sie im Wiki.
Der folgende Beispielcode bezieht sich auf das fsm-Beispiel.
Verwenden Sie die integrierte Python-Shell oder das Python-Skriptfenster zur Interaktion. Beide bieten eine (eingeschränkte) Autovervollständigung.
Lassen Sie uns alle Lookup-Tabellen auflisten und ihre booleschen Funktionen ausgeben:
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("")
Für die Beispiel-Netlist fsm.vhd wird dies ausgegeben:
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)