o-gs/dji-firmware-tools

GitHub: o-gs/dji-firmware-tools

一套用于提取、解密、修改和重新打包 DJI 无人机固件的开源工具集,支持多代产品的固件分析与设备通信。

Stars: 2137 | Forks: 504

# dji-firmware-tools 用于提取、修改和重新打包 [DJI](http://www.dji.com) 多旋翼无人机固件的工具。 # 动机 该项目最初是作为 [phantom-licensecheck](https://github.com/probonopd/phantom-licensecheck) 解析器的替代实现而开始的。 随着时间的推移,它已经发展到支持多代 DJI 产品。 它包含的工具不仅允许提取,还允许将先前提取的模块重新打包 回单个文件中。还有一些工具专门用于特定模块, 以提取并允许修改其内容。 # 用例 以下是该工具的一些可能用途。 ### 维修后的校准 更换无人机的某些组件可能需要校准。这些工具 能够在某些设备中触发校准,主要是配备 [霍尔传感器](https://en.wikipedia.org/wiki/Hall_effect_sensor) 的云台。 也可以使用它们向无人机发送任何自定义数据包, 从而触发出厂功能(如校准或配对)——只要 你知道该数据包应该是什么样子。 ### 板级和组件级零件识别 [本项目的 wiki](https://github.com/o-gs/dji-firmware-tools/wiki) 包含大量关于每架无人机内部电路板, 以及每块电路板上组件的信息。这些信息由许多爱好者 和维修技术人员创建并分享。 ### 飞行参数修改 该工具可用作 DJI Assistant 软件的命令行版本, 这也允许为缺乏此类 OEM 软件或高级功能被锁定的平台更改参数。 来自 DJI 的 Flight Controllers 定义了数百个影响其 行为的参数。只要新值在 FC 固件接受的范围内, 就可以通过向无人机发送命令来修改这些参数。 ### 固件修改 这些工具允许修改固件二进制文件,然后将其重新打包 回可刷写的固件包中。这样,任何由软件控制的功能 都可以被更改,包括: * 硬件配对可以被禁用, * 参数的允许值范围可以被更改, * 所有硬编码的限制都可以被取消或扩展, * 未使用的硬件功能可以被启用, * 额外的设备可以被添加并集成到无人机中, * 任何你能想到的内容,只要你有能力实现这些更改。 有时可能需要额外的知识和软件修改 (即对无人机进行 root)才能刷入修改后的固件——某些固件包 使用非对称加密进行签名,而私钥很少可用。 ### 研究 如果你对 DJI 的硬件和软件感兴趣,这里是开始 学习的起点。你可以: * 捕获并分析无人机和 RC 内模块之间的通信, 以弄清楚特定硬件和软件的功能, * 使用 wiki 比较各平台之间的硬件和软件,或者在 打开无人机之前在组件级分析电路板, * 提取固件更新包,以分析和比较由 无人机内每个可编程芯片执行的二进制文件, * 分析固件中的特定二进制文件,例如将其转换为 ELF 并使用反汇编器查看内容,应用符号以便 更容易理解代码的功能, * 查找固件二进制文件和通信协议中的安全漏洞, * 比较不同 FW 包版本之间的固件二进制文件, * 解析无人机生成的飞行日志, * 获取一些基础知识,以便在与改装者或研究人员 社区互动时不会显得愚蠢。 # 分步说明 不会提供此类说明。这些工具适用于具有丰富 硬件和软件知识的工程师。你需要知道自己在做什么才能 使用这些工具实现任何目标。 这是为了确保这些工具不会被 script kiddies 用于禁用 安全机制并允许违反当地法律。 如果你不明白这些工具是如何工作的,就不应该使用它们。如果出现任何 警告,你必须调查原因,以确保最终固件 不会损坏。使用这些工具的风险由你自己承担。 如果你不知道从哪里开始,请查看 [tests](#tests)。它们将为你 提供与无人机通信的命令行,或者提取特定固件 所有层的命令行(前提是你能正确放置它)。 # 固件结构 由于所有工具均以源代码形式提供,因此通过查看其源代码, 可以轻松查看这些工具处理的结构和协议的详细信息。 源代码也可用作格式文档。 有关更高级别和更多与硬件相关的信息,请查看[项目 Wiki](https://github.com/o-gs/dji-firmware-tools/wiki)。 # 工具 这些工具可分为两类: * 独立于硬件的工具 —— 使用这些工具你不需要拥有任何 DJI 产品。 你只需要它们使用的输入文件,例如 DJI Firmware Package 或 DAT Log 文件。 * 产品通信工具 —— 你需要将无人机连接到 PC, 才能以任何有意义的方式使用这些工具。目前,这些工具使用串行接口 (UART)和 I2C。 下面简要介绍这些特定的工具。在不带参数运行它们时, 将为你提供每个工具支持命令的详细信息。 要获取每个工具命令行参数的具体信息,请使用 `--help` 选项运行它们。一些工具在其头部还有额外说明——尝试查看它们。 ### dji_xv4_fwcon.py DJI Firmware xV4 Container 工具;允许从以 `xV4` 开头的包文件中提取模块, 或通过合并固件模块来创建容器。请首先使用此工具 提取从 DJI 下载的 BIN 文件,前提是该文件以 `xV4` 开头。 从 *Phantom 3 Pro* 的 DJI 固件包中提取模块的示例: ```./dji_xv4_fwcon.py -vv -x -p P3X_FW_V01.08.0080.bin``` ### dji_imah_fwsig.py DJI Firmware IMaH Un-signer 和解密工具;允许从以 `IM*H` 开头的 `.sig` 文件中解密和取消签名模块。在从固件包中解包单个 模块后使用此工具,以解密其内容。只要所选密钥的 私钥可用,该工具也可以对模块进行重新签名。 用于加密和身份验证的密钥随着时间的推移而变化;当 `IM*H` 文件引用工具拥有多个版本的密钥时,它将 在警告消息中显示可能的密钥列表,并为当前操作选择 最新的密钥。 为 *Mavic Pro* 取消签名 Camera 固件的示例: ```./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``` 为 *Phantom 4 Pro V2* 取消签名 FC 固件的示例: ```./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``` 为 *Mini 2* 签名先前未签名的 FC 固件的示例(需要带私钥部分的 `PRAK`): ```./dji_imah_fwsig.py -vv -k PRAK-2019-09 -s -i wm161_0306_v03.04.09.74_20210112.pro.fw.sig``` 有关该工具用法的更多示例,以及特定 平台的密钥标识符,请阅读用于测试它的脚本:`tests/test_dji_imah_fwsig_rebin1.sh`。 ### dji_mvfc_fwpak.py DJI Mavic Flight Controller Firmware 解密工具;移除大约同一时期发布的几款 DJI 产品: *Mavic Pro*、*Spark*、*Inspire 2* 和 *Phantom 4* 的 Flight Controller 固件模块中的第二层加密。不接受 `IM*H` 格式——要求输入文件已经移除了第一层加密。 为 *Mavic Pro* 解密 FC 固件的示例: ```./dji_mvfc_fwpak.py dec -i wm220_0306_v03.02.40.11_20170918.pro.fw``` ### amba_fwpak.py Ambarella A7/A9 固件包工具;允许从固件中提取分区, 或将它们合并回去。在提取 DJI Container 后创建的文件中 使用此工具提取 Ambarella 固件。你可以通过其中包含的大量 "Amba" 字符串,或文件开头的 32 字符零填充字符串 来识别 Ambarella 固件。 从 *Phantom 3 Pro* 的 Ambarella 固件中提取分区的示例: ```./amba_fwpak.py -vv -x -m P3X_FW_V01.08.0080_m0100.bin``` ### amba_romfs.py Ambarella A7/A9 固件 ROMFS 文件系统工具;允许从 ROMFS 文件系统文件中提取单个文件, 或从单个文件重建文件系统。 在提取 Ambarella 固件后使用此工具。你可以通过文件开头附近的文件名 (被 0xff 填充字节块包围)来识别 ROMFS 分区。 从 *Phantom 3 Pro* 的 Ambarella 固件中提取 ROMFS 分区的示例: ```./amba_romfs.py -vv -x -p P3X_FW_V01.08.0080_m0100_part_rom_fw.a9s``` ### amba_ubifs.sh 用于挂载 Ambarella 固件中 UBIFS 分区的 Linux 脚本。挂载 后,可以复制或修改文件。在提取 Ambarella 固件后使用此工具。可以通过文件开头的 `UBI#` 轻松识别包含 UBIFS 的文件。 从 *Phantom 3 Pro* 的 Ambarella 固件挂载 Root Filesystem 分区的示例: ```sudo ./amba_ubifs.sh P3X_FW_V01.08.0080_m0100_part_rfs.a9s``` ### arm_bin2elf.py 用 ELF 头包装二进制可执行 ARM 镜像的工具。如果固件 包含可执行文件的二进制镜像,此工具可以为其重建 ELF 头。 这样就可以轻松反汇编 ELF 格式,因为大多数调试器都可以读取 ELF 文件。 请注意,在加密固件上使用此工具将无法生成可用的 ELF。 将 *Phantom 3* 的 FC 固件转换为 ELF 的示例: ```./arm_bin2elf.py -vv -e -b 0x8020000 -l 0x6000000 -p P3X_FW_V01.07.0060_m0306.bin``` 上述命令将使该工具尝试检测代码 (`.text`) 和数据 (`.data`) 段之间的边界应该在哪里。这种检测并不完美, 特别是对于它们之间没有 `.ARM.exidx` 段的二进制文件。如果二进制文件中存在 `.ARM.exidx`,则该工具可以轻松找到它并正确划分二进制数据, 将 `.ARM.exidx` 视为 `.text` 和 `.data` 之间的分隔符。 换句话说,`.ARM.exidx` 的位置会影响 `.text` 段的长度, 以及 `.data` 段的起始偏移量。如果文件中没有 `.ARM.exidx` 段,它仍将用作分隔符,只是大小为零。 在初步查看反汇编后,最好检查一下 `.text` 和 `.data` 段之间的正确边界位于何处。此位置的内存地址 可用于生成更好的 ELF 文件。 在初步查看后对 ELF 进行额外更新可以包括定义 `.bss` 段。 这些段代表二进制文件使用的未初始化 RAM 和 MMIO 区域。 你可能很想根据芯片的编程指南直接定义一个覆盖整个 内存映射地址范围的大段,但这会导致巨大的内存占用 并在反汇编文件时造成相关减速,同时也会使文件更难 导航。 请注意,所有段偏移量都是使用内存中的地址定义的,而不是 BIN 文件中的 位置。如果你在 BIN 文件中找到了某个段的位置, 请记住在插入到此工具的命令行之前,将基地址添加到该文件位置。 基地址通常可以在特定芯片的编程指南中找到;有时它 可能会偏离该位置,前提是二进制文件是由额外的 bootloader 加载的。 在这种情况下,bootloader 会从文档中获取该位置,而真正的固件 二进制文件会加载到稍高一点的基地址处。 针对特定固件的优化示例: ```./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``` ```./arm_bin2elf.py -vv -e -b 0x000A000 --section .ARM.exidx@0x0212E0:0 --section .bss@0x00000:0x08000 --section .bss2@0x40000000:0x50000 --section .bss3@0xE0000000:0x10000 -p C1_FW_v01.09.0200_m1400.bin``` ```./arm_bin2elf.py -vv -e -b 0x000A000 --section .ARM.exidx@0x0233E0:0 --section .bss@0x02000000:0x04000 --section .bss2@0x2008000:0x1000 --section .bss3@0x1C000000:0x2400 --section .bss4@0x1c024000:0x2400 --section .bss5@0x4002C000:0x50000 --section .bss6@0x400F8000:0x200 --section .bss7@0xE000E000:0x1200 -p C1_FW_V01.06.0000_m1401.bin``` ```./arm_bin2elf.py -vv -e -b 0x8008000 --section .ARM.exidx@0x8015510:0 --section .bss@0x1FFFF700:0x05A00 --section .bss2@0x40000000:0x6700 --section .bss3@0x40010000:0x5500 --section .bss4@0x40020000:0x2200 --section .bss5@0x42200000:0x100 --section .bss6@0x42420000:0x500 -p P3X_FW_V01.08.0080_m0900.bin``` ```./arm_bin2elf.py -vv -e -b 0x8008000 --section .ARM.exidx@0x801B6D0:0 --section .bss@0x1FFFF700:0x0C900 --section .bss2@0x40000000:0x6700 --section .bss3@0x40010000:0x5500 --section .bss4@0x40020000:0x7000 --section .bss5@0x50060800:0x100 -p P3X_FW_V01.11.0030_m0400.bin``` ```./arm_bin2elf.py -vv -e -b 0x0420000 --section .ARM.exidx@0x4EDAF0:0 --section .bss@0x20400000:0x40000 --section .bss4@0x42200000:0x100 -p MATRICE600_FW_V02.00.00.21_m0306.bin``` ```./arm_bin2elf.py -vv -e -b 0x0420000 --section .ARM.exidx@0x4F0E00:0 --section .bss@0x20400000:0x60100 --section .bss2@0x400E0000:0x2000 -p wm330_0306_v03.01.10.93_20160707.fw_0306.decrypted.bin``` ```./arm_bin2elf.py -vv -e -b 0x0420000 --section .ARM.exidx@0x5277d0:0 --section .bss@0x20400000:0x60000 --section .bss2@0x400E0000:0x1000 --section .bss3@0xE0000000:0x10000 -p wm100_0306_v03.02.43.20_20170920.pro.fw_0306.decrypted.bin``` ```./arm_bin2elf.py -vv -e -b 0x0420000 --section .ARM.exidx@0x5465d8:0 --section .bss@0x20400000:0x60100 --section .bss2@0x400E0000:0x2000 -p wm220_0306_v03.02.35.05_20170525.pro.fw_0306.decrypted.bin``` ```./arm_bin2elf.py -vv -e -b 0x7D000000 --section .ARM.exidx@0x7D0356E0:0 --section .bss@0x7D04f380:0x3800 --section .bss2@0x7D0f1900:0x200 -p wm230_0801_v10.00.07.12_20180126-recovery.img.TZOS.bin``` ```./arm_bin2elf.py -vv -e -b 0xFFFC0000 --section .ARM.exidx@0xFFFDA540:0x20 --section .bss@0xFFFE14D0:0x42B0 --section .bss1@0x0202000:0x20 --section .bss2@0x0402020:0x20 --section .bss3@0x0B00000:0x40 --section .bss4@0x2700000:0x40 --section .bss5@0x9000000:0x20 --section .bss6@0xF0440000:0x4500 --section .bss7@0xF0501200:0x200 --section .bss8@0xF0A09000:0x20 --section .bss9@0xF0A40000:0x1200 --section .bss10@0xF0A4D000:0x2100 --section .bss11@0xF0A61000:0x1200 --section .bss12@0xF0A72000:0x20 --section .bss13@0xF0D02000:0x20 --section .bss14@0xF0D04000:0x20 --section .bss15@0xF0E00A00:0xC0 --section .bss16@0xF0E08000:0x20 --section .bss17@0xF5001000:0x40 --section .bss18@0xF6409000:0x100 --section .bss19@0xF6800000:0x1200 --section .bss20@0xFA800000:0x100 --section .bss21@0xFAF01000:0x3500 --section .bss22@0xFB001000:0x2900 --section .bss23@0xFCC01000:0x2400 --section .bss24@0xFD001000:0x2D00 --section .bss25@0xFD400000:0x20 --section .bss26@0xFD501000:0x2400 --section .bss27@0xFF001000:0x1100 -p wm230_0801_v10.00.07.12_20180126.pro.fw_0801.bootarea_p0_BLLK.bin``` 此工具仅支持 bin 到 elf 方向的转换。要将 ELF 文件转换回 BIN(即在修改后),请使用针对 特定架构的 `objcopy` 实用程序。`objcopy` 工具是 GNU Binary Utilities (`binutils`)的一部分,而不是本仓库的一部分。 示例: ```arm-none-eabi-objcopy -O binary P3X_FW_V01.07.0060_m0100_part_sys.elf P3X_FW_V01.07.0060_m0100_part_sys.bin``` ```arm-none-eabi-objcopy -O binary P3X_FW_V01.07.0060_m0900.elf P3X_FW_V01.07.0060_m0900.bin``` ### amba_sys2elf.py Ambarella A7/A9 固件“系统软件”分区转换器。该分区 包含可执行文件的二进制镜像,此工具用 ELF 头对其进行包装。这样就可以轻松反汇编 ELF 格式, 因为大多数调试器都可以读取 ELF 文件。此工具与 `arm_bin2elf.py` 非常相似, 只是它针对特定固件进行了预配置。 示例: ```./amba_sys2elf.py -vv -e -l 0x6000000 -p P3X_FW_V01.08.0080_m0100_part_sys.a9s``` 为 `arm_bin2elf.py` 解释的所有边界调整规则同样适用于此工具。 针对特定固件的优化示例: ```./amba_sys2elf.py -vv -e -l 0x6000000 --section .ARM.exidx@0xEA83E4C:0 -p P3X_FW_V01.08.0080_m0100_part_sys.a9s``` ```./amba_sys2elf.py -vv -e -l 0x6000000 --section .ARM.exidx@0xEA82EC0:0 -p P3X_FW_V01.07.0060_m0100_part_sys.a9s``` ```./amba_sys2elf.py -vv -e -l 0x6000000 --section .ARM.exidx@0xEA64774:0 -p P3X_FW_V01.01.0008_m0100_part_sys.a9s``` ### amba_sys_hardcoder.py Ambarella A7/A9 固件“系统软件”分区硬编码值编辑器。 该工具可以解析转换为 ELF 的 Ambarella 固件 SYS 分区。 它在二进制数据中查找某些硬编码值,并允许 导出或导入它们。导出的 JSON 文件中只有 `setValue` 元素 是真正可更改的,所有其他数据仅供参考。 将硬编码值导出到 JSON 文件的示例: ```./amba_sys_hardcoder.py -vv -x --elffile P3X_FW_V01.08.0080_m0100_part_sys.elf``` 从 JSON 文件导入值并返回到 ELF 的示例: ```./amba_sys_hardcoder.py -vv -u --elffile P3X_FW_V01.08.0080_m0100_part_sys.elf``` ### dm3xx_encode_usb_hardcoder.py Dji DM3xx DaVinci encode_usb 二进制硬编码值编辑器。 该工具可以解析来自 TI DM3xx DaVinci Media Processor 的 Dji Firmware 模块中的 encode_usb ELF 文件。 它在二进制数据中查找某些硬编码值,并允许 导出或导入它们。 将硬编码值导出到 JSON 文件的示例: ```./dm3xx_encode_usb_hardcoder.py -vv -x --elffile P3X_FW_V01.07.0060_m0800-encode_usb.elf``` 从 JSON 文件导入值并返回到 ELF 的示例: ```./dm3xx_encode_usb_hardcoder.py -vv -u --elffile P3X_FW_V01.07.0060_m0800-encode_usb.elf``` ### lightbridge_stm32_hardcoder.py Dji Lightbridge STM32 微控制器二进制硬编码值编辑器。 该工具可以解析转换为 ELF 的 Lightbridge MCU 固件。 它在二进制数据中查找某些硬编码值,并允许 导出或导入它们。 将硬编码值导出到 JSON 文件的示例: ```./lightbridge_stm32_hardcoder.py -vv -x --elffile P3X_FW_V01.07.0060_m0900.elf``` 从 JSON 文件导入值并返回到 ELF 的示例: ```./lightbridge_stm32_hardcoder.py -vv -u --elffile P3X_FW_V01.07.0060_m0900.elf``` ### dji_flyc_hardcoder.py Dji Flight Controller 固件二进制硬编码值编辑器。 该工具可以解析转换为 ELF 的 Flight Controller 固件。 它在二进制数据中查找某些硬编码值,并允许 导出或导入它们。 将硬编码值导出到 JSON 文件的示例: ```./dji_flyc_hardcoder.py -vvv -x -e P3X_FW_V01.07.0060_m0306.elf``` 从 JSON 文件导入值并返回到 ELF 的示例: ```./dji_flyc_hardcoder.py -vvv -u -e P3X_FW_V01.07.0060_m0306.elf``` ### dji_flyc_param_ed.py Flight Controller Firmware Parameters Array Editor 在固件二进制文件中查找飞行 参数数组,并允许将参数提取到 JSON 格式的文本文件中。然后可以轻松修改此文件,并用于更新 二进制固件,从而更改每个参数的属性和限制。 为了查找参数数组,该工具需要用于将 二进制文件加载到微控制器 RAM 中使用的基地址。如果你不知道要使用的 基地址,特定芯片的编程指南可能会为你提供线索。 提取然后更新 Flight Controller的示例: ```./dji_flyc_param_ed.py -vv -x -m P3X_FW_V01.07.0060_m0306.bin``` ```./dji_flyc_param_ed.py -vv -u -m P3X_FW_V01.07.0060_m0306.bin``` 更多其他产品的示例: ```./dji_flyc_param_ed.py -vv -x -b 0x420000 -m A3_FW_V01.02.00.00_m0306.bin``` ```./dji_flyc_param_ed.py -vv -x -b 0x420000 -m MATRICE600_FW_V02.00.00.21_m0306.bin``` ```./dji_flyc_param_ed.py -vv -x -b 0x420000 -m MATRICE600PRO_FW_V01.00.00.80_m0306.bin``` ```./dji_flyc_param_ed.py -vv -x -b 0x420000 -m wm220_0306_v03.02.35.05_20170525.pro.bin``` ```./dji_flyc_param_ed.py -vv -x -b 0x0000 -m wm230_0306_v01.00.02.255_20170213.bin``` ### comm_dat2pcap.py 带有 pcap 输出格式的 DJI Universal Packet Container 流解析器。 该脚本解析 Raw DUML 流(即飞行日志文件 ```FLY???.DAT```)并用 PCap 头包装单个数据包。在传递数据之前会检查数据包的 CRC。 然后可以使用任何支持 PCap 格式的工具来分析数据(即 Wireshark)。 转换飞行日志文件的示例: ```./comm_dat2pcap.py -vv -d FLY002.DAT``` ### comm_serial2pcap.py 带有 DUML 打包器和 PCap 输出格式的 DJI 串行总线嗅探器。 该脚本从两个 UART 捕获数据,并用 PCap 头包装单个 DUML 数据包。 在将数据传递到 PCap 文件或 FIFO 管道之前,会检查数据包的 CRC。 然后可以使用任何支持 pcap 格式的工具来分析数据(即 Wireshark)。 该实用程序需要两个串行接口,其 RX 线连接到无人机 内部的 RX 和 TX 线。 从两个 UART-to-TTL(又名 FTDI)转换器开始捕获的示例: ```./comm_serial2pcap.py -b 115200 -F /tmp/wsf /dev/ttyUSB0 /dev/ttyUSB1``` ### comm_mkdupc.py 带有十六进制字符串输出的 DUML Packet Builder。 此工具可以构建一个包含给定报头字段和 payload 的正确 DUML 数据包。 该数据包将以十六进制形式输出。已知命令的列表和预期 payload 的外观可以在下文所述的 Wireshark 解析器中找到。 生成数据包以向 Spark Camera 模块询问其 Sensor ID 的示例: ```./comm_mkdupc.py --receiver_type=Camera --seq_num=65280 --ack_type=ACK_After_Exec --cmd_set=Camera --cmd_id=181``` ### comm_serialtalk.py 向 DJI 产品发送数据包并接收响应的 DUML Builder。 此工具构建包含给定报头字段和 payload 的正确 DUML 数据包。 然后它通过给定的串行端口发送,并等待响应。它会在 收到返回的数据包时将其显示出来。 它可以被视为某些无人机中可以找到的 `dji_mb_ctrl` 二进制文件的 替代品。不过,这两个工具之间的参数名称是不同的。 向 Flight Controller 询问硬件和固件版本数据的示例(在 Ph3 上测试): ```./comm_serialtalk.py --port /dev/ttyUSB0 -vv --timeout=5000 --receiver_type=FlyController --seq_num=65280 --ack_type=No_ACK_Needed --cmd_set=General --cmd_id=1``` 向 Flight Controller 询问硬件和固件版本数据的示例(Mavic 3): ```./comm_serialtalk.py --bulk -vv --timeout=5000 --receiver_type=FlyController --seq_num=65280 --ack_type=ACK_After_Exec --cmd_set=General --cmd_id=1``` ### comm_og_service_tool.py 适用于 Dji 产品的 OGs Service Tool。 该脚本允许触发 Dji 无人机的几项服务功能。它与无人机 进行通信的方式类似于 `comm_serialtalk.py`,但为某些重要功能 提供了更简便的接口。 将 Ph3 Pro 上的 Flight Controller 参数 200-300 列出为 CSV 格式的示例: ```./comm_og_service_tool.py --port /dev/ttyUSB0 P3X FlycParam list --start=200 --count=100 --fmt=csv``` 获取 Spark 上 Flight Controller 参数值的示例: ```./comm_og_service_tool.py --port /dev/ttyUSB0 -vv SPARK FlycParam get g_config.flying_limit.max_height_0 --fmt=2line``` 设置 Spark 上 Flight Controller 参数值的示例: ```./comm_og_service_tool.py --port /dev/ttyUSB0 -vv SPARK FlycParam set g_config.flying_limit.max_height_0 500``` 执行 Spark 云台 "joint coarse" 校准服务的示例: ```./comm_og_service_tool.py --port /dev/ttyUSB0 -vv SPARK GimbalCalib JointCoarse``` 使用 Windows 主机执行 Spark 云台 "linear hall" 校准服务的示例: ```python3 comm_og_service_tool.py --port COM23 -vv SPARK GimbalCalib LinearHall``` 将 Mavic 3 Pro 上的 Flight Controller 参数 200-300 列出为 CSV 格式的示例: ```./comm_og_service_tool.py --bulk MAV3 FlycParam list --start=200 --count=100 --fmt=csv``` ### comm_sbs_bqctrl.py Smart Battery System 通信工具。 此工具允许与基于 Smart Battery Data Specification 设计的芯片进行交互。它还支持 Texas Instruments 在其 BQ 系列 电量计芯片中实现的对该规范的某些扩展。 使用此工具需要连接到兼容 SBS 芯片的 SMBus 线 (SDA,SCL,GND)。SMBus 通信使用 I2C 作为基础,因此大多数带有 I2C 总线的设备都可以用来建立通信。 使用 I2C 接口简单读取 BatteryStatus() 的示例(脚本将在内部构造 SMBus 消息): ```./comm_sbs_bqctrl.py -vvv --bus "i2c:1" --dev_address 0x0b read BatteryStatus``` 使用 SMBus 接口,通过 ManufacturerAccess() 从 BQ30z55 读取多个标志字段的示例: ```./comm_sbs_bqctrl.py -v --bus "smbus:1" --dev_address 0x0b --chip BQ30z55 --short monitor BQStatusBitsMA``` 使用默认 SHA-1 密钥、在操作系统的第二个总线设备上使用 I2C 接口解封 BQ30z55(启用写入功能)的示例: ```./comm_sbs_bqctrl.py -v --bus "i2c:2" --dev_address 0x0b --chip BQ30z55 --short sealing Unseal``` ### tests `tests` 文件夹包含一组脚本,可用于验证 这些工具是否正常工作。那里有两种通用类型的测试: * 通信工具测试,标记为 `comm`。这些是针对通常与 真实设备通信的脚本。测试将预期的答案注入接收 缓冲区,因此无需连接产品即可运行它们。 * 固件提取工具测试,标记为 `fw_xv4`、`fw_imah_v1`、`fw_imah_v2`。 这些测试提取并重新打包在 `fw_packages` 目录中找到的固件, 然后将生成的文件与原始文件进行比较,以检查是否引入了 意外的更改。 除了测试你的修改之外,你还可以将这些测试用作这些工具更多 用例的来源。它们记录了用于提取特定 固件和在产品上执行特定命令的命令行。 这些测试准备与 `pytest` 一起使用。执行所有测试的示例: ```pytest tests -rsx --full-scope --log-cli-level=INFO``` `--full-scope` 选项使测试在所有已知的二进制文件上执行, 而不是在用于持续集成的选定二进制文件上执行。CI 测试是有选择性的, 以确保自动测试能在合理的时间内完成。 请记住,这些测试只会在放置在 `fw_packages` 文件夹的正确子文件夹中的二进制文件上运行。可以在测试脚本中 轻松找到子文件夹的有效名称。如果没有将固件二进制文件放入该文件夹, 所有固件提取测试都将被跳过。 除了运行所有测试外,你还可以运行特定测试(使用 `-k`)或一组 带有特定标记的测试(使用 `-m`)。仅运行 `fw_xv4` 测试的示例: ```pytest tests -rsx --full-scope -m fw_xv4 --log-cli-level=DEBUG``` ### comm_dissector 该文件夹包含 [Wireshark](https://www.wireshark.org/) 解析器,用于分析 DJI 无人机接口中的通信。 该工具的文档[包含在其文件夹中](comm_dissector/README.md)。 # 符号 对于特定版本的某些特定固件模块,在 'symbols' 目录中提供了部分 符号。这些符号采用两种格式: - MAP 文件 —— 只需极少的精力即可加载到大多数反汇编器中。对于 IDA Pro, 有一个插件可以读取 MAP 文件并相应地重命名函数和变量。 这些文件中仅包含被赋予有意义名称的函数和全局变量。 - IDC 脚本 —— IDA Pro 专用的格式。不仅存储函数和全局变量, 还存储类型信息——枚举和结构体。也允许存储带有名称 和类型的函数参数和局部变量。可以通过 IDA Pro 轻松应用于 已打开的 ELF 文件,其他工具都无法理解它。 符号与上述工具生成的 ELF 文件相匹配, 而不是直接与 BIN 匹配。请使用上一节中提供的示例命令 生成内容与符号相匹配的 ELF 文件。 当你为没有可用符号的固件版本进行工作时,你可能 希望使用带有符号的版本作为命名参考。 如果你正在寻找用于参考符号的最佳 FW 版本,或者你根本不在乎 FW 版本,而只想要最完整的符号——请检查 MAP 文件的大小。MAP 文件主要包含手动命名的符号,因此最大的那个文件将对应 进行了更多逆向工程工作的固件版本。
标签:Cutter, 固件工具, 大疆, 客户端加密, 嵌入式系统, 无人机, 硬件破解, 系统逆向, 逆向工具