⏱️ Reading time: 13 min
The previous owner of a 2014 Renault Latitude wasn’t exaggerating: without a specific TomTom SD card, the car locks the menu where you change the clock. That’s why an Estonian engineer applied firmware reverse engineering to the navigation unit instead of paying 60 euros for that card.
📑 En este artículo
- TL;DR
- What Is Firmware Reverse Engineering?
- Why Auditing Firmware Without Documentation Matters
- How It Works: From Raw Binary to Filesystem
- Practical Examples and How to Get Started
- Real-World Use Cases
- Common Mistakes and Best Practices
- Tool Comparison
- Going Deeper: Signatures, Verification, and Emulation
- Frequently Asked Questions
- Is it legal to reverse engineer firmware on a device I own?
- What’s the difference between static and dynamic analysis of embedded firmware?
- Which tool is best for getting started with filesystem extraction?
- How do you identify the filesystem type inside a firmware image?
- What should you do if an embedded device’s firmware is encrypted or signed?
- References
The case, documented on the nns.ee blog, is the anecdote that sparks this guide on how to audit any embedded device without documentation: extracting the filesystem, locating real configs, and understanding which tools to use.
TL;DR
- binwalk identifies and extracts the hidden filesystem inside a firmware image; mounting it read-only exposes real configs.
- Configuration files almost always live under /etc, /usr/local/etc, or /data on embedded Linux.
- QEMU lets you emulate ARM firmware without risking the original hardware during testing.
- A DRM scheme tied to an SD card’s CID, as in the TomTom case, blocks modified images before they’re installed.
- Comparing binaries from different versions with binwalk and diff helps pinpoint what changed between firmware releases.
What Is Firmware Reverse Engineering?
Firmware reverse engineering is the process of analyzing the software running inside an embedded device (router, camera, navigation unit) without its source code or documentation, in order to understand its internal structure, extract its filesystem, and locate configurations, credentials, or business logic hidden inside the binary.
It differs from desktop software reverse engineering in one key detail: there’s almost never an installer or a public API describing the file format. The only thing usually available is an update binary that the manufacturer itself distributes so the device can update on its own, without expecting anyone to open it in a hex editor.
This discipline applies both in offensive security (finding exploitable vulnerabilities) and in defensive security and interoperability: understanding what your own router, your IP camera, or, as in this case, your car’s navigation unit actually does, when the manufacturer never published a technical manual.
Why Auditing Firmware Without Documentation Matters
Embedded electronics manufacturers rarely publish complete specs for their firmware: there’s no changelog, no API docs, and updates arrive as an opaque binary. That opacity isn’t an accident. Tying basic functions (like changing the clock) to a proprietary accessory, as TomTom did with its maps SD card, is a form of vendor lock-in: you sell the hardware once and keep charging for the accessory that makes it fully functional.
On the security side, opening the firmware is the only way to confirm what’s really inside a device you’re about to connect to your network or your car. Hardcoded credentials, debug services left open in production, or incomplete validation logic show up constantly in home IoT firmware, and the only way to find them before someone with different intentions does is to audit them first.
There’s also a repair argument: if the manufacturer disappears, discontinues the product, or simply doesn’t sell the replacement part in your country, understanding the firmware is the difference between keeping the device running or throwing it out. The author of the Renault case didn’t want maps or piracy, just wanted the dashboard clock to show the right time after the switch to winter time.
How It Works: From Raw Binary to Filesystem
Every firmware reverse engineering process follows more or less the same order, whether the target is a router, a camera, or a car navigation unit. First you need to get the binary: downloading it from the manufacturer’s support site as an update file, extracting it from an SD card or eMMC, or dumping it directly from the flash chip with an SPI programmer if there’s no other way to access it.
With the file in hand, the next step is identifying what’s inside. The file command recognizes known headers, but most update images aren’t a single filesystem: they’re a container with a bootloader, a compressed kernel, and one or more filesystems concatenated one after another. That’s where binwalk comes in, scanning the binary byte by byte looking for known signatures (magic numbers for squashfs, cramfs, ext3, jffs2, ubifs, gzip, LZMA) and reporting at which offset each one starts.
flowchart TD
A["Downloaded firmware (.bin)"] --> B["bootloader"]
A --> C["recovery partition"]
A --> D["data partition (ext3/squashfs)"]
D --> E["etc: configs and init scripts"]
D --> F["usr: binaries and libraries"]
D --> G["data: user settings"]
Once the offsets are located, each section is extracted with dd or with binwalk’s automatic extraction, and the resulting filesystem is mounted read-only. From there, exploring /etc, the init scripts (SysV under /etc/init.d or systemd units), the binaries in /usr, and the variables that build the startup scripts usually reveals in minutes what the documentation never told you: which daemon listens on which port, where the real configuration file lives, and what credentials were left written in plain text.
flowchart TD
A["Acquire the firmware"] --> B["Identify format and partitions"]
B --> C["Extract the filesystem"]
C --> D["Mount read-only"]
D --> E["Explore configs and init scripts"]
E --> F["Verify findings against the real device"]
Practical Examples and How to Get Started
This workflow can be practiced right now on Linux (Debian or Ubuntu) with already-packaged tools. On macOS, brew install binwalk is enough; on Windows, the simplest approach is running the same commands inside WSL2 with an Ubuntu distro.
First, install the dependencies:
sudo apt update
sudo apt install -y binwalk file e2fsprogs squashfs-tools
With a downloaded firmware image (let’s call it firmware.bin), the first step is identifying its format:
file firmware.bin
Expected output, typical of an update image for an embedded-Linux-based device:
firmware.bin: data
file almost never recognizes the full container because it’s a proprietary format; that’s why the second command is binwalk, which scans the internal signatures:
binwalk firmware.bin
The output follows the standard three-column format (decimal offset, hexadecimal offset, signature description), for example:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes
65536 0x10000 Linux kernel ARM boot executable zImage
1310720 0x140000 EXT filesystem, blocks count: 65536
With the offsets identified, you can let binwalk extract everything automatically:
binwalk -e firmware.bin
This creates a _firmware.bin.extracted/ folder with each section already separated. If one of them turned out to be an ext3 image (like the ttsystem file in the Renault case), it’s mounted like this:
mkdir -p /mnt/fw
sudo mount -o loop,ro _firmware.bin.extracted/140000.ext3 /mnt/fw
To confirm the mount is read-only before touching anything:
mount | grep /mnt/fw
Expected output:
/dev/loop0 on /mnt/fw type ext2 (ro,relatime)
From there, finding configuration files is a matter of going through the typical folders of any embedded Linux:
find /mnt/fw/etc -maxdepth 2 -type f \( -name "*.conf" -o -name "*.cfg" \)
ls /mnt/fw/etc/init.d/ 2>/dev/null
This is the point where the author of the Renault case found that the settings menu depended on a definition read from the SD card, not from the filesystem itself: the configuration app’s logic never finished loading without that external file.
Real-World Use Cases
This technique shows up constantly outside the automotive world.
- Consumer devices with no technical manual: home routers, IP cameras, and, as in the case that opens this article, car navigation units that depend on a proprietary accessory for basic functions.
- Offensive and defensive security research: analysts looking for hardcoded credentials, backdoors, or leaked private keys inside publicly available update images.
- Interoperability and repair: community projects, like the prior work on the same TomTom Carminat LIVE unit published on GitHub, which document unofficial protocols so others don’t have to repeat the work from scratch.
Common Mistakes and Best Practices
- Mounting read-write by mistake: always use
-o loop,ro; mounting rw can corrupt the image before you finish the analysis. - Working on the original: copy the dump with
ddbefore touching anything; if something goes wrong, you copy again instead of desoldering the flash chip a second time. - Assuming the filesystem from the file extension: a
.binsays nothing about its content; trust binwalk’s signatures or the magic numbers, not the name. - Flashing a modified image without testing it first: emulate first with QEMU or a test environment; a failed flash on real hardware can leave the device unable to boot.
- Ignoring signature verification: if the device rejects your modified image with no clear explanation, there’s most likely a verification layer before flashing, not a bug on your end.
⚠️ Watch out: flashing a modified image without testing it first in an emulator can leave an embedded device unable to boot; in consumer electronics there’s rarely a cheap way to reverse that.
Tool Comparison
No single tool covers every case: most analysts end up combining binwalk for the first scan with a manual mount when the signatures aren’t enough.
| Tool | When to Use It | Advantage | Limitation |
|---|---|---|---|
| binwalk | First scan of any unknown firmware image | Automatically detects signatures for dozens of filesystems and compression formats | Can extract junk if there are false-positive signatures inside binary data |
| unblob | When binwalk can’t extract cleanly or there are nested layers | More robust recursive extraction and better handling of proprietary formats | Slower and requires installing more dependencies |
| dd + mount -o loop | When the exact filesystem offset has already been identified | Full control, without relying on third-party heuristics | Requires calculating offsets by hand with a hexdump |
| QEMU | To run the extracted firmware without touching the real hardware | Lets you iterate without the risk of bricking the device | Emulating specific peripherals (CAN bus, touchscreens) usually requires manual patches |
Going Deeper: Signatures, Verification, and Emulation
Firmware reverse engineering gets interesting when the device won’t accept just any modified image. In the Renault case, the engineer repackaged the extracted ttsystem and let the unit install it from the SD card. The unit accepted original images without issue but rejected the modified one, even though the updater’s visible logic showed no obvious validation. That led to setting up an emulator with QEMU, using a patched 2.6 kernel to ignore the reboot syscalls the system triggered every three seconds without the recovery partition present, and confirming there that a full verification layer was missing before accepting an update.
sequenceDiagram
participant U as Unit
participant SD as SD Card
participant R as Recovery partition
U->>SD: reads update image
SD-->>U: delivers signed ttsystem
U->>R: boots into recovery mode
R->>R: verifies signature and hash
alt signature valid
R-->>U: applies the update
else signature invalid
R-->>U: rejects the image
end
The second layer of protection was even more aggressive: the original SD cards carry a CID (a unique identifier burned into the card), and the map files came signed against that specific CID. Copying the files to a blank SD card didn’t work because the signature didn’t match the new CID, the same principle video game consoles use for DRM to tie content to a hardware serial number.
💭 Key takeaway: when a device rejects a modified image with no clear error message, it’s the most reliable sign that a verification layer (signature, hash, or DRM) exists before flashing.
For this kind of firmware binary audit, emulating in QEMU instead of flashing straight to real hardware is the difference between iterating a hundred times in an afternoon or bricking the unit on the first failed test. The downside is that emulating specific peripherals almost never comes built into the emulator: you have to write or patch those drivers by hand, which is exactly what the author of the original case documented.
Your next step: download a public firmware image from any old router you no longer use (many manufacturers publish update .bin files on their support site) and run binwalk -e on it to practice the full workflow before trying it on a device you actually care about.
Frequently Asked Questions
Is it legal to reverse engineer firmware on a device I own?
In most jurisdictions, analyzing the firmware of a device you own for interoperability or repair is protected under copyright exceptions, though laws vary by country. Redistributing the extracted binary or bypassing a DRM for piracy purposes can violate license agreements or anti-circumvention laws.
What’s the difference between static and dynamic analysis of embedded firmware?
Static analysis examines the extracted binaries without running them: strings, disassembly, grepping configuration files. Dynamic analysis runs the real or emulated firmware (for example with QEMU) to observe its runtime behavior, something essential when the logic depends on external hardware like a CAN bus.
Which tool is best for getting started with filesystem extraction?
binwalk remains the standard starting point: it identifies known signatures and extracts automatically. If the result turns out corrupted or incomplete, unblob usually handles cases with nested layers or proprietary formats that binwalk doesn’t fully recognize.
How do you identify the filesystem type inside a firmware image?
First with file on the extracted binary, which recognizes standard headers for ext2/3/4, squashfs, cramfs, jffs2, or ubifs. If that doesn’t yield a result, a hexdump of the first bytes against a list of known magic numbers usually confirms the exact format.
What should you do if an embedded device’s firmware is encrypted or signed?
First you need to confirm it’s actually encrypted and not just compressed: high entropy across the whole file (which binwalk also measures) is the typical clue. If there’s a signature but no encryption, the content can still be extracted; what’s blocked is installing a modified version, not reading the original.
References
- nns.ee: the original article about how the author reverse engineered the firmware of the 2014 Renault Latitude in order to change the clock.
- andronedev/carminat-tomtom-live-re on GitHub: prior reverse engineering work on the same TomTom Carminat LIVE unit.
- binwalk on GitHub: the firmware signature and extraction tool used as the first step in most analyses.
- QEMU: the emulator that lets you run extracted firmware without risking the original hardware.
- ext3 on Wikipedia: reference on the filesystem that turned out to contain the ttsystem image in the Renault case.
📱 Enjoying this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.
Featured image: Foto de Vishnu Mohanan en Unsplash
Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.
Leave a comment
0 Comments