Autel Evo Firmware Unpacker

Background

Just looking around the internet one day when a product caught my eye. I’ve heard/seen of the DJI drones all over place but never anything from this company, Autel. Their main product is the EVO(they have a new EVO II now).I looked around for a bit to see if anyone had done any reversing work before on it and to my suprise it looked like new territory. So immediately I decided this was going to be a great new project to start.

What are we dealing with?

The Autel EVO https://auteldrones.com/products/evo
A consumer UAS to rival the DJI Mavic
EVO

I figured that like most embedded devices the firmware update process would be similar, grab update from internet, place on sdcard, flash. Did some Googling around and came across the download page for the firwmare https://www.autelrobotics.com.au/pages/downloads
Download

First Looks

First things first, what do we got

file EVO_FW_V1.4.9.bin 
EVO_FW_V1.4.9.bin: data

Well thats not helpful how about checking if its compressed/encrypted. Entropy

Looks like only some of if it is uncompresed…interesting. Let’s see what we see in a hex view Hex

We see what looks to be some sort of structure that is XML-like

"<filetransfer>"
"<fileinfo>"
"<filecontent>"

Putting it all together

If we think of it like XML then we know that if "<filetransfer>" is parent then we should see an end tag, but there isn’t one. Also the " characters are not a typo, those apear to be part of the structure. It also looks like the highest level tag is a filetransfer and signifies the beginning of a file entry.

00000000  22 3c 66 69 6c 65 74 72  61 6e 73 66 65 72 3e 22  |"<filetransfer>"|
00000010  22 3c 66 69 6c 65 69 6e  66 6f 3e 22 00 00 00 0b  |"<fileinfo>"....|
00000020  fd ce 69 48 68 65 61 64  65 72 2e 6a 73 6f 6e 22  |..iHheader.json"|
00000030  3c 66 69 6c 65 63 6f 6e  74 65 6e 74 3e 22 00 00  |<filecontent>"..|
00000040  01 75 e8 85 a4 36 7b 22  58 42 30 31 35 5f 4d 4f  |.u...6{"XB015_MO|

Next, a fileinfo tag follows, with no gap inbetween both tags. However after the "<fileinfo>" tag we see a couple bytes of space followed by what appears to be a filename. If it truly is a filename then we can guess that it probably is dynamic, meaning that the name can be changed. If we follow that thought path then the unpacker of the firmware needs to be able to figure out the length of the filename ahead of time.

If we assume the filename is header.json then the unpacker needs to know ahead of time to unpack 11 bytes (0x0B).

00000010  22 3c 66 69 6c 65 69 6e  66 6f 3e 22 00 00 00 0b  |"<fileinfo>"....|
00000020  fd ce 69 48 68 65 61 64  65 72 2e 6a 73 6f 6e 22  |..iHheader.json"|

If we look, just after the start of the tag, we see 8 bytes before the filename starts. And lucky us what do we see, 00 00 00 0b. Boom, we know how the filename size is figured out. What about the next 4 bytes? Well I never fully figured those out (sorry), my guess is either a timestamp or some sort of CRC.

We have our last tag, "<filecontent>", and just by looking at the hexdump we can already tell that there is once again an 8 byte gap before what appears to be JSON starts.

00000030  3c 66 69 6c 65 63 6f 6e  74 65 6e 74 3e 22 00 00  |<filecontent>"..|
00000040  01 75 e8 85 a4 36 7b 22  58 42 30 31 35 5f 4d 4f  |.u...6{"XB015_MO|
00000050  44 42 5f 46 57 5f 22 3a  7b 22 66 69 6c 65 70 61  |DB_FW_":{"filepa|

For this one I took a guess that it probably follows the same structure as before and now that the tag is called filecontent I assumed it would be the file size. The remaining bytes, 8-field_size are the actual content of the file being transfered. Now we just need a parser to extract everything for us!

Structure as it stands

"<filetransfer>"

"<fileinfo>"
field_size: bytes 0-4, big endian
unknown: bytes 4-8, ??, crc/timestamp maybe
data: bytes 8-X, data

"<filecontent>"
field_size: bytes 0-4, big endian
unknown: bytes 4-8, ??, crc/timestamp maybe
data: bytes 8-X, data

I’ve written a firmware parser that you can find on Github to unpack your EVO firmware https://github.com/anthok/autel

Unpack

What’s Left?

  • Parser doesn’t automatically recurse through, so its very manual at the moment.
  • We now have all the juicy firmware files unpacked for all the components of the Autel EVO!
  • Someone could take this work further and begin to understand the formats of all the subcomponents.
  • This could lead to firmware modifcations and adding in capabilities.
  • Those unknown bytes! Would love to know what they are