APP开发平台
Unity 3D开发
通信端口
连接 :56789(RM) <===> 45678(udp 广播),
通信UDP:10608(app) <===> 10607(RM)
工具
c#反汇编 dnSpy(https://github.com/dnSpy/dnSpy)
?抓包wireshark
抓包数据格式
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
|