published on in Tech Tips & Tricks Creations

HC-12 Hacking

I have a strange obsession with the STM8 microcontroller. Arguably because it’s so cheap (you could get in in bulk from <0,40€ per piece or for 0,60€ on a dev-board), but powerful and versatile at the same time, due to:

  • lots of GPIOs
  • UART/SPI/I2C/ADC
  • low power
  • proper interrupts
  • works both at 3.3V and 5V

When investigating radio communication for some hobby projects a few years I stumbled upon the HC-12 module which easily adds wireless serial communication to your project. It’s essentially an STM8 that controls a Si4463 radio IC. Which got me thinking that it’d be nice to run my software directly on the STM8 instead of requiring an additional one. Unfortunately there’s no open-source firmware for the device (there is https://github.com/al177/hc12pj, but it’s not really functional), so I thought about modifying the original firmware to add my own handlers.

And so this story begins. And yes, I may have nerded out about this in the process…

Part 1: Acquiring the firmware

Unfortunately the HC-12 firmware isn’t public. While the datasheet mentions an AT+UPDATE command for firmware updates, I wasn’t able to find further documentation on this nor any firmware images.

Buffer overflows

My initial attempts to cause buffer-overflows weren’t really successful. I definitely triggered some undefined behavior and was likely able to dump some RAM, but if the target registers (e.g. of counters) are 8-bit wide that isn’t sufficient to dump the whole firmware.

SWIM Debug Interface

The STM8 has a debug interface via the SWIM pin (and I may have already written a tool to directly interact with it). The HC-12 has the readout protection option bytes set though. While you can reprogram the device, you cannot read out the firmware.

Glitching

TODO 35C3

My next attempt would be to

The MCU booted the readout protection wasn’t active and I was able to use the SWIM debug interface to dump the complete firmware.

Part 2: Understanding the firmware

The firmware image itself is of little use if you can’t understand it. I couldn’t find a useful disassembler. There was an [IDA 6 plugin](TODO github) and I tried to port it to IDA 7, but never really finished and took on different projects. Until a year later when I discovered that [someone had in fact ported it](TODO …).

A few evening of exploration yielded a good enough understanding of the internals. I identified a few sections of code that can probably be replaced with custom things. Now to make this available to others I’d need to provide the firmware dump which would probably cause copyright issues. So instead it’d be much nicer to provide others the ability to extract the firmware themselves.

During the firmware analysis I also found the code responsible for handling the AT+UPDATE command and it can indeed be used to reprogram the device. I wrote a little tool that adds code to dump the firmware into a section of the AT+VERSION command handler and then executes it to retrieve a firmware dump.

TODO datasheets

Part 3: Customizing the firmware

There’s about 1.2kb usable space for code & data without compromising any of the core functionalities. That should be enough for many use-cases. Expect more on this soon.