Tools for handling firmwares of DJI products, with focus on quadcopters.
Tools for handling firmwares of DJI products, with focus on quadcopters.
Tools for extracting, modding and re-packaging firmwares of DJI multirotor drones.
The project started as an alternative implementation of the parser from phantom-licensecheck. Over time it has grown to support many generations of DJI products. It consists of tools which allow not only extraction, but also re-packing of the previously extracted modules back into single file. There are also tools which are supposed to be used on specific modules to extract and allow modification of their content.
Here are a few of possible uses of the tools.
Replacing some components of the drone may require calibration. The tools are capable of triggering calibration in some devices, mostly gimbals with Hall sensors.
It is also possible to use them to send any custom packet to the drone, and this way trigger factory functions like calibration or pairing - as long as you know how the packet should look like.
The wiki of this project has tons of information about boards within each drone, and components on each board. This info is created and shared by many enthusiasts and repair technicians.
The tools can be used as command line version of DJI Assistant software, which also allows to change parameters for platforms which lacks such OEM software or where it has the advanced functions locked.
Flight Controllers from DJI define hunderds of parameters which affect their behavior. These can be modified by just sending a command to the drone, as long as the new value is within limits accepted by FC firmware.
The tools allow modifying firmware binaries, and then re-packing them back into flashable firmware package. This way, any software-controled functionality can be altered, including:
It may sometimes require additional knowledge and software modifications (ie. rooting the drone) to flash modified firmware - some firmware packages are signed using asymmetric cryptography, and private keys are rarely available.
If you're interested in DJI hardware and software, this is the place to start learning. You can:
Such instruction will not be provided. These tools are for engineers with vast hardware and software knowledge. You need to know what you're doing to achieve anything with these tools.
This is to make sure the tools won't be used by script kiddies to disable security mechanisms and to allow breaking local laws.
If you can't understand how the tools work, you should not use them. If any warnings are shown, you must investigate the cause to make sure final firmware will not be damaged. You are using the tools on your own risk.
If you don't know where to start, check the tests. They will provide you with command lines to communicate to the drone, or to extract all the layers of a specific firmware (as long as you can place it correctly).
Since all the tools are available in source code form, it is easy to check details on the structure and protocols processed by these tools by looking at their source. The source code is intended to also act as a format documentation.
For higher level and more hardware related info, check the project Wiki.
The tools can be divided into two categories:
Hardware-independent tools - Those for which you do not need to have any DJI product to use. You just need an input file they use, like DJI Firmware Package or DAT Log file.
Product Communication tools - You need to connect your drone to a PC in order to use these tools in any meaningful way. Currently the tools use serial interface (UART) and I2C.
Below the specific tools are described in short. Running them without parameters will give you details on supported commands in each of them.
To get specifics about command line arguments of each tool, run them with --help
option. Some tools also have additional remarks in their headers - try viewing them.
DJI Firmware xV4 Container tool; allows extracting modules from package file which
starts with xV4, or creating container by merging firmware modules. Use this tool
first, to extract the BIN file downloaded from DJI, as long as the file starts with
xV4.
Example of extracting modules from DJI firmware package for Phantom 3 Pro:
./dji_xv4_fwcon.py -vv -x -p P3X_FW_V01.08.0080.bin
DJI Firmware IMaH Un-signer and Decryptor tool; allows to decrypt and un-sign module
from .sig file which starts with IM*H. Use this tool after untarring single
modules from a firmware package, to decrypt its content. The tool can also re-sign
a module, as long as private part of the chosen key is available.
Keys used for encryption and authentication were changing over time; when an
IM*H file refers to a key for which the tool has several versions, it will
display a list of possible keys in a warning message, and select the most
recent key for current operation.
Example of un-signing Camera firmware for Mavic Pro:
./dji_imah_fwsig.py -vv -k PRAK-2017-01 -k PUEK-2017-07 -u -i wm220_0101_v02.00.55.69_20161215.pro.fw.sig
Example of un-signing FC firmware for Phantom 4 Pro V2:
./dji_imah_fwsig.py -vv -k PRAK-2017-01 -k PUEK-2017-07 -u -i wm335_0306_v03.03.04.10_20180429.pro.fw.sig
Example of signing previously un-signed FC firmware for Mini 2 (requires PRAK with private part):
./dji_imah_fwsig.py -vv -k PRAK-2019-09 -s -i wm161_0306_v03.04.09.74_20210112.pro.fw.sig
For more examples of usage of the tool, as well as identifiers of keys for specific
platforms, read the script used for testing it: tests/test_dji_imah_fwsig_rebin1.sh.
DJI Mavic Flight Controller Firmware Decryptor tool; removes second layer encryption
in Flight Controller firmware modules from several DJI products released around the
same period: Mavic Pro, Spark, Inspire 2 and Phantom 4. Does not accept IM*H
format - requires input files with first level encryption already removed.
Example of decrypting FC firmware for Mavic Pro:
./dji_mvfc_fwpak.py dec -i wm220_0306_v03.02.40.11_20170918.pro.fw
Ambarella A7/A9 firmware pack tool; allows extracting partitions from the firmware, or merging them back. Use this to extract Ambarella firmware from files created after DJI Container is extracted. You can recognize the Ambarella firmware by a lot of "Amba" strings within, or by a 32-char zero-padded string at the beginning of the file.
Example of extracting partitions from Ambarella firmware for Phantom 3 Pro:
./amba_fwpak.py -vv -x -m P3X_FW_V01.08.0080_m0100.bin
Ambarella A7/A9 firmware ROMFS filesystem tool; allows extracting single files from ROMFS filesystem file, or rebuilding filesystem from the single files. Use this after the Ambarella firmware is extracted. You can recognize ROMFS partitions by file names near beginning of the file, surrounded by blocks of 0xff filled bytes.
Example of extracting ROMFS partition from Ambarella firmware for Phantom 3 Pro:
./amba_romfs.py -vv -x -p P3X_FW_V01.08.0080_m0100_part_rom_fw.a9s
Linux script for mounting UBIFS partition from the Ambarella firmware. After
mounting, the files can be copied or modified. Use this after the Ambarella
firmware is extracted. The file containing UBIFS can be easily recognized
by UBI# at the beginning of the file.
Example of mounting Root Filesystem partition from Ambarella firmware for Phantom 3 Pro:
sudo ./amba_ubifs.sh P3X_FW_V01.08.0080_m0100_part_rfs.a9s
Tool which wrapps binary executable ARM images with ELF header. If a firmware contains binary image of executable file, this tool can rebuild ELF header for it. The ELF format can be then easily disassembled, as most debuggers can read ELF files. Note that using this tool on encrypted firmwares will not result in useable ELF.
Example of converting FC firmware for Phantom 3 to ELF:
./arm_bin2elf.py -vv -e -b 0x8020000 -l 0x6000000 -p P3X_FW_V01.07.0060_m0306.bin
The command above will cause the tool to try and detect where the border between
code (.text) and data (.data) sections should be. This detection is not perfect,
especially for binaries with no .ARM.exidx section between them. If .ARM.exidx
exists in the binary, the tool can easily find it and divide binary data properly,
treating .ARM.exidx as a separator between .text and .data.
In other words, position of the .ARM.exidx influences length of the .text section,
and starting offset of the .data section. If there is no .ARM.exidx section in
the file, it will still be used as separator, just with zero size.
After first look at the disassembly, it is good to check where the correct border
between .text and .data sections is located. Memory address of this location can
be used to generate better ELF file.
Additional updates to the ELF after first look can include defining .bss sections.
These sections represent uninitialized RAM and MMIO areasused by the binary. It is
tempting to just define one big section which covers whole memory map address range
according to programming guide of the chip, but that results in huge memory usage
and related slowdowns while disassembling the file, while also making the file harder
to navigate.
Note that all section offsets are defined using in-memory address, not the position within BIN file. If you have found proper location of a section within BIN file, remember to add base address to the file position before inserting to the command line of this tool.
Base address can be often found in programming guide of the specific chip; sometimes it may be shifted from that location, if the binary is loaded by an additional bootloader. In such cases the bootloader takes the location from documentation, and the real firmware binary is loaded at a bit higher base address.
Optimized examples for specific firmwares:
./arm_bin2elf.py -vv -e -b 0x8020000 --section .ARM.exidx@0x80A5D34:0 --section .bss@0x10000000:0x0A000 --section .bss2@0x20000000:0x30000 --section .bss3@0x40000000:0x30000 -p P3X_FW_V01.07.0060_m0306.bin
./arm_bin2elf.py -vv -e -b 0x000A000 --section .ARM.exidx@0x026E50:0 --section .bss@0x10000000:0x08000 --section .bss2@0x40000000:0x50000 --section .bss3@0xE0000000:0x10000 -p C1_FW_V01.06.0000_m1400.bin
No open issues yet, or sync has not completed.