SkyRC MC3000: reverse-engineering the firmware update program, and extracting the firmware embedded in it

As per the subject. Here’s the procedure I concocted:

  1. Downloaded MC3000_Firmware_Update__V1.18.exe from the SkyRC website;

  2. Submitted it at (which is IME does a good quick-analysis of EXE files, malware or not); at the analysis screen, selected the “DETAILS” tab and noted the following:
    TrID Generic CIL Executable (.NET, Mono, etc.) (67.7%) → Indicates the EXE was written in Dot.Net :nauseated_face:
    Manifest Resource
    UpgradeFirmware.loader.hex → These look very interesting
    UpgradeFirmware.rom.hex → Ditto.

  3. Googled for a good Dot.Net decompiler, found this: GitHub - dnSpy/dnSpy: .NET debugger and assembly editor; downloaded from the ‘Releases’ section, copied and extracted it into the Desktop of a Win10 machine, then entered the resulted directory and executed dnSpy.exe, and used it to open the above-mentioned MC3000_Firmware_Update__V1.18.exe

  4. Used the program’s search function to look for “UpgradeFirmware.rom.hex”, then clicked on it in the results, and then in the window that opened (which showed apparently very healthy HEX file contents), and used + and then pasted the results in a Notepad window, saving the result as “UpgradeFirmware.rom.hex.txt”; then using Windows File Manager, renamed the file to remove the “.txt” extension, resulting in a “UpgradeFirmware.rom.hex” file.

  5. Repeated 3) above for “UpgradeFirmware.loader.hex”.

  6. Used HEX2BIN to transform convert both .HEXes to the corresponding .BINs, producing UpgradeFirmware.loader.bin and UpgradeFirmware.rom.bin; HEX2BIN produced the following output, respectivelly:

    5a) UpgradeFirmware.rom.hex:

Lowest address:   08004000
   -> According to [1], this MCU's [3] flash starts at 08000000; so this HEX skips the first 0x4000 (16K) bytes, which is probably reserved space for the other HEX below);
Highest address:  0801A95B
Starting address: 08004000
Max Length:       92508
Binary file start = 08004000
Records start     = 08004000
Highest address   = 0801A95B
Pad Byte          = FF

5b) UpgradeFirmware.loader.hex:

Lowest address:   00000000
Highest address:  0000B20F
Starting address: 00000000
Max Length:       45584
    -> This seems too large for a mere (boot)loader... and when added to the 92508 bytes 
        of the main code above, exceeds the 128KB flash capacity of this MCU. When considered
        along with [2] below, this seems to indicate this file is some kind of "red herring" 
        and not actually part of the firmware update process.
Binary file start = 00000000
Records start     = 00000000
Highest address   = 0000B20F
Pad Byte          = FF
  1. Opened both .BIN files with a binary hex editor/visualizer and had a look around looking for strings etc:
    UpgradeFirmware.rom.bin seemed very promising, in fact I could locate a lot of messages I’m used to see in the charger’s display during normal operations. [2] As per UpgradeFirmware.loader.bin, its ‘excess size’ noted above could perhaps be explained by the large areas filled with FFs (which HEX2BIN identified above as the “Pad Byte”), but these areas are smack in the middle of the image; other things didn’t look as good, eg the message “.S.I.L.I.C.O.N. .L.A.B.O.R.A.T.O.R.I.E.S.8.C. .D.e.v.e.l.o.p.m.e.n.t. .B.o.a.r.d” (the “.” are non-ASCII bytes, indicating the message is coded in an one-char-per-16bit-word manner, possibly UNICODE), but anyway some googling brought this up: C8051F380DK C8051 8-bit MCU Development Kit - Silicon Labs; this seems totally off the mark, being a development kit for a 8051-compatible MCU, which is a totally different beast than the [3] STM32-compatible STM32F103RBT6 clone that reportedly powers this charger.
    I dont believe this charger would have two different MCUs, specially not a separate one just for booting, so more and more I’m starting to think that this “loader.hex” file is some kind of red herring or leftover from some other project.

  2. Then I tried the disassembly/decompiling tools that I could find/borrow (specially IDA Pro 7.0 and 7.3, at a friend’s computer that actually has licenses for them) but wasn’t able to make further progress. I got the impression that IDA is not actually very appropriate for ARM MCU image disassembly/decompiling – but this could be because these were old versions, from 2017 or so. Unfortunately I didn’t have access to any other versions, or other tools.

As I’m totally inexperienced with the STM32 architecture and even more with this specific MCU, and moreover reverse engineering is not really my forté (I’m much better at compiling than de-compiling :wink: ), I will end this here, at least for now, and hope that someone more experienced and knowledgeable than me in these matters can pick the torch :flashlight: up and continue ahead.

Anyone wanting the HEX files and not willing to go to all the rigmarole above, I can supply the ones I extracted – please contact me over PMs as I’m not posting them here to avoid cluttering our beautiful forum with large-ish files that will probably not be of interest to most people.

4 Thanks

WOW… lots of work. Thanks for doing it. Hopefully some code wizard will take an interests and carry on. It would be great to have open source community supported firmware for the MC3000… Rather than the black box we have.

1 Thank

My thoughts exactly! And it should not be that difficult, I’ve seen other projects, dealing with potentially much more complicated hardware, succeeding – eg GitHub - DualTachyon/uv-k5-firmware: Open reimplementation of the Quan Sheng UV K5 firmware v2.1.27

I asked the developer of that project for some hints, and s/he responded beautifully: What tool(s) were used to help reverse-engineer the original firmware? · Issue #43 · DualTachyon/uv-k5-firmware · GitHub

That’s one more reason I love opensource, people are usually very kind and helpful and oftentimes will go out of their way to help.

So, it’s game ON again, I’m downloading and installing the reverse-engineering kit s/he suggested and trying my hand on that once more.

I hope I can report more progress here in a couple of days.

Wish me luck! :slight_smile:

1 Thank

Good luck… !!

1 Thank

Best wishes in the venture and thanks for all the hard work.

1 Thank

First progress report, after installing Ghidra and playing a bit (well, actually many bits :wink: ) with it, and searching for and finding some support material:

  • It was surprisingly easy to install, just followed instructions here (via).
  • Before using it for the first time, I watched a short video tutorial (no direct URL, click here and search for " Getting Started"); I hate video stuff, but this one was pretty short and actually useful.
  • Then I started it, created a new project, and imported UpgradeFirmware.rom.hex into it; did it twice with “language” (which in Ghidra-speak actually means architecture/processor) set to “ARM-Cortex-little-default” and then to “ARMv7-32-little-default” (which would be the more specific and less specific processor types, with very similar (if not equal) results; in the end stuck with the former. Also, clicked on Options and set base address to 08004000, as told previously by HEX2BIN.
  • Then I opened it with the CodeBrowser tool (the one with the dragon head on the toolbar), and told it to go ahead and analyze it, exactly as instructed by the tutorial.

The result seems to be much more complete and to make much more sense than the ones I previously obtained with IDA Pro, but on trying to read through it, I quickly realized there’s a ton of stuff on which I will need to educate myself first in order to progress; basically ARM processor characteristics, architecture and instruction set. Here’s the best reference I found for that so far: ARM-ASM-Tutorial –; it seems almost made-to-order for the MCU in the MC3000, as it centers on the STM32F103RB while the MC3000 uses a submodel of it, the STM32F103RBT6); In its “Processor type & documentation” section, it includes links to a ton of ARM manuals freely available as PDFs, these are the ones I’ve downloaded and saved for future reference:

This reference also mentions the eventual need for a debug adapter, which makes a lot of sense given my past experiences with embedded development; it mentions all STM32 MCUs support a debug interface called SWD (which I understand is STMicro-proprietary but similar to the more universal JTAG); some searching brought up this, which indicates the SWD interface needs 3 pins called SWDIO, SWCLK and nSRST, besides VCC and GND; I’m wary of opening up my shiny new MC3000, but no need as @HKJ already did it in his epic review of the MC3000, including a very detailed and clear picture of the area around the MCU; in that picture, at the center-left border I can see a row of unsoldered pads labeled exactly 3.3V (aka VCC), NRST, SWDIO, SWCLK, and GND, so it seems the MC3000 circuit board just needs some jumper pins soldered to these pads and it would be ready to connect to a proper SWD adapter; that would allow me to flash the MCU directly (without needing to use SkyRCs EXEs or decode their proprietary USB firmware upgrade protocol), so it would be much easier to recover from the eventual ‘bricking’ that is almost unavoidable in these kinds of endeavors, and would also make it much easier to debug a future opensource implementation.

TBH, the breadth and width of material and resources I still need to get acquainted with and buy is more than a little disencouraging :expressionless:

I plan to keep on ploughing, but barring some special “a-ha moment” or major breakthrough, it’s looking to be at least many months of work due to my ignorance and inexperience in all the above.

If other people with more experience and resources would join or take the lead of this effort, things would go much faster and smoother, so here I leave with a call for anyone willing to.

3 Thanks