Falamable/drone-protocol-analyzer

GitHub: Falamable/drone-protocol-analyzer

通过Wireshark抓包逆向分析DMH0002HW无人机的UDP控制协议,并用Python实现脱离官方App的编程控制。

Stars: 1 | Forks: 0

# 逆向工程我的无人机:物理项目 🚁 对于我的物理项目,我决定做点不一样的事情:我对我的 DMH002HW 无人机的通信协议进行了逆向工程,这样我就可以编写自己的 Python 脚本来控制它飞行! 这个项目帮助我将课堂上学到的关于**网络(UDP/IP)、十六进制、二进制数据和编程**的理论应用到了实际场景中。以下是我的具体操作步骤。 ## 1. 目标:破解无人机 通常,我使用手机上的官方 App 来控制无人机。该 App 通过 Wi-Fi 发送不可见的信号来控制无人机。 我想用我自己编写的 Python 代码来替换这个 App。但要做到这一点,我需要拦截这些信号,并理解 App 与无人机“对话”时使用的“语言”(即协议)。 ## 2. 方法:使用 Wireshark 进行抓包 为了弄清楚这个 App 是如何工作的,我在 PC 上安装了一个 Android 模拟器,安装了无人机的官方 App,并连接到了无人机的 Wi-Fi。然后,我使用了一个名为 **Wireshark** 的工具来记录模拟器和无人机之间的所有网络流量。Wireshark 就像一个窃听器,会记录连接上发送的每一个数据包。 我将这次记录保存为 `.pcapng` 文件。通过分析这个文件,我需要回答三个主要问题: 1. **数据发往哪里?**(IP 地址和端口) 2. **数据是如何发送的?**(协议) 3. **数据包含了什么内容?**(Payload) ## 3. 发现:破解代码 在盯着查看了大量的网络日志之后,我开始注意到一些规律,并成功破译了该协议! ### A. 地址簿(IP 和端口) - **协议:** 该 App 使用 **UDP**(用户数据报协议)。在我的 AS Level 课程大纲中,我了解到 UDP 速度很快,并且与 TCP 不同,它不需要等待确认。这对于控制无人机来说非常合理,因为你需要实时的控制并且做到零延迟。 - **目标 IP:** 无人机充当自己的 Wi-Fi 路由器。它的 IP 地址是 `192.168.169.1`。 - **端口:** 无人机在端口 `8800` 上监听控制命令。 ### B. 语言(十六进制 Payload) 计算机以二进制形式发送数据,但 Wireshark 以 **十六进制**(基数为 16)的形式显示,以便于阅读。我注意到主要发送了两种类型的数据包: #### 1. “启动 / 飞行”数据包(88 字节长) 在飞行过程中,该 App 大约每 30 毫秒发送一个巨大的数据包。如果我停止发送这些数据包,无人机就会假定连接已丢失并安全地悬停。 以下是其中一个数据包内部的原始十六进制数据: ``` ef 02 58 00 02 02 00 01 00 00 00 00 [a6 07 00 00] 08 00 66 80 [80 80 81 40] 41 ... ``` 以下是我的破译过程: - **`ef 02`**:这是一个“魔数”。它基本上是在告诉无人机:“嘿,这是一个控制数据包!” - **`58 00`**:数据包的长度(十六进制的 `0x58` 等于十进制的 88)。 - **`[a6 07 00 00]`**:这是**序列号**。每发送一个数据包,它就会增加 1。它帮助无人机忽略旧的、延迟的数据包。 - **`[80 80 81 40]`**:这些是实际的**摇杆数值**! - `0x80` 在十进制中是 128。由于一个字节的范围是 0-255,所以 128 正好处于中间位置。这意味着俯仰、横滚和偏航的摇杆正处于完美的居中状态。 - `0x40` 在十进制中是 64。这代表油门(高度控制)处于零位/怠速状态。 #### 2. “停止”数据包(4 字节长) 当我关闭 App 或按下停止键时,它会发送一个微小的 4 字节数据包,立即终止连接: ``` ef 00 04 00 ``` ## 4. 解决方案:编写 Python 脚本 既然我已经知道了 IP、端口和确切的十六进制代码,我就可以使用 Python 构建完全相同的数据包,并通过 Wi-Fi 将它们发送出去。 这是我编写的 Python 脚本。它使用 `socket` 库连接到无人机,发送“怠速”控制命令 5 秒钟以保持其存活,然后干净地将其关闭。 ``` import socket import time import struct DRONE_IP = "192.168.169.1" DRONE_PORT = 8800 def create_control_packet(seq_num): # This is the 88-byte hex payload I copied from Wireshark. # The joysticks are centered, and throttle is zero. base_hex = ( "ef025800020200010000000000000000" # First 16 bytes "08006680808081404199000000000000" # Next 16 bytes (Joysticks are here!) "00000000000000000000000000000000" "00000000000000000000000000000000" "00000000000000000000000000000000" "324b142d0000" # Last 6 bytes ) # Convert the long string of hex into actual raw bytes packet = bytearray.fromhex(base_hex) # I used the 'struct' library to easily inject my increasing # Sequence Number into bytes 12, 13, 14, and 15 in Little-Endian format. packet[12:16] = struct.pack("
标签:Android 模拟器, DMH0002HW, Python 控制脚本, UDP 协议, Wi-Fi FPV 无人机, Wireshark, 二进制解析, 十六进制数据分析, 句柄查看, 无人机逆向工程, 无线通信, 物理学项目, 物联网黑客, 硬件黑客, 移动应用逆向, 网络数据包分析, 自定义飞行控制, 计算机网络实践, 逆向工具, 通信协议分析, 防御绕过, 飞行控制指令 (油门/偏航/俯仰/翻滚)