HALucinator
Firmware rehosting through abstraction layer modeling.
HALucinator runs embedded firmware binaries without the original hardware. Rather
than emulating every peripheral register, it intercepts calls to the firmware's
hardware abstraction layer — HAL_UART_Transmit, spi_write, and friends —
and answers them in Python. Replacing a handful of HAL functions is usually
enough to boot a binary that would otherwise fault immediately on missing
hardware, which makes firmware reachable for debugging, analysis, and fuzzing.
Install
pip install halucinator
That is a complete, working rehosting setup. The unicorn backend ships by default because it is the only one that needs no externally-built binary, so there is nothing else to install before emulating a binary.
| Extra | Installs | For |
|---|---|---|
[net] |
scapy, pyserial | Host network / serial external devices |
[symbols] |
cle | ELF symbol extraction via hal_make_addr |
[mcp] |
mcp[cli] | The halucinator-mcp server |
[all] |
all of the above | Everything except the dev tooling |
[unicorn] still resolves as a no-op alias, so older instructions saying
pip install halucinator[unicorn] keep working.
Requires Python 3.10 or newer.
Other backends
HALucinator supports several execution backends, selected with --emulator:
unicorn, qemu, avatar2, libafl-qemu, renode, and ghidra. Only
unicorn is installable purely from PyPI — the others depend on an external
QEMU build, a Renode install, or the avatar2 fork tracked in the source
repository. See the repository
README for those setups.
Usage
Emulation is driven by YAML configuration. Configs are conventionally split into three files — memory layout, intercepts, and a symbol/address map — which HALucinator concatenates, with later files taking precedence:
halucinator -c memory.yaml -c intercepts.yaml -c addresses.yaml --emulator unicorn
Splitting them this way keeps the intercept list portable across builds of the same firmware: only the address map changes when the binary is recompiled.
Configuration sketch
Memory layout and emulated peripherals:
memories:
flash: {base_addr: 0x8000000, size: 0x200000, permissions: r-x, file: firmware.bin}
ram: {base_addr: 0x20000000, size: 0x51000}
peripherals:
logger: {base_addr: 0x40000000, size: 0x20000000, permissions: rw-, emulate: GenericPeripheral}
What to intercept, and which handler answers it:
intercepts:
- class: halucinator.bp_handlers.stm32f4.stm32f4_uart.STM32F4UART
function: HAL_UART_Transmit
symbol: HAL_UART_Transmit
- class: halucinator.bp_handlers.generic.common.ReturnZero
function: HAL_RCC_OscConfig
symbol: HAL_RCC_OscConfig
function selects the handler method (matched against the handler's
@bp_handler decorator); symbol resolves the address from the symbol map, so
prefer it over hardcoding addr. Handlers accept class_args for
per-intercept configuration.
The full schema — machine settings, watchpoints, registration_args,
run_once, and the peripheral model list — is documented in the repository
README.
Handler families
Prebuilt intercept handlers ship for common HALs and RTOSes:
- generic —
ReturnZero,ReturnConstant,SkipFunc, counters, timers - stm32f4 — STM32F4 HAL: UART, GPIO, SPI, ethernet, timers, WiFi
- libopencm3 — ADC, DMA, flash, GPIO, RCC, SPI, timer, USART
- atmel_asf_v3 — Atmel ASF: contiki, ethernet, radio, SD/MMC, timers, USART
- mbed — Mbed OS: boot, serial, timer
- vxworks — VxWorks: boot, filesystem, ethernet, interrupts, scheduler, tasks
- zephyr — Zephyr: filesystem, UART
Command-line tools
| Command | Purpose |
|---|---|
halucinator |
Run an emulation from config files |
hal_make_addr |
Extract a symbol/address map from an ELF (needs [symbols]) |
hal_dev_uart |
UART external device — the interactive console |
hal_dev_host_eth, hal_dev_host_eth_server |
Bridge emulated ethernet to the host |
hal_dev_virt_hub, hal_dev_eth_wireless |
Virtual network hub and wireless link |
hal_dev_802_15_4 |
IEEE 802.15.4 radio device |
hal_dev_irq_trigger |
Inject interrupts into a running emulation |
halucinator-mcp |
MCP server for agent-driven rehosting (needs [mcp]) |
qemulog2trace |
Convert QEMU logs to execution traces |
External devices communicate with the emulator over ZeroMQ, so they run as
separate processes — typically one terminal for hal_dev_uart and another for
halucinator itself.
Supported architectures
ARM Cortex-M · ARM (full, e.g. arm926) · AArch64 · MIPS · PowerPC · PowerPC64
Documentation
Full documentation, worked examples, the VSCode extension and debug-adapter integration, and the developer setup live in the source repository:
https://github.com/halucinator/halucinator
License and credit
GPL-3.0-or-later.
HALucinator was initially created by Abraham Clements and Eric Gustafson at Sandia National Laboratories, together with their collaborators and PhD advisors at Purdue University, UC Santa Barbara, and EPFL. The work was published at the 29th USENIX Security Symposium:
HALucinator: Firmware Re-hosting Through Abstraction Layer Emulation. Abraham Clements, Eric Gustafson, Tobias Scharnowski, Paul Grosen, David Fritz, Christopher Kruegel, Giovanni Vigna, Saurabh Bagchi, and Mathias Payer. 29th USENIX Security Symposium (USENIX Security '20), August 2020.
It has since been developed by the Sandia HALucinator team, with later contributions from the GrammaTech HALucinator team and Christopher Wright. The complete contributor list is the project's git history.
Sandia National Laboratories is a multimission laboratory managed and operated by National Technology & Engineering Solutions of Sandia, LLC, a wholly owned subsidiary of Honeywell International Inc., for the U.S. Department of Energy's National Nuclear Security Administration under contract DE-NA0003525.
Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains certain rights in this software.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file halucinator-1.9.0.tar.gz.
File metadata
- Download URL: halucinator-1.9.0.tar.gz
- Upload date:
- Size: 514.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3bcbc11d80cdbd3c588c0db13f6419ce03eafeff82bb82356ab924fb9a73050
|
|
| MD5 |
97567376b2f14f5e1e9e105b197ddd93
|
|
| BLAKE2b-256 |
3c742ec894047c5901aa17e1eabcf8248d5fd798907e5b7854eefbf8db11aed9
|
Provenance
The following attestation bundles were made for halucinator-1.9.0.tar.gz:
Publisher:
publish.yml on halucinator/halucinator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
halucinator-1.9.0.tar.gz -
Subject digest:
d3bcbc11d80cdbd3c588c0db13f6419ce03eafeff82bb82356ab924fb9a73050 - Sigstore transparency entry: 2341328751
- Sigstore integration time:
-
Permalink:
halucinator/halucinator@010625d15978bdb724be41051e83117303f43877 -
Branch / Tag:
refs/tags/v1.9.0 - Owner: https://github.com/halucinator
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@010625d15978bdb724be41051e83117303f43877 -
Trigger Event:
release
-
Statement type:
File details
Details for the file halucinator-1.9.0-py3-none-any.whl.
File metadata
- Download URL: halucinator-1.9.0-py3-none-any.whl
- Upload date:
- Size: 641.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd3365fe15559d1572ba1e922c9bbb37f7f9e68703f73474d4faa4c3c36fe896
|
|
| MD5 |
0929755ee83fb77966e46ddba53d14da
|
|
| BLAKE2b-256 |
f0289fae4c1be5a4af2775fe2c6c828a48208c2d2b9e2512fcadd553615c29a9
|
Provenance
The following attestation bundles were made for halucinator-1.9.0-py3-none-any.whl:
Publisher:
publish.yml on halucinator/halucinator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
halucinator-1.9.0-py3-none-any.whl -
Subject digest:
bd3365fe15559d1572ba1e922c9bbb37f7f9e68703f73474d4faa4c3c36fe896 - Sigstore transparency entry: 2341328757
- Sigstore integration time:
-
Permalink:
halucinator/halucinator@010625d15978bdb724be41051e83117303f43877 -
Branch / Tag:
refs/tags/v1.9.0 - Owner: https://github.com/halucinator
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@010625d15978bdb724be41051e83117303f43877 -
Trigger Event:
release
-
Statement type: