Skip to content

Firmware Structure

IoT firmware is a complex, multi-layered system designed to operate embedded hardware with minimal resource usage. Understanding its structure is critical for reverse engineering, security analysis, and vulnerability assessment. A typical IoT firmware image consists of several core components, each serving a distinct role in system initialization, operation, and security. These components are often tightly integrated, requiring careful analysis to uncover hidden behaviors or weaknesses.


Bootloader: The First Execution Stage

The bootloader is the first software executed when an IoT device powers on. Its primary responsibilities include:
- Initializing hardware (clocks, memory, peripherals)
- Verifying firmware integrity (e.g., cryptographic signatures)
- Loading and transferring control to the kernel or application

Key characteristics:
- Often stored in read-only memory (ROM) or flash
- May include secure boot mechanisms (e.g., RSA signatures)
- Can be proprietary or open-source (e.g., U-Boot, SPL)

Analysis example:
To inspect a bootloader binary, use tools like hexdump or objdump:

hexdump -C firmware.bin | head -n 20
objdump -d bootloader.bin | grep 'main\|entry'


Kernel: Core System Management

The kernel is the core of the operating system, managing hardware resources and providing low-level services. In IoT devices, it often runs embedded Linux (e.g., Yocto Project) or real-time OS (RTOS).

Key responsibilities:
- Process scheduling and memory management
- Device driver support (e.g., UART, SPI, WiFi)
- Security enforcement (e.g., SELinux, AppArmor)

Analysis example:
Disassemble a Linux kernel binary to identify critical functions:

arm-none-eabi-objdump -M no-aliases -d kernel.elf | grep 'sys_call\|irq_handler'


Root Filesystem: Application and Configuration Storage

The root filesystem contains the OS's files, libraries, configuration, and user data. It is typically compressed (e.g., squashfs) to save space.

Key components:
- /bin, /sbin: Essential binaries
- /etc: Configuration files
- /lib: Shared libraries
- /usr: User applications

Analysis example:
Extract and inspect a squashfs filesystem:

unsquashfs rootfs.squashfs -d extracted_fs
find extracted_fs -name "*.conf" -exec cat {} \;


Application Binaries: Device-Specific Logic

Application binaries implement the device's primary functionality, such as sensor data processing, communication protocols (MQTT/CoAP), or user interface logic. These binaries are often compiled for ARM or RISC-V architectures.

Key considerations:
- May include hardcoded credentials or secrets
- Use protocol stacks (e.g., MQTT client libraries)
- May interface with hardware peripherals (e.g., ADC, GPIO)

Analysis example:
Extract strings from an application binary to find potential secrets:

strings app_binary.bin | grep 'password\|token\|key'


Key takeaways

  • The bootloader is critical for secure boot and initial hardware setup.
  • The kernel manages system resources and enforces security policies.
  • The root filesystem contains essential configuration and libraries.
  • Application binaries implement device-specific logic and may harbor vulnerabilities.
  • Tools like objdump, unsquashfs, and strings are essential for analyzing firmware components.