I wanted to explore the configuration and firmware update protocol used by this electronic speed controller (ESC) for electric skateboards from Favourite (FVT) Electronics:
Note that the same ESC is sold by Maytech with the MTES 120A SBEC name.
It uses a USB to UART adapter for connecting to the controller which is also used for configuring the popular LittleBee ESC for quadcopters:
The LittleBee ESC uses an open source BLHeli firmware which includes a bootloader with an UART based communications protocol at a fixed 19200 baud rate.
So I decided to capture the UART traffic to the ESC using the Saleae Logic 8 logic analyser during the following actions:
- reading the ESC configuration (CSV log),
- sending the configuration to ESC (CSV log), and
- sending a firmware update (CSV log).
The CSV logs are also available on GitHub.
The XOR Skywalker
The firmware update log was the most interesting because I immediately noticed the #Skywalker20A#
string in the plain UART traffic which means the firmware is sent completely decoded:
I used a bit of regex and hex-to-binary magic to extract the byte sequence from the UART traffic log:
$bin = array(); $fw = file_get_contents( $argv[1] ); // Extract byte strings from the CSV log. preg_match_all( '#\((.*?)\)#', $fw, $bytes ); foreach ( $bytes[1] as $byte ) { $bin[] = hex2bin( substr( $byte, -2 ) ); } file_put_contents( $argv[1] . '.bin', implode( '', $bin ) );
and compared it with the original firmware file E_SkateBoard_120A_170818_QuickStart.hgm from the FVT website:
All the 0x00
bytes in the UART traffic were clearly mapped to 0x68
in the firmware.
Having read plenty of firmware related articles on Hackaday I thought of trying to check for XOR obfuscation and with 0x68
mapping to 0x00
the XOR value is simply 0x68
. Here is how to XOR all bytes of a file with PHP:
$xor = array(); $fw = file_get_contents( 'E_SkateBoard_120A_170818_QuickStart.hgm' ); for ( $i = 0; $i < mb_strlen( $fw ); $i++ ) { $xor[] = mb_substr($fw, $i, 1) ^ hex2bin( '68' ); } file_put_contents( 'E_SkateBoard_120A_170818_QuickStart.bin', implode( '', $xor ) );
And we get a decoded firmware file which has the #Skywalker20A#
along with a BLHELI
reference right at the very end:
What’s Next
The Skywalker20A
string is a reference to the ESC layout and the SiLabs C8051F310 MCU pin mapping for the BLHeli firmware. Using that as a starting point it is necessary to:
- Verify the version of BLHeli bootloader running on the FVT 120V ESC by looking at the boot message in the UART traffic.
- Check if the firmware update protocol matches the one in the bootloader.
- Check if the C8051F310 MCU can be programmed via the exposed C2 interface.
- Check if the pinout matches Skywalker20A or FVT_20A.