---
title: 'Pemu: Firmware Rehosting for ENS Fuzzing'
url: https://www.emergentmind.com/topics/pemu
type: topic
---

# Pemu: Firmware Rehosting for ENS Fuzzing

Searching arXiv for the specified paper and closely related context.
Pemu is a **protocol-aware firmware rehosting framework** for effective, automated, and scalable fuzzing of **embedded network stacks**. It targets a central limitation of firmware rehosting: existing rehosting-based fuzzers usually feed firmware **raw bytes** through modeled peripherals, which is often inadequate for inputs that are **deeply structured, layered, stateful, and protocol-dependent**. In embedded network stacks, this causes fuzzing inputs to fail at early validation layers, repeatedly exercising low-level parsing and checksum logic rather than reaching the **transport layer** or **application logic**. Pemu addresses this by automatically detecting and handling the use of network protocols in firmware, generating valid network packets that transparently encapsulate fuzzing data and allow it to flow into deeper firmware logic [2509.13740].

## 1. Problem setting and design objectives

Firmware rehosting enables researchers to run embedded firmware in an emulator instead of on physical hardware, which supports scalable fuzzing. The difficulty, as identified by Pemu, is that embedded systems are designed for specialized use cases and therefore expose unique and diverse communication stacks. For **embedded network stacks (ENSs)**, network input is not merely byte-oriented; it is multi-layered, protocol-specific, and frequently dependent on prior message exchanges. Under those conditions, random byte mutation almost always fails at early checks such as frame formats, checksums, static values, address fields, and sequencing requirements [2509.13740].

Pemu is built around two stated requirements for an optimal rehosting solution for ENS fuzzing. First, it should **need no hardware setup or target-specific seed traffic/configuration**. Second, it should **automatically reach deeper protocol and application logic**, rather than only low-level parsers. This positioning is explicitly contrasted with several existing approaches. Typical rehosting fuzzers treat network input like generic peripheral data and are not packet-aware. AFLNet depends on existing traffic captures, which are difficult to obtain for embedded targets without hardware and manual effort. EmNetTest requires seed packets and often source-code or target knowledge to specify metadata and network configuration, and it mostly tests up to the transport layer rather than full firmware application logic [2509.13740].

A further complication is protocol state. Embedded stacks may require multi-packet exchanges such as ARP for MAC discovery, DHCP for IP assignment, TCP SYN/SYN-ACK exchange, or protocol-specific request/reply sequences. Pemu treats this not as an exceptional case but as a core property of ENS fuzzing. This suggests that the framework is designed not only to validate packet syntax but also to maintain enough protocol context for deeper execution to become reachable [2509.13740].

## 2. Protocol-aware methodology

Pemu’s central mechanism is a **self-configuring virtual network** between the fuzzer and the firmware. Raw fuzzing input is automatically encapsulated into **valid packets** for the current protocol stack; firmware output is parsed to extract state such as addresses, identifiers, and sequence numbers; the firmware is actively probed to discover which protocols are present; and the known protocol stack is iteratively expanded. The stated purpose is to let fuzzing data flow into **deeper layers** of the network stack, including application logic [2509.13740].

The packet model is explicitly layered. A network packet is represented as a stack of protocol layers, each with a header and a body, where the body of lower layers contains the next protocol. Header fields may be **static** values, **references** to upper or lower layers, **computed** values such as checksums, **stateful** values such as sequence numbers and flags, or fuzzable fields. Pemu uses protocol grammars derived from official specifications and encoded in **YAML**. These grammars describe fragmentation, compression, length fields, checksums, fixed header values, and references between layers. The grammars are manually derived once per protocol family, and Pemu ships with YAML configurations for **38 protocols** [2509.13740].

Fuzzing input is used to populate every field that is not semantically rigid. Consequently, fuzzing can affect payloads, mutable header fields, metadata, and boundary conditions in error handling. Pemu also supports **stateful encapsulation**, meaning that it can generate **sequences** of packets rather than a single packet when required by the protocol. The paper lists TCP handshake packets, DHCP message exchanges, fragmentation metadata, and sequence-number updates as examples. In addition, Pemu supports deliberate fault injection through malformed fields to test parser error paths, motivated by prior work indicating that many embedded network vulnerabilities depend on one or two bad header fields [2509.13740].

State extraction is the complementary mechanism. Pemu parses outgoing network frames and extracts information including MAC addresses, IPv4/IPv6 addresses, PAN IDs, transaction IDs, nonces, sequence numbers, and protocol-specific identifiers. The paper distinguishes **unsolicited** packets, such as those sent during initialization or periodically, from **solicited** packets sent in response to received traffic; both are used for state extraction. After extraction, Pemu performs parsing-based analysis to choose the most likely consistent state for the next fuzzing round. This is described as a self-correcting loop: candidate addresses, IDs, and nonces are collected, a plausible configuration is inferred, and that configuration is then used to improve subsequent packet generation [2509.13740].

## 3. Active probing and iterative protocol-tree recovery

A principal novelty of Pemu is **automatic protocol detection by active probing**. Because the system starts with no prior knowledge, it must determine which protocol layers are present. Pemu therefore generates candidate packets for many protocol types and observes how the firmware responds. Its key insight is that malformed packets often reach common error handlers, whereas valid packets progress further and exercise distinct code paths. For this reason, Pemu uses **unique basic-block coverage**, not merely total coverage, as the signal for protocol acceptance [2509.13740].

The use of unique coverage addresses a specific failure mode of naïve probing. A malformed packet can produce high aggregate coverage if it triggers large error-handling paths. Pemu therefore prefers packet types that produce **uniquely covered basic blocks**, which are treated as more indicative of actual protocol acceptance. Probe packets are **syntactically valid**, and all fuzzing bytes are set to zero so that random content does not accidentally mimic unsupported protocol fields. Probing is performed while fuzzing is paused in order to keep the configuration consistent [2509.13740].

Protocol discovery is incremental and is described as **iterative protocol-tree recovery**. The process begins with an empty network configuration, probes candidate packet types, identifies the next reachable protocol layer from coverage, adds that protocol to the configuration, and then repeats. The paper illustrates this with an MQTT server over TCP/IP. Initially no protocols are known; the firmware sends ARP traffic, allowing Pemu to detect ARP and Ethernet; the firmware later performs DHCP, enabling detection of DHCP and UDP; after IP assignment, TCP becomes reachable; and finally MQTT can be fuzzed through the correct packet stack. The configuration thus evolves from a frame-oriented view toward Ethernet, ARP, IPv4, UDP/TCP, and then DHCP or MQTT [2509.13740].

The framework also includes a robustness property for mistaken additions. If Pemu accidentally adds an unused protocol, the fuzzer is not forced to use it for every input. Because the fuzzer can choose encapsulation depth and coverage feedback naturally deprioritizes unhelpful choices, incorrect expansions do not necessarily destabilize the campaign. This suggests that protocol-tree recovery is designed to remain useful even when inference is imperfect [2509.13740].

## 4. Architecture, implementation, and platform model

Pemu is intentionally **platform-independent** and exposes a minimal API to the rehosting platform: `get_packet` and `send_packet`. The underlying rehosting system remains responsible for deciding when a packet should be requested, how packets are delivered to firmware memory, and how DMA or peripherals are modeled. This division of responsibilities is central to Pemu’s claim of portability across differing rehosting styles [2509.13740].

Its architecture comprises three main components. The **encapsulation module** takes raw fuzzing input, builds valid packets, can operate at different encapsulation depths, and can generate packets in probe mode. The **state extractor** parses outgoing frames and stores discovered addresses, IDs, sequence numbers, and related values. The **probing/analysis component** runs probe packets, compares coverage, and determines which protocol layer is present next [2509.13740].

The implementation is in **Python**, comprises about **3,600 lines of code**, and is released as open source with patches to supported platforms. YAML protocol definitions are provided for **38 protocols**. Within YAML, header fields are categorized as static values, length values, references to higher layers, handler-based computed values, state-related values, and fuzzable remaining fields. For complex fields such as IEEE 802.15.4 FCF, fragmentation, compression, and checksums, Pemu allows custom handler functions; the paper characterizes this as a one-time effort per new protocol [2509.13740].

A plausible implication is that Pemu’s abstraction level is deliberately intermediate: it is not a full replacement for a rehosting system, but neither is it a simple packet mutator. Instead, it acts as a protocol-aware layer on top of rehosting, transforming generic fuzzing input into syntactically and semantically valid traffic and feeding protocol state back into subsequent generation [2509.13740].

## 5. Integration with rehosting tools

Pemu is integrated with **Fuzzware**, **Hoedur**, and **SEmu**, which the paper presents as three distinct rehosting styles: **single-stream** for Fuzzware, **multi-stream** for Hoedur, and **spec-based** for SEmu. Because network peripheral and DMA handling differ across platforms, the paper proposes two integration strategies. **Hook-based integration** inserts hooks at the points where packet data is first accessed and injects Pemu-generated packets into the correct RAM buffer. **Peripheral emulation** instead implements a network peripheral that handles MMIO interactions and autonomously injects packets [2509.13740].

The concrete integration effort differs substantially across the three platforms.

| Platform | Integration form | Reported implementation detail |
|---|---|---|
| Fuzzware | Network peripherals manually implemented for four MCUs | About 435 lines of Python on average |
| Hoedur | Hooks for packet reception/transmission across four MCUs | About 184 lines of Rust per MCU; total 823 lines |
| SEmu | Integrated via an existing Ethernet peripheral | Only 34 lines of Python |

These figures are presented as evidence that the same protocol-aware layer can be connected to different rehosting substrates with different packet-delivery mechanisms. At the same time, they show that the amount of platform work remains contingent on the maturity of the underlying rehosting environment, especially with respect to DMA and peripheral modeling [2509.13740].

The paper explicitly treats some of this integration burden as a limitation of the broader rehosting ecosystem rather than of Pemu itself. If DMA modeling is unavailable, one must locate a HAL function once per HAL and write an MCU-specific handler to identify packet buffers and inject packets. This places Pemu within a layered tooling model: protocol awareness is decoupled from, but dependent on, lower-level emulator support [2509.13740].

## 6. Evaluation, findings, and limitations

The evaluation covers **9 firmware samples** spanning **4 MCUs**, **3 vendors**, **6 OSes**, and **5 network stacks**, with protocol suites including Ethernet/TCP-IP, BLE, and IEEE 802.15.4 / 6LoWPAN. The experiments use **5 fuzzing runs per sample**, reporting medians and **95% confidence intervals**. Across all three integrated platforms, the paper concludes that Pemu is applicable beyond a single emulator architecture, supporting its claim of platform independence [2509.13740].

On coverage, Pemu consistently improves average basic-block coverage relative to baseline rehosting fuzzers. The reported improvements are **8.5%** for SEmu, **40.7%** for Fuzzware, and **39.2%** for Hoedur. The paper attributes SEmu’s smaller gains to the limitation that SEmu can only send one packet per emulation run. Coverage gains are strongest for TCP/IP targets, where IPv4 imposes strict early checks and valid addresses supplied via DHCP or state extraction materially affect reachability. For IEEE 802.15.4 / 6LoWPAN targets, gains are smaller or mixed in some cases because lower layers are more permissive and compressed or fragmented formats are complex, though Pemu still helps reach application-layer handlers such as CoAP and SNMP. BLE targets are described as harder because of stack complexity, vendor-specific components, single-packet execution constraints, and early dependence on correct addresses; the paper reports around **15%** improvement for the BLE Heart Rate Monitor on Fuzzware, about **12%** on Hoedur, and mixed results for the nimBLE sample depending on whether the correct BLE address was extracted [2509.13740].

The timing data provides additional detail on protocol inference. Using Fuzzware as an example, the paper reports a median time of **47 minutes** to detect the **first protocol**, **12 hours 33 minutes** to detect the **last protocol**, and **1 hour 35 minutes** to detect the **first value**. On average, protocol configurations were detected **3.75 times** per campaign and new values **1.4 times** per campaign. After initial protocol discovery, Fuzzware typically reached the **network layer** about **25 minutes** later and the **transport layer** about **3 hours 5 minutes** later. The baseline rarely reached transport-layer code; Pemu made that practical [2509.13740].

In direct comparison with EmNetTest, using EmNetTest’s dataset of **12 known vulnerabilities** across **3 ENSs**, Pemu rediscovered **all 12**, all on network or transport layers. Several required **multiple sequential packets**, which the paper uses to demonstrate support for protocol state and sequencing. Pemu also found **3 additional bugs** in the FreeRTOS-plus-TCP stack that EmNetTest missed [2509.13740].

Across the broader evaluation, Pemu found **five previously unknown software faults**: **three bugs in FreeRTOS-plus-TCP**, **one OOB write in LwIP**, and **one OOB read in STM32F767 HAL**. The LwIP OOB write, found in a SEmu dataset sample, could let an attacker control the PC by overwriting data structures behind the network buffer and was related to a sample misconfiguration. The STM32F767 HAL OOB read was caused by a thread synchronization or race condition, triggered by a valid TCP segment plus periodic ARP broadcasts overlapping; it was disclosed to the vendor, which acknowledged the issue and issued an advisory. The paper emphasizes that this last bug is not in the network stack itself but is only reachable when valid network traffic is delivered, supporting the claim that end-to-end firmware rehosting can expose faults beyond a standalone stack model [2509.13740].

The authors also tested generality beyond network stacks by adding **Modbus** support and fuzzing a heat-press firmware. Pemu again outperformed the baseline because valid **CRC-16** checksum generation mattered and random packets almost never satisfied the checksum constraint. This is presented as evidence that packet-aware encapsulation is useful for structured communication protocols beyond classic IP networking [2509.13740].

The paper is explicit about several limitations. Pemu assumes that the rehosting platform can write frames into the firmware’s receive memory and read transmitted frames back out. Integration can require manual per-platform work when DMA modeling is unavailable. Hoedur experiences a performance overhead of around **2x to 10x** because Hoedur is Rust-based while Pemu is implemented in Python. Pemu also depends on the base rehosting platform reaching the point where packets are processed at all; if network functionality is not reached, Pemu cannot help. Finally, encryption and authentication remain difficult. Pemu can integrate encryption-like transformations similarly to compression, but it cannot bypass cases requiring pre-shared secrets, private keys, or authenticated handshakes [2509.13740].

Taken together, these results position Pemu as a **network-protocol-aware layer on top of firmware rehosting** that combines **encapsulation grammars**, **state extraction from outgoing packets**, **coverage-based active probing**, and **iterative protocol-tree discovery**. The paper’s main empirical claim is that these mechanisms let fuzzers move beyond shallow packet parsing and reach deeper embedded network code and application logic, with measurable coverage gains, complete rediscovery of the benchmark vulnerabilities considered, and discovery of previously unknown faults [2509.13740].

Source: https://www.emergentmind.com/topics/pemu