I usually start any research by looking at normal usage to get an understanding of the system, understand the interfaces, etc. Since it’s my car, I’m quite familiar with the user exposed parts.
Next is usually the firmware upgrade process to get a clean version of the firmware. Luckily, the CMU gets fairly regular updates, but they are usually installed by a dealership.
CMU updates
Searching for CMU updates leads to various options to download the .zip files. Mazda is pretty good at taking them down, so there is no single simple repository and they are often shared privately on forums. The updates are password encrypted, but that password is also available online.
Peeking under the hood
I decided to look at the updates to see what information I can gain from them.
The update file have the version name and number and end in .up, but are actually .zip files. When unpacked with the password, a list of folders is unpacked (more on those later), along with a couple files.
jci_subord_cert.pem
publisher_cert.pem
main_instructions.ini
versions.ini.gz
The certificates are interesting as they could point to some signature checks for the updates.
The text contents of versions.ini.gz
are split into sections like “Settings”,
“Compatibility” and “DisplayVersion”, presumably checks to execute before the
update.1
The fun part is in main_instructions.ini
, which looks like a recipe for a
software update.
Instructions
The main_instructions.ini
is split into “Settings”, “Instructions”,
“Instructions_Ext” and “DataStorage”.
Settings
The Settings
section has some keys about compression and step count that can
be used to verify the validity of the rest of the file.
[Settings]
PackageID = 120938102938
CompressionType = GZIP
TotalStepsCount = 800
Main Instructions
The really interesting part is in [Instructions]
and [Instructions_Ext]
. The
steps are numbered in order and take the following format
<stepnr> = <instruction>, <folder>, <instruction_file>, <instructions>
So the updater looks in <folder>
for the <instruction_file>
(another
.ini) and expects to find <instructions>
instructions.
Three different <instruction>
s were identified:
- Execute :: Is mainly to execute shell commands
- FileUpdate :: Contains mostly commands to create, copy, remove, files
- ImageUpdate :: The target .ini contains extra
[Settings]
that pertain to flash type, partition size etc.
Step Instructions
The format of the .ini files in those folders is the same as in the main file,
but instead of calling other .ini files, the <instruction>
actually have an
effect. Some examples:
1 = Execute,"echo === Updating Files ==="
2 = Remove,"/tmp/update.sh"
Simulated Execution
All these actions were fairly straightforward to read and script. The goal was to rebuild the filesystem from the update, potentially retrieving enough information to emulate the system for more interactive tests.
Based on where some files are copied to, it looks like the script is ran from
/tmp
, so when creating the simulated filesystem, we execute everything
relative to <extraction_folder>/tmp
and /
maps to ./<extraction_folder>
.
The instructions relating to files, like Create
, Copy
, etc. can be used to
populate that filesystem.
This obviously doesn’t cover any shell-scripts that unpack files and most
specifically ImageUpdate
s are not yet executed. But the list of those is
fairly short and can be listed with the tool and manually processed.
Future plans
A long term goal was to extract all known updates and create a list of files
that changed and pick out files of interest for further analysis with tools like
vbindiff
, text files getting line diffed etc.
-
The use of GZip compression for a simple text file is interesting (and used a lot in this firmware, so I will skip that detail often), because it doesn’t save a lot of space for these tiny text files, but it adds some checksums, which is a somewhat free integrity check. ↩︎