IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> DJI Robomaster S1 APP反汇编 -> 正文阅读

[移动开发]DJI Robomaster S1 APP反汇编

APP开发平台

Unity 3D开发

通信端口

连接 :56789(RM) <===> 45678(udp 广播),

通信UDP:10608(app) <===> 10607(RM)

工具

c#反汇编 dnSpy(https://github.com/dnSpy/dnSpy)

?抓包wireshark

抓包数据格式

  • RM定时发送至APP,大小1514 +

APP目录

主要dll在应用目录:.\RoboMaster_Data\Managed

  • Assembly-CSharp.dll
  • Foundations.dll
  • RobotService.dll
  • Thirdparty.dll :第三方库封装?kdtree、protobuf、QR码(zxing)
  • Native.dll:平台相关(ios、android、MacOS、Windows):WifiManager、ShowWindow、HideWindow、ShowOpenFileDialog、ShowSaveFileDialog
  • 其余第三方库
    • firebase:数据库
    • zxing:qr码等
    • ZFBrowser:嵌入网页
    • Concentus.dll:Opus 语音 codec
    • Unity 及UnityEngine相关库
    • c#系统库

加密解密(DJIAlgorithmImpl, DJI.Foundations.Internal)

		// Token: 0x0600013F RID: 319 RVA: 0x000074BC File Offset: 0x000056BC		
		public static byte[] SimpleEncrypt(byte[] data)
		{
			byte[] array = new byte[data.Length];
			byte b = 7;
			for (int i = 0; i < data.Length; i++)
			{
				array[i] = (data[i] ^ b);
				b = (b + 7 ^ 178);
			}
			return array;
		}

		// Token: 0x06000140 RID: 320 RVA: 0x000074F8 File Offset: 0x000056F8
		public static byte[] SimpleDecrypt(byte[] data)
		{
			byte[] array = new byte[data.Length];
			byte b = 7;
			for (int i = 0; i < data.Length; i++)
			{
				array[i] = (data[i] ^ b);
				b = (b + 7 ^ 178);
			}
			return array;
		}

在DJICommonAlgorithm中封装:

		// Token: 0x06000075 RID: 117 RVA: 0x000040CD File Offset: 0x000022CD
		public static byte[] SimpleEncrypt(byte[] data)
		{
			return DJIAlgorithmImpl.SimpleEncrypt(data);
		}

		// Token: 0x06000076 RID: 118 RVA: 0x000040D5 File Offset: 0x000022D5
		public static byte[] SimpleDecrypt(byte[] data)
		{
			return DJIAlgorithmImpl.SimpleDecrypt(data);
		}

DJIUdpServer在

public class DJIUDPServer
	{
		// Token: 0x1700000D RID: 13
		// (get) Token: 0x060000A4 RID: 164 RVA: 0x00004543 File Offset: 0x00002743
		// (set) Token: 0x060000A5 RID: 165 RVA: 0x0000454B File Offset: 0x0000274B
		private DJIUDPServerErrorCode ErrorCode
		{
			get
			{
				return this.mErrorCode;
			}
			set
			{
				if (this.mErrorCode != value)
				{
					this.mErrorCode = value;
					Action<DJIUDPServerErrorCode> onError = this.OnError;
					if (onError == null)
					{
						return;
					}
					onError(this.mErrorCode);
				}
			}
		}

		// Token: 0x060000A6 RID: 166 RVA: 0x00004573 File Offset: 0x00002773
		public DJIUDPServer(int port)
		{
			this.m_ServerPort = port;
		}

		// Token: 0x060000A7 RID: 167 RVA: 0x00004582 File Offset: 0x00002782
		public bool Start()
		{
			return this.Start(this.m_ServerPort);
		}

		// Token: 0x060000A8 RID: 168 RVA: 0x00004590 File Offset: 0x00002790
		public bool Start(int port)
		{
			this.m_ServerPort = port;
			bool result;
			try
			{
				if (this.m_ServerSocket == null)
				{
					this.m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
					this.m_ServerSocket.Bind(new IPEndPoint(IPAddress.Any, this.m_ServerPort));
					this.m_ServerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
					this.m_ServerSocket.EnableBroadcast = true;
					DJIUDPServer.DJIStateObject djistateObject = new DJIUDPServer.DJIStateObject(this);
					AsyncCallback callback = new AsyncCallback(DJIUDPServer.AsyncRecvCallback);
					EndPoint endPoint = new IPEndPoint(IPAddress.Any, this.m_ServerPort);
					this.m_ServerSocket.BeginReceiveFrom(djistateObject.RecvBuffer, 0, djistateObject.RecvBuffer.Length, SocketFlags.None, ref endPoint, callback, djistateObject);
					this.ErrorCode = DJIUDPServerErrorCode.NoError;
				}
				Debuger.Log(DJIUDPServer.TAG, new string[]
				{
					"UDP Started"
				});
				result = true;
			}
			catch (Exception ex)
			{
				Debuger.Log(DJIUDPServer.TAG, new string[]
				{
					"UDP Start With Exception: " + ex.ToString()
				});
				this.Stop();
				this.ErrorCode = DJIUDPServerErrorCode.StartError;
				result = false;
			}
			return result;
		}

		// Token: 0x060000A9 RID: 169 RVA: 0x000046A8 File Offset: 0x000028A8
		public void Stop()
		{
			try
			{
				if (this.m_ServerSocket != null)
				{
					Socket serverSocket = this.m_ServerSocket;
					this.m_ServerSocket = null;
					serverSocket.Close();
					Debuger.Log(DJIUDPServer.TAG, new string[]
					{
						"UDP Stopped..."
					});
				}
			}
			catch (Exception ex)
			{
				Debuger.Log(DJIUDPServer.TAG, new string[]
				{
					"UDP Stop With Exception: " + ex.ToString()
				});
			}
		}

		// Token: 0x060000AA RID: 170 RVA: 0x00004720 File Offset: 0x00002920
		public bool SendDataTo(string targetIp, int port, byte[] buffer)
		{
			if (buffer == null || buffer.Length == 0)
			{
				return false;
			}
			bool result;
			try
			{
				IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(targetIp), port);
				result = (this.m_ServerSocket.SendTo(buffer, remoteEP) == buffer.Length);
			}
			catch (Exception ex)
			{
				Debuger.Log(DJIUDPServer.TAG, new string[]
				{
					"UDP Send Error: " + ex.ToString() + " IP:" + targetIp
				});
				result = false;
			}
			return result;
		}

		// Token: 0x060000AB RID: 171 RVA: 0x00004798 File Offset: 0x00002998
		private void OnRecvUDPMessage(string clientIp, int clientPort, byte[] message)
		{
			MonoSingleton<DJIThreading>.Instance.DispatchOnMainThread(delegate
			{
				DJIUDPServerRecvHandler onRecvData = this.OnRecvData;
				if (onRecvData == null)
				{
					return;
				}
				onRecvData(clientIp, clientPort, message);
			});
		}

		// Token: 0x060000AC RID: 172 RVA: 0x000047E0 File Offset: 0x000029E0
		private static void AsyncRecvCallback(IAsyncResult ar)
		{
			if (ar == null)
			{
				return;
			}
			DJIUDPServer.DJIStateObject djistateObject = (DJIUDPServer.DJIStateObject)ar.AsyncState;
			DJIUDPServer server = djistateObject.Server;
			try
			{
				Socket serverSocket = server.m_ServerSocket;
				if (serverSocket != null)
				{
					EndPoint endPoint = new IPEndPoint(IPAddress.Any, server.m_ServerPort);
					int num = serverSocket.EndReceiveFrom(ar, ref endPoint);
					if (num > 0)
					{
						byte[] array = new byte[num];
						Array.Copy(djistateObject.RecvBuffer, array, num);
						IPEndPoint ipendPoint = endPoint as IPEndPoint;
						server.OnRecvUDPMessage(ipendPoint.Address.ToString(), ipendPoint.Port, array);
					}
					AsyncCallback callback = new AsyncCallback(DJIUDPServer.AsyncRecvCallback);
					serverSocket.BeginReceiveFrom(djistateObject.RecvBuffer, 0, djistateObject.RecvBuffer.Length, SocketFlags.None, ref endPoint, callback, djistateObject);
					server.ErrorCode = DJIUDPServerErrorCode.NoError;
				}
			}
			catch (Exception ex)
			{
				Debuger.Log(DJIUDPServer.TAG, new string[]
				{
					"UDP AsyncRecvCallback Exception: " + ex.ToString()
				});
				server.ErrorCode = DJIUDPServerErrorCode.RecvError;
			}
		}

		// Token: 0x04000026 RID: 38
		private static readonly string TAG = "UDP";

		// Token: 0x04000027 RID: 39
		private Socket m_ServerSocket;

		// Token: 0x04000028 RID: 40
		private int m_ServerPort;

		// Token: 0x04000029 RID: 41
		public DJIUDPServerRecvHandler OnRecvData;

		// Token: 0x0400002A RID: 42
		public Action<DJIUDPServerErrorCode> OnError;

		// Token: 0x0400002B RID: 43
		private DJIUDPServerErrorCode mErrorCode;

		// Token: 0x0200003B RID: 59
		internal class DJIStateObject
		{
			// Token: 0x0600015B RID: 347 RVA: 0x0000783B File Offset: 0x00005A3B
			public DJIStateObject(DJIUDPServer server)
			{
				this.Server = server;
			}

			// Token: 0x0400006D RID: 109
			public byte[] RecvBuffer = new byte[256];

			// Token: 0x0400006E RID: 110
			public DJIUDPServer Server;
		}
	}

参考文献

1、大疆DJI Robomaster S1机器人通过4G网络远程控制的方法(无需改硬件)

https://www.jarvisw.com/?p=1328

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-17 12:03:47  更:2021-07-17 12:04:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 10:45:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码