{"id":39099191,"url":"https://github.com/nevvman18/hc-12_reverse_engineering","last_synced_at":"2026-01-17T19:01:08.098Z","repository":{"id":238333393,"uuid":"796037946","full_name":"Nevvman18/HC-12_Reverse_Engineering","owner":"Nevvman18","description":"Everything on reversing the HC-12 radio serial module","archived":false,"fork":false,"pushed_at":"2024-06-11T13:28:20.000Z","size":21716,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-06-11T14:54:43.073Z","etag":null,"topics":["firmware","hc-12","hk32f030m","reverse-engineering","si4463","stm8"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Nevvman18.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-04T18:42:30.000Z","updated_at":"2024-06-11T14:54:43.649Z","dependencies_parsed_at":null,"dependency_job_id":"f7ac50b5-da4e-4884-b6e0-ace86e3fa3be","html_url":"https://github.com/Nevvman18/HC-12_Reverse_Engineering","commit_stats":null,"previous_names":["nevvman18/hc-12_reverse_engineering"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Nevvman18/HC-12_Reverse_Engineering","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nevvman18%2FHC-12_Reverse_Engineering","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nevvman18%2FHC-12_Reverse_Engineering/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nevvman18%2FHC-12_Reverse_Engineering/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nevvman18%2FHC-12_Reverse_Engineering/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nevvman18","download_url":"https://codeload.github.com/Nevvman18/HC-12_Reverse_Engineering/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nevvman18%2FHC-12_Reverse_Engineering/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28516540,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T18:55:29.170Z","status":"ssl_error","status_checked_at":"2026-01-17T18:55:03.375Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firmware","hc-12","hk32f030m","reverse-engineering","si4463","stm8"],"created_at":"2026-01-17T19:01:07.200Z","updated_at":"2026-01-17T19:01:08.051Z","avatar_url":"https://github.com/Nevvman18.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# HC-12 - Reverse Engineering\nHC-12 - one of the many good radio modules you can find on the market. *And the most mysterious*.\n\n## Introduction\nFor one of my projects I bought a pair of them. Unfortunately, after about half a year, one of them either **went deaf or silent**, due to a broken radio IC.\n\nI ended up buying another pair. Instead of importing from China, I got them from my local store, and **they were fake**! Bad reception, no config mode - these were the problems.\u003cbr\u003e\nAfter returning them, I received another 3 pieces from the same store in China. And they work *perfectly*.\u003cbr\u003e\nBUT, the new ones **didn't communicate with the old** ones!\n\n## How could they be so different?\nI started looking at them closely. Same **Si4463** radio IC, same PCB but a **different MCU!**\u003cbr\u003e\n\n### First? revision\nRuns on a **HK32F030MF4P6** MCU. It's *like an STM32* family, but **cheaper** and more ***sketchy***.\u003cbr\u003e\nSpecs: 32-bit Cortex-M0, 32MHz, 16KB flash, 2KB RAM (actually 4!) \u003cbr\u003e\nLooks powerful for the module, but unfortunately it isn't the most user-friendly (explained later on).\n\n### Second revision\nHere it gets better, because **everything is the same**, apart from the MCU.\u003cbr\u003e\nThis time, it's **STM8S003F3P6**. Manufactured by STMicroeletronics, so it is **documented well** and it seems ***nicer to play with***.\u003cbr\u003e\nSpecs: 8-bit 16MHz uC, 8KB flash, 1kB RAM.\u003cbr\u003e\n\n### Side-by-side comparison\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"./photos/1st%20rev%20macro.jpg\" alt=\"1st rev\" style=\"width:45%\"/\u003e\n\u003cimg src=\"./photos/2nd%20rev%20macro.jpg\" alt=\"2nd rev\" style=\"width:45%\"/\u003e\n\u003c/p\u003e\n\n## Firmware extraction\n### First revision\nFirstly, I checked it's version with the built-in AT command `AT+VER`, which got me a response of **`HC-12_V2.6`**. The weird thing is that some modules respond with 'HC-12 \\[version]', and some with 'www.hc01.com \\[version]'.\u003cbr\u003e\n\nThe main MCU is a HK32 family uC. It is programmed using **SWD** interface. After a bit of research, I stumbled upon some [blog](https://nerdralph.blogspot.com/2020/12/trying-to-test-ten-cent-tiny-arm-m0-mcu.html) [posts](https://nerdralph.blogspot.com/2021/01/trying-to-test-ten-cent-tiny-arm-m0-mcu.html) featuring the programming adventure.\u003cbr\u003e\nFor programming it I wanted to use my ST-Link V2 probe. It turns out that during connection there occurs some sort of verification process, which doesn't allow me to read the firmware.\u003cbr\u003e\n\nI carefully attached the probe to the HC-12 (it has 2 test points on the back side of the board) and started debugging.\u003cbr\u003e\n\nUsing pyOCD I successfully connected to the core of the HK32:\n```console\n(.venv) monkey@computer:~$ pyocd cmd -v -t stm32f051\n0000530 I Target type is stm32f051 [board]\n0000539 I DP IDR = 0x0bb11477 (v1 MINDP rev0) [dap]\n0000584 I AHB-AP#0 IDR = 0x04770021 (AHB-AP var2 rev0) [discovery]\n0000587 I AHB-AP#0 Class 0x1 ROM table #0 @ 0xe00ff000 (designer=555 part=600) [rom_table]\n0000589 I [0]\u003ce000e000:SCS v6-M class=14 designer=43b:Arm part=008\u003e [rom_table]\n0000590 I [1]\u003ce0001000:DWT v6-M class=14 designer=43b:Arm part=00a\u003e [rom_table]\n0000591 I [2]\u003ce0002000:BPU v6-M class=14 designer=43b:Arm part=00b\u003e [rom_table]\n0000595 I CPU core #0: Cortex-M0 r0p0, v6.0-M architecture [cortex_m]\n0000597 I 2 hardware watchpoints [dwt]\n0000599 I 4 hardware breakpoints, 0 literal comparators [fpb]\nConnected to STM32F051 [Lockup]: B55B5A1A00000000392CF301\npyocd\u003e rw 0x0 64\nTransfer failed: Memory transfer fault (read) @ 0x00000000-0x0000007f\npyocd\u003e unlock\n0065045 W T bit in XPSR is invalid; the vector table may be invalid or corrupt [cortex_m]\nError: target was not halted as expected after calling flash algorithm routine (IPSR=3)\npyocd\u003e reg flash\nFlash.ACR @ 40022000 = 00000000\nFlash.KEYR @ 40022004 = 00000000\nFlash.OPTKEYR @ 40022008 = 00000000\nFlash.SR @ 4002200c = 00000000\nFlash.CR @ 40022010 = 00000080\nFlash.AR @ 40022014 = 00000000\nFlash.OBR @ 4002201c = fffffffa\nFlash.WRPR @ 40022020 = ffffffff\npyocd\u003e wr Flash.KEYR 0x45670123\nwriting 0x45670123 to 0x40022004:32 (KEYR)\npyocd\u003e wr Flash.KEYR 0xCDEF89AB\nwriting 0xcdef89ab to 0x40022004:32 (KEYR)\npyocd\u003e rw 0x0 64\nTransfer failed: STLink error (18): AP error\npyocd\u003e\n```\n\nI was able to read status, reset, halt, change registers, but any operations of writing and **flash reading were unsuccessful**. I also tried sending magic-byte ROP disable, which should work, but didn't. The issue has to be with the ST-Link. Segger J-Link should work, but I don't own one.\u003cbr\u003e\n\nI wanted to somehow extract the firmware. I saw [this writeup](https://github.com/rumpeltux/hc12) (and also other things [there](https://itooktheredpill.irgendwo.org/2020/hc12-hacking/)) on someone reversing same HC-12 modules. *rumpeltux* found out, that with sending various bytes over serial port he was able to get the firmware from the device. Tried it with my version, but it didn't work, throwing assignment errors.\u003cbr\u003e\n\n**My firmware extraction attempt from 1st module revision was unsuccessful.**\n\n### Second revision\nThis time it **went better**. STM8, being supported by my debuggers, is programmed with **SWIM** interface. This module responds to `AT+VER` with **`www.hc01.com HC-12 v2.6`**.\u003cbr\u003e\nI assumed that it won't go so easily, because in the previously mentioned post, *rumpeltux* had to power glitch the uC to be able to extract the firmware.\u003cbr\u003e\nI connected the STLink with the STM8 using 2 test points on the back:\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"./photos/2nd%20rev%20swim%20interface.jpg\" alt=\"2nd rev test points\" style=\"width:30%\"/\u003e\n\u003cimg src=\"./photos/2nd%20rev%20mcu%20macro.jpg\" alt=\"2nd rev STM8 uC\" style=\"width:30%\"/\u003e\n\u003c/p\u003e\u003cbr\u003e\n\nFor the firmware extraction attempt, I used the official ST Visual Programmer.\u003cbr\u003e\nFirst attempt - `Unable to read bytes [...]`. I thought that again it was the Read-Out Protection byte. But wait, clicked the button second time and... **I was able to read the whole firmware!** For known reasons I won't release the original firmware image, but I will analyse it later on.\u003cbr\u003e\nOn the **OPTION BYTE** page the first register was set to: **`ROP --- Read Out Protection OFF`**.\u003cbr\u003e\nCompared the results with other 2 modules running the `v2.6` firmware and I can confirm that all 3 modules have exaclty the same memory contents. Also neither of them had ROP byte active.\n\n\n## Firmware analysis\nNote that I only have the `v2.6` firmware.\u003cbr\u003e\n\n### PROGRAM MEMORY\nUploading the main firmware to [binvis.io](https://binvis.io/) reveals that only the first 200 bytes contain interesting characters in a mostly human-readable format.\u003cbr\u003e\nSome interesting parts: \u003cbr\u003e\n* At address **0x00008080** there is `HC-12_V2.3` string. But the module calls that it is v2.6, like below:\n* At address **0x000080F1** there is `HC-12 v2.6...www.hc01.com` which is a string shown on the UART output.\n* At address **0x0000808E** there is `20210319` which looks like a compilation timestamp.\n* At address **0x000081F8** there is `How are you..Long time no see`. I don't know what that could be, it never shows up during operation.\n* There are also some bytes like `OK` `ERROR` `OK+B00..`, which mention AT command programming replies.\n\nThe rest of the *PROGRAM MEMORY* is a compiled machine firmware. I want to decompile it in **Ghidra** in future, because there seem to be plug-ins for disassembling STM8 firmware files. The bad news is that *rumpeltux* decompiled his module's `v2.4` firmware and said that re-using it is ***not a viable option***.\n\n### DATA MEMORY\nThis is the EEPROM memory that contains program variables, like transmitter mode, frequency, baud rate. I observed how they change with trying different settings.\u003cbr\u003e\nFor example, byte **0x00004001** stores the **radio channel**, `0x02` being channel 1 and `0xFE` being channel 127.\u003cbr\u003e\nI manually set the channel byte to `0xFF`, to which the module responded with `OK+RC254`. I can also set this channel via AT command, though it exceeds the range of 1-127 mentioned in the datasheet. Weird? Setting byte to `0x02` occured in a `OK+RC127`, maybe the decimal values of channel bytes are divided by 2 to get it in a configuration number. Will check communication on these channels later.\n\n## Compatibility of v2.4 with v2.6\nI discussed about these modules with [rumpeltux](https://github.com/rumpeltux). He quickly managed to analyze my firmware dumps from v2.6. The `AT+UPDATE` **dumping vulnerability** that was present in v2.4 isn't there anymore with the newer releases. Fortunately, the radio ICs are similar, and the only difference is **pinout difference** (you can see it in a header file in his custom firmware). After making some minor changes, he managed to compile firmware for both versions and now both of them can **communicate with each other**. Will have to try that.\n\n## Final thoughts\nThese radio modules seem like a mystery. Tons of versions, clones and unconfirmed information can be found. In future I will try to decompile the firmware and analyse the module more.\u003cbr\u003e\nThere seem to be custom firmware projects on github, like these:\n* [*rumpeltux's* custom firmware for v2.4 and v2.6](https://github.com/rumpeltux/hc12fw)\n* [AX.25 packet radio firmware](https://github.com/al177/hc12pj) - compiled it quickly and it works (at least the serial port)\n\n## Useful links\n* [*rumpeltux's* blog](https://itooktheredpill.irgendwo.org/2020/hc12-hacking/) post about HC-12 reverse engineering\n* [stm8flash](https://github.com/vdudouyt/stm8flash)\n* [eevblog discussion](https://www.eevblog.com/forum/microcontrollers/$0-25-hk32f030m-(cortex-m0-32mhz-16kb-2kb)/) about the HK32F030M uC\n* [Ralph Doncaster's](https://nerdralph.blogspot.com/2020/12/trying-to-test-ten-cent-tiny-arm-m0-mcu.html) HK32F030M programming attempt\n* [Reprogramming a HC-11 CC1101 433MHz Wireless Transceiver Module](https://mvdlande.wordpress.com/2016/09/03/reprogramming-a-hc-11-cc1101-433mhz-wireless-transceiver-module/)\n* [Hackaday post](https://hackaday.com/2018/05/05/fail-of-the-week-never-assume-all-crystals-are-born-equal/) about differences in HC-12 batches\n* [Hackaday post](https://hackaday.io/project/27319-432-434mhz-range-spectrum-analyzer-based-on-hc-12) about DIY HC-12 radio spectrum analyzer","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnevvman18%2Fhc-12_reverse_engineering","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnevvman18%2Fhc-12_reverse_engineering","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnevvman18%2Fhc-12_reverse_engineering/lists"}