抓取DNF手游封包示例,这里以聊天封包为示例
手游端对封包采用了lz4压缩算法和xor异或算法,除了body参与加密和压缩。其余都不加密
—————-协议格式——————————————-
totalLen | module | sequence | all-zero | body
short | short | byte | byte | byte[]
整个封包长度 包头ID反转 序列化主要用于XOR 业务id 加密数据包
例如一下数据 第3个字节和第4个字节为: 79 27需要翻转过来才是正确的包头ID也就是 27 79
1.客户端发送到服务端的封包数据(已解密)
1E 00 79 27 01 00 16 00 08 05 12 0C E6 B5 8B E8 AF 95 E5 B0 81 E5 8C 85 30 CF B1 D4 A2 01
2.客户端发送到服务端的封包数据(加密)
20 00 79 27 01 00 16 00 F1 06 09 04 13 0D E7 B4 8A E9 AE 94 E4 B1 80 E4 8D 84 31 CE B0 D5 A3 00
使用16进制转字符串就可以看到中文的明文部分
y'测试封包0ϱԢ
3.服务端发送到客户端封包数据(未加密)
2D 00 79 27 01 00 25 00 10 05 20 CF B1 D4 A2 01 52 1B E6 9C 8D E5 8A A1 E5 99 A8 E5 8F 91 E9 80 81 E8 81 8A E5 A4 A9 E5 B0 81 E5 8C 85
-y'% ϱԢR服务器发送聊天封包
4.服务端发送到客户端封包数据(加密)
2F 00 79 27 01 00 25 00 F1 17 11 04 21 CE B0 D5 A3 00 53 1A E7 9D 8C E4 8B A0 E4 98 A9 E4 8E 90 E8 81 80 E9 80 8B E4 A5 A8 E4 B1 80 E4 8D 84
———————————————客户端和服务端传输的加密手法
public static byte[] xor(byte[] in, byte xorByte) { byte[] res = new byte[in.length]; for (int i = 0; i < in.length; i++) { res[i] = (byte) (in[i] ^ xorByte); } return res; } public static byte[] lz4Compress(byte[] in, int decompressedLength) { int maxCompressedLength = lz4Compressor.maxCompressedLength(decompressedLength); byte[] compressedData = new byte[maxCompressedLength]; int compressedLength = lz4Compressor.compress(in, 0, decompressedLength, compressedData, 0, maxCompressedLength); byte[] res = new byte[compressedLength]; System.arraycopy(compressedData, 0, res, 0, compressedLength); return res; }
感谢大佬的分享,赞一个!
感谢大佬的分享,赞一个!