Bare Metal Reverse Engineering
SolaSec (Co-founder · Solosack)
DEF CON 33 · Day 1 · Main Stage
Overview
This talk, "Bare Metal Reverse Engineering" by SolaSec, dives deep into the intricate world of analyzing firmware that runs directly on hardware without a conventional operating system. SolaSec, co-founder of Solosack and an experienced embedded software developer, guides the audience through the challenges and methodologies of reverse engineering raw, stripped binaries often found in bare metal and Real-Time Operating System (RTOS) environments, specifically focusing on ARM 32-bit microcontrollers. The presentation emphasizes that understanding firmware development is crucial for effective firmware reverse engineering.

Key moments
- 0:00 Talk overview: bare metal RE, firmware dev, tools.
- 0:54 Understanding bare metal operating systems and characteristics.
- 2:28 Benefits and importance of learning firmware development.
- 4:04 Explaining firmware layers: BSP, HAL, and RTOS.
- 5:02 Introduction to ARM assembly and x86 differences.
- 6:00 Understanding ARM's confusing Thumb instruction set mode.
- 6:40 Overview of ARM general purpose and specific registers.
Bare Metal Reverse Engineering
Speakers: SolaSec, Co-founder, Solosack
Conference: DEF CON
YouTube: https://www.youtube.com/watch?v=zfxKbsLKb3E
Overview
This talk, "Bare Metal Reverse Engineering" by SolaSec, dives deep into the intricate world of analyzing firmware that runs directly on hardware without a conventional operating system. SolaSec, co-founder of Solosack and an experienced embedded software developer, guides the audience through the challenges and methodologies of reverse engineering raw, stripped binaries often found in bare metal and Real-Time Operating System (RTOS) environments, specifically focusing on ARM 32-bit microcontrollers. The presentation emphasizes that understanding firmware development is crucial for effective firmware reverse engineering.
The talk is particularly relevant for security researchers, embedded developers, and anyone interested in the low-level aspects of hardware and software interaction. It highlights an often-overlooked area of reverse engineering, contrasting it with the more common Intel x86 analysis. By demystifying ARM assembly, showcasing practical firmware development techniques, and introducing powerful tools like Ghidra with specialized plugins, SolaSec provides a comprehensive roadmap for tackling the complexities of bare metal firmware, ultimately aiming to recover application-level source code from highly optimized and obfuscated binaries.
The significance of this topic lies in the increasing prevalence of embedded systems across various critical infrastructure, IoT devices, and medical implants. Vulnerabilities at the firmware level can have profound impacts, and the ability to analyze these systems is paramount for both identifying and mitigating security risks. SolaSec argues that firmware reverse engineering is a valuable, yet relatively untapped, skill set that offers both intellectual challenge and career opportunities.
Background
▶ Watch: Talk overview: bare metal RE, firmware dev, tools. (0:00)
Bare metal environments are fundamentally different from systems running full-fledged operating systems like Linux or Windows. In bare metal, software interacts directly with hardware, often lacking the sophisticated layers of abstraction and privilege separation found in higher-level systems. Key characteristics include lightweight scheduling (or none at all), minimal extra abstraction, and the common practice of direct register access. When firmware is extracted from a board, it's typically a raw binary, often stripped of symbols and debugging information, making reverse engineering a significant challenge.
SolaSec stresses the importance of understanding firmware development to effectively reverse engineer it. Firmware, defined as the low-level software interacting fundamentally with hardware, teaches invaluable lessons about hardware architecture, memory structures, and coding patterns. The speaker humorously refers to firmware developers as having "full stack elitism" due to the depth of knowledge required. Despite its complexity, firmware reverse engineering is presented as an "untapped market" with good compensation and inherent enjoyment.
The spectrum of low-level systems covered ranges from pure bare metal (e.g., simple microcontrollers) to those utilizing RTOSes like FreeRTOS, QNX, or µC/OS-III. While RTOSes introduce scheduling and task management, they are still considered close to bare metal from a reverse engineering perspective compared to embedded Linux or Windows IoT. The talk specifically focuses on ARM 32-bit microcontrollers, a dominant architecture in embedded systems.
Firmware is typically organized into distinct layers:
- Board Support Package (BSP): This is the lowest layer, comprising specific, fundamental calls to hardware registers (e.g., setting a GPIO pin or enabling a peripheral clock). It's highly specific to the hardware.
- Hardware Abstraction Layer (HAL): Built atop the BSP, HALs provide a more generalized, easier-to-use interface for interacting with hardware peripherals. Manufacturers like STMicroelectronics (for STM32) provide extensive HALs to simplify development.
- RTOS (Real-Time Operating System): Above the HAL (though sometimes integrated), an RTOS manages tasks, scheduling, threads, queues, semaphores, and other concurrency primitives.
Understanding these layers is crucial because they manifest differently in disassembled code. While HALs simplify development, they often introduce more complex, abstracted code from a reverse engineering standpoint, requiring specialized techniques to unravel.
Key Findings
▶ Watch: Benefits and importance of learning firmware development. (2:28)
The central challenge addressed by SolaSec is the reverse engineering of raw, stripped bare metal binaries where conventional tools and techniques for higher-level operating systems often fall short. The talk's key finding is that a multi-faceted approach, combining deep knowledge of ARM assembly with an understanding of firmware development patterns and leveraging specialized Ghidra tools, can effectively deconstruct these complex binaries and recover meaningful application logic.
The core contributions and findings presented are:
- ARM Assembly Mastery: Emphasizing that proficiency in ARM assembly, including its nuances like Thumb mode, register usage (R0-R12 general purpose, R13 Stack Pointer, R14 Link Register, R15 Program Counter), instruction sets (Load/Store, Branching), and relative addressing, is non-negotiable for effective bare metal RE.
- Firmware Development as a RE Aid: Demonstrating that knowing how firmware is built (both the "hard way" via direct register manipulation in BSP and the "easy way" via HALs) provides critical context for interpreting disassembled code. This allows reverse engineers to recognize common patterns and understand the intent behind low-level operations.
- Ghidra-Centric Toolchain for Automation: Highlighting Ghidra's powerful capabilities when augmented with specific plugins:
- SVD Loader (by Level Down Security): Automates the parsing of SVD (System View Description) files (XML representations of microcontroller registers) to annotate Ghidra's memory map. This transforms generic memory addresses into meaningful peripheral registers, significantly accelerating BSP-level analysis.
- Typeloader (speaker's tool): Automatically parses HAL header files to create corresponding data types within Ghidra. This enables accurate type-casting of complex HAL structures in the decompiled output, restoring the original high-level HAL function calls.
- BSIM (Binary Similarity, NSA/Ghidra): A technique that pre-compiles known libraries (like RTOSes or HALs) into a database. This allows Ghidra to identify and label known functions in an unknown binary, effectively "weeding out" boilerplate code and allowing the reverse engineer to focus on the custom application logic.
Ultimately, the key finding is that by systematically applying these techniques and tools, it's possible to reconstruct the original source code, or a very close approximation, from stripped bare metal firmware, moving from raw assembly instructions all the way up to identifiable application and library calls.
Technical Deep Dive
▶ Watch: Explaining firmware layers: BSP, HAL, and RTOS. (4:04)
Understanding the intricacies of ARM assembly is foundational to bare metal reverse engineering. Unlike Intel x86, which is a Complex Instruction Set Computer (CISC), ARM is a Reduced Instruction Set Computer (RISC). This means ARM instructions are generally simpler, fixed-length, and execute faster, but often require more instructions to achieve the same task as a single x86 instruction. Key differences include ARM's dedicated registers, simpler decoding, and a more stripped-down architecture.
A particularly confusing aspect of ARM is Thumb mode. While ARM instructions are always 32-bit, Thumb mode introduces 16-bit instructions, which can improve code density. Many ARM microprocessors switch dynamically between ARM and Thumb modes, based on the least significant bit of the instruction address, which complicates analysis due to varying byte offsets.
ARM processors feature several important registers:
- General-purpose registers: R0 through R12, used for data manipulation and function arguments.
- Special-purpose registers:
- R13 (Stack Pointer - SP): Points to the top of the stack.
- R14 (Link Register - LR): Stores the return address for function calls.
- R15 (Program Counter - PC): Points to the next instruction to be executed.
Data types on ARM include words (32-bit), halfwords (16-bit), and bytes (8-bit), reflected in instructions like LDR (Load Word), LDRH (Load Halfword), and LDRSB (Load Signed Byte).
Core ARM assembly instructions involve:
- Loading and Storing: Instructions like
LDR(Load Register) move data from memory into a register, whileSTR(Store Register) moves data from a register into memory. For example,LDR R2, [R0]loads the value at the address in R0 into R2. - Branching:
B(Branch) instructions control program flow, similar togotostatements. Conditional branches likeBEQ(Branch if Equal) andBNE(Branch if Not Equal) act asifstatements.BL(Branch with Link) is used for function calls, saving the return address in the Link Register.BX(Branch and Exchange) is used for switching between ARM and Thumb modes. - Relative Addressing: A common compiler optimization where memory accesses are relative to a base register (often the PC) plus an offset, rather than a direct absolute address. For instance,
LDR R2, [R0, #4]loads the value from the address R0 + 4 into R2. - Stack Frames: Functions typically use stack frames to manage local variables and save/restore registers. The prologue of a function sets up the stack frame (e.g., pushing LR and other registers), and the epilogue restores them before returning.
SolaSec illustrates these concepts with a simple C function check(int a, int b) and its corresponding ARM assembly, showing how GEF (GDB Enhanced Features) can be used to step through the code, observe register changes, and understand stack frame manipulation.
The talk then transitions to firmware development, demonstrating the "hard way" (BSP) versus the "easy way" (HAL).
The Hard Way (BSP): To initialize a single GPIO pin (e.g., PC2) on an STM32 microcontroller, one must directly manipulate peripheral registers. This involves:
- Enabling the Peripheral Clock: Accessing the RCC (Reset and Clock Control) peripheral boundary address (e.g.,
0x40023800on STM32) and setting a specific bit (e.g.,GPIOC_EN) in its clock enable register. - Configuring the GPIO Mode: Accessing the GPIO Port C base address and setting specific bits in its mode register to configure PC2 as an input.
- Configuring Pull-up/Pull-down: Setting bits in the GPIO pull-up/pull-down register.
Direct register manipulation requires careful bitwise logic (e.g., ORing with a mask to set bits, ANDing with the complement of a mask to clear bits) to avoid inadvertently modifying other peripheral configurations. This process is tedious and highly specific to the microcontroller's datasheet.
The Easy Way (HAL): In contrast, using a HAL (like ST's STM32 HAL) simplifies development significantly. For instance, setting up a UART peripheral involves creating an instance of a pre-built structure (e.g., UART_HandleTypeDef) and calling high-level HAL functions (e.g., HAL_UART_Init). The HAL abstracts away the direct register writes, making the code much cleaner and portable across similar STM32 devices, but also more complex to reverse engineer without proper tooling. This complexity arises because discrete, direct register calls are replaced by numerous function calls within the HAL, which then ultimately perform the register manipulation.
Demo / Proof of Concept
▶ Watch: Understanding ARM's confusing Thumb instruction set mode. (6:00)
The practical demonstration focuses on using Ghidra, the NSA's open-source reverse engineering framework, as the primary tool for bare metal analysis, augmented by specialized scripts and plugins.
The general Ghidra workflow for bare metal firmware begins with:
- Importing the Binary: The raw firmware binary is imported into Ghidra.
- Processor Configuration: The processor is set to
ARM:LE:32:Cortex(Little Endian, 32-bit, Cortex-M). The speaker also mentions adding a "flash mirror block" which is a common practice for Cortex-M devices where flash memory can be mapped to address 0. - Memory Map Configuration: Before analysis, the memory map is manually configured based on the microcontroller's datasheet. This involves defining the Flash, RAM, and peripheral regions with their correct base addresses and sizes.
- Initial Analysis: Ghidra's auto-analysis is initiated, specifically leveraging the "ARM aggressive instruction finder" to improve disassembly accuracy, especially with Thumb mode instructions.
Once analyzed, Ghidra presents its familiar interface with the disassembly listing, decompiler window (attempting to recover C-like source code), and facilities for renaming/retyping functions and searching for strings. However, the raw decompilation of bare metal firmware initially appears as generic pointer manipulations and address calculations, far from readable source code.
To bridge this gap, SolaSec introduces three critical enhancements:
- SVD Loader (by Level Down Security): This Ghidra script automates the tedious process of mapping peripheral registers.
- Functionality: It parses SVD (System View Description) files, which are XML documents provided by chip manufacturers that detail all peripheral registers, their addresses, and bitfield layouts.
- Application: After running the script and selecting the appropriate SVD file for the target microcontroller, Ghidra's memory map is updated. Generic addresses that were previously
0x40023800now become named peripherals likeRCC_BASEorGPIOC_MODER. - Impact: When Ghidra decompiles code that accesses these addresses, it can now infer the access to a specific peripheral register. By then type-casting these generic pointers (e.g.,
(uint32_t )0x40023800) to the correct peripheral structure (e.g.,RCC_TypeDef), the decompiler output dramatically transforms. The previously unreadable code like(uint32_t *)(param_1 + 0x38)becomesRCC->AHB1ENR, revealing the original intent of enabling the clock for a peripheral. This allows the reverse engineer to see code that closely resembles the original BSP-level source.
- Typeloader (SolaSec's Custom Tool): This tool extends the type-casting capability to the HAL layer.
- Functionality: It parses the actual HAL header files (e.g.,
stm32l4xx_hal_uart.h) for the specific microcontroller family. - Application: It creates corresponding data types within Ghidra for all the HAL structures (e.g.,
UART_HandleTypeDef) and functions. - Impact: With these HAL data types loaded, the reverse engineer can then identify patterns in the decompiled code that resemble HAL function calls or structure manipulations. By type-casting generic structures to their proper
HAL_types, Ghidra can reconstruct the high-level HAL function calls (e.g.,HAL_UART_Init(&huart1)), effectively recovering the "easy way" firmware development source code.
- BSIM (Binary Similarity - NSA/Ghidra): This powerful feature helps filter out known boilerplate code.
- Functionality: BSIM allows the creation of a database of known function signatures. This is achieved by taking a known project (e.g., an STM32 project using HAL and FreeRTOS), compiling it, reversing it in Ghidra, and then exporting its function signatures to a BSIM database.
- Application: When analyzing an unknown firmware binary, the BSIM database can be loaded. Ghidra then automatically searches for functions in the unknown binary that are structurally similar to those in the database.
- Impact: This is particularly useful for identifying common library functions, RTOS calls (like
osThreadNewfor creating a new thread), or standard HAL functions. By setting similarity and confidence thresholds, the reverse engineer can quickly label these known functions, saving immense time. The primary benefit is the ability to "weed out" generic RTOS or HAL code that is not part of the custom application logic, allowing the researcher to focus on the unique and potentially vulnerable parts of the firmware.
Through this combination of Ghidra's core capabilities and these specialized tools, SolaSec demonstrates how to systematically move from a raw, stripped binary to an almost exact reconstruction of the original C source code, making the application logic discernable.
Defensive Implications
▶ Watch: Overview of ARM general purpose and specific registers. (6:40)
Understanding bare metal reverse engineering provides defenders with critical insights into the security posture of embedded systems. First and foremost, it enables a deeper level of vulnerability research than what is possible with higher-level analyses. By being able to dissect stripped firmware, defenders can identify subtle flaws in direct register access, improper peripheral configuration, or insecure use of HAL functions that might lead to privilege escalation, denial of service, or data exfiltration.
For firmware developers, this talk underscores the importance of secure coding practices even at the lowest levels. Misconfigurations in the BSP (e.g., not properly clearing sensitive registers, enabling unnecessary peripherals, or insecure memory access patterns) can introduce significant attack surfaces. While HALs abstract complexity, their incorrect usage can still lead to vulnerabilities. Developers should also be aware that their compiled code, even when stripped, can be meticulously reconstructed, meaning that security-by-obscurity is not a reliable defense.
Furthermore, these techniques are invaluable for supply chain security. Organizations deploying embedded devices can use bare metal reverse engineering to audit third-party firmware for malicious implants, backdoors, or unintended functionality, especially when source code is unavailable. It also aids in incident response for embedded devices, allowing forensic analysis of compromised firmware to understand attack vectors and persistence mechanisms.
Finally, knowing the tools and methodologies presented (Ghidra, SVD Loader, Typeloader, BSIM) allows defenders to build more robust firmware analysis pipelines. This can include automated scanning for known vulnerable function patterns or deviations from expected behavior in their own products, proactively strengthening their embedded systems against sophisticated attacks.
Key Takeaways
- Bare metal reverse engineering is a specialized and valuable skill, crucial for understanding and securing embedded systems, IoT, and critical infrastructure.
- Deep understanding of ARM assembly is non-negotiable, including Thumb mode, register usage (R0-R15), memory access patterns (Load/Store, relative addressing), and branching logic.
- Knowledge of firmware development (BSP and HAL) is key to interpreting disassembled code, as it helps identify the intent behind low-level register manipulations and high-level library calls.
- Ghidra, augmented with specific plugins, is a powerful toolset for bare metal reverse engineering, offering features like SVD Loader for peripheral mapping, Typeloader for HAL type reconstruction, and BSIM for binary similarity analysis.
- Automated tools significantly accelerate the process by allowing precise type-casting of registers and HAL structures, enabling the reconstruction of near-original source code from stripped binaries.
- BSIM is essential for filtering out boilerplate code (e.g., RTOS or standard library functions), allowing reverse engineers to focus their efforts on the custom application logic, which is often the most relevant for security analysis.
About the Speaker(s)
SolaSec is the co-founder of Solosack, a company focused on embedded security and related services. His background is in electrical engineering, which provided him with a strong foundation in hardware. He spent a number of years as an embedded software developer, gaining extensive experience in firmware development. This practical experience in building firmware directly translated into his expertise in firmware reverse engineering, which forms the core of this talk. SolaSec is passionate about the field and can be found on social media under the handle "Sole Deo Gloria." He also actively participates in events like the DEF CON Biohacking Village CTF, offering hands-on demonstrations related to his work.
Reviews
Dr. Zero (Offensive Security Researcher) — SOLID
Competent, well-structured introduction to bare metal firmware RE on ARM with a practical Ghidra-centric toolchain. The content is solid and the speaker clearly knows the domain, but this is fundamentally a tutorial aimed at practitioners who haven't worked in this space before — not novel research, not new attack surfaces, not anything that will make a vendor lose sleep.
Heather Calloway (CISO) — WEAK
A technically competent tutorial on ARM firmware reverse engineering with a solid toolchain walkthrough, but it never climbs out of the lab. The defensive implications section is bolted on and generic — it tells defenders they should do firmware analysis without telling anyone in a position of authority what that actually requires institutionally.