
HAL [/hel/] est un framework complet de rétro-ingénierie et de manipulation de netlists.
Virtuellement toutes les recherches disponibles sur l'analyse de netlists reposent sur une représentation sous forme de graphe de la netlist inspectée. Au cœur, HAL fournit exactement cela : un framework pour parser des netlists de sources arbitraires, par exemple FPGA ou ASIC, en une représentation de netlist basée sur un graphe, et pour fournir les outils intégrés nécessaires au parcours et à l'analyse des portes et des fils inclus.
Notre vision est que HAL devienne l'équivalent en rétro-ingénierie matérielle d'outils comme IDA ou Ghidra. Nous voulons que HAL permette une base commune aux chercheurs et analystes pour améliorer la reproductibilité des résultats de recherche et abstraire les tâches récurrentes de base telles que le parsing de netlists.
HAL est développé activement par le groupe Embedded Security du Max Planck Institute for Security and Privacy. En plus de multiples projets de recherche, il est également utilisé dans notre cours universitaire "Einführung ins Hardware Reverse Engineering" (Introduction à la rétro-ingénierie matérielle) à l'Université de la Ruhr à Bochum (RUB).
Notez que nous avons également un ensemble de circuits de benchmark modernes et à l'état de l'art pour l'évaluation des techniques de rétro-ingénierie de netlists, disponible dans un dépôt séparé.
Ce dépôt contient une sélection de plugins soigneusement choisis :
libertyUne documentation complète des fonctionnalités de HAL du point de vue de l'utilisateur est disponible dans notre Wiki. De plus, nous fournissons une documentation complète de l'API C++ et de l'API Python.
Pour les instructions de construction de HAL, veuillez vous référer à la page dédiée de notre Wiki.
Installez HAL ou construisez-le et lancez l'interface graphique via hal -g. Vous pouvez lister toutes les options disponibles via hal [--help|-h].
Nous avons inclus quelques projets d'exemple dans le sous-répertoire examples. Pour démarrer avec un projet d'exemple, vous devez l'importer
via Import Project depuis le menu principal ou en déposant le fichier zippé dans la zone OPEN PROJECT de l'écran d'accueil.
Ce faisant, une fenêtre contextuelle demandera un répertoire avec des droits d'écriture où HAL créera le répertoire du projet et décompressera
les fichiers. N'utilisez pas d'outils externes pour la décompression car des adaptations sont faites pour que la netlist et la bibliothèque de portes
soient trouvées la prochaine fois que le projet est ouvert.
Si vous souhaitez ouvrir votre propre netlist Verilog ou VHDL, vous devez exécuter Import Netlist à la place. Cela ne fonctionnera que si
une bibliothèque de portes correspondante existe dans plugins/gate_libraries/definitions ou si vous fournissez manuellement la bibliothèque de portes.
Pour des instructions sur la création de votre propre bibliothèque de portes et d'autres tutoriels utiles, jetez un œil au wiki.
Le code d'exemple suivant se réfère à l'exemple fsm.
Utilisez le shell Python intégré ou la fenêtre de script Python pour interagir. Les deux offrent une fonctionnalité d'autocomplétion (limitée).
Listons toutes les tables de correspondance et affichons leurs fonctions booléennes :
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("")
Pour la netlist d'exemple fsm.vhd, cela affiche :
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)