某xun视频通信协议逆向分析

admin 2025年1月6日22:57:14评论12 views字数 15591阅读51分58秒阅读模式
某xun视频通信协议逆向分析

在一些app中通信架构的方式,没有进入so库就让让逆向分析人员非常难处理,以某大厂的某某视频介绍下整体的流程。

某xun视频通信协议逆向分析
 目录

一.抓包分析

二.找到加密点

三.还原加密流程

四.代码还原

总结

一.抓包分析

如下图所示请求体和响应体都被加密了,如果我们想要获得这个接口的数据那么就找到请求发送的逻辑及其请求被解包的逻辑

某xun视频通信协议逆向分析

二.找到加密点

frida-trace -U - -j "*!AdFeedImagePoster" com.t***.******frida-trace -U -F -j "AdFeedImagePoster!*" com.t***.******

result:

/* TID 0x37fb */  3192 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>")  3194 ms  <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>"  3248 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>")  3249 ms  <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>"  7125 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>")  7126 ms  <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18272 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18273 ms     | AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18273 ms     |    | AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18273 ms     |    | <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18273 ms     | <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18274 ms  <= "<instance: java.lang.Object, $className: com.*****.*****protocol.pb.AdFeedImagePoster>" 18279 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18279 ms     | AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18279 ms     | <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18280 ms  <= "<instance: java.lang.Object, $className: com.*****.*****protocol.pb.AdFeedImagePoster>" 18287 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18287 ms     | AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18287 ms     | <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18288 ms  <= "<instance: java.lang.Object, $className: com.*****.*****protocol.pb.AdFeedImagePoster>" 18319 ms  AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18319 ms     | AdFeedImagePoster$ProtoAdapter_AdFeedImagePoster.decode("<instance: com.squareup.wire.ProtoReader>") 18320 ms     | <= "<instance: com.*****.*****protocol.pb.AdFeedImagePoster>" 18320 ms  <= "<instance: java.lang.Object, $className: com.*****.*****protocol.pb.AdFeedImagePoster>"

frida可以显示出来调用流程,但是我们想要的数据为主页广告,现在请求包是加密的,虽然上面的代码被调用,但是我们无法确定想要的数据就在那个请求包内

三.还原加密流程

但是在apk中的源码中 UnifiedProtocolUtils类里面找到了
方法

encodeUnifiedRequest

decodeUnifiedResponse

经过charles抓包的的数据和这个两个方法的数据来看,是经过这两个方法进行组包后发送到服务器上。

那么如何确定广告在哪呢?
首先让腾讯视频停留在将要进视频详情页单还没进去视频详情页的时候,打开charles进行抓包

截取距离g**广告最近的acc.**.com发送的请求

并将其使用charles保存为二进制文件

小插曲:观察**视频的整个网络请求都在NetWorkTask类下面 package com.t***。***.route

在其请求完成之后调用了

 int[] iArr = new int[1];
#bArr2是acc这个请求返回的二进制数据
bArr3 = UnifiedProtocolUtils.decodeUnifiedResponse(bArr2, iArr);

代码如下

import qqbrower.GzipUtils;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.nio.ByteBuffer;public class main {    private static final int CMD = 65281;    private String bytesToHex(byte[] bytes) {        StringBuilder sb = new StringBuilder();        for (byte b : bytes) {            sb.append(String.format("%02x", b));        }        System.out.println(sb.toString());        return sb.toString();    }    private static byte[] getJceDataFromBuffer(byte[] bArr, boolean z, int i, int[] iArr) {        bArr = GZIP.Decode(bArr);        ByteBuffer wrap = ByteBuffer.wrap(bArr);        int position = wrap.position() + 16;        int length = (bArr.length - position) - 1;        if (length <= 0) {            iArr[0] = -869;            return null;        }        byte[] bArr2 = new byte[length];        System.arraycopy(bArr, position, bArr2, 0, length);        return bArr2;    }    public static byte[] decodeUnifiedResponse(byte[] bArr, int[] iArr) {        boolean z;        if (bArr == null || bArr.length == 0) {            return null;        }        ByteBuffer wrap = ByteBuffer.wrap(bArr);        if (wrap.get() != 19 || wrap.getInt() != bArr.length) {            return null;        }        wrap.getShort();        if ((wrap.getShort() & 65535) != CMD) {            return null;        }        wrap.getShort();        int i = wrap.getShort() & 65535;        if (i != 0) {            iArr[0] = i;            return null;        }        wrap.getLong();        int i2 = wrap.getInt();        if ((i2 & 2) <= 0) {            z = false;        } else if ((i2 & 16) > 0) {            z = true;        } else {            iArr[0] = -867;            return null;        }        if (wrap.getInt() == 5) {            return null;        }        wrap.getLong();        wrap.position(wrap.position() + 32);        wrap.get();        wrap.position(wrap.position() + 10);        wrap.get();        wrap.position(wrap.position() + (wrap.getShort() & 65535));        int i3 = 65535 & wrap.getShort();        wrap.position(wrap.position() + i3);        int i4 = 83 + i3 + 2;        int i5 = wrap.getInt();        int i6 = i4 + 4;        if (wrap.get(bArr.length - 1) != 3) {            iArr[0] = -869;            return null;        }        int length = (bArr.length - i6) - 1;        if (length <= 0) {            iArr[0] = -868;            return null;        }        byte[] bArr2 = new byte[length];        System.arraycopy(bArr, i6, bArr2, 0, length);        return getJceDataFromBuffer(bArr2, z, i5, iArr);    }    public static void main(String[] args) throws IOException {        File file = new File("C:\mycode\javatools\src\main\java\qqlive\acc25196");        FileInputStream inputStream = new FileInputStream(file);        byte[] bytes = new byte[(int) file.length()];        inputStream.read(bytes);        main tsmain = new main();        int[] iArr = new int[1];        main.decodeUnifiedResponse(bytes, iArr);        tsmain.bytesToHex(   main.decodeUnifiedResponse(bytes, iArr));    }}

输出的二进制文件通过肉眼观察不符合jcestruct的格式

这时猜想是不是protobuf

然后验证了下

[1](i):53[2](b):com.t**.adService[3](b):/com.**.adService/getAdDetail[9](b):  [9.1](i):217  [9.3](i):1655792059010  [9.4](i):1655792059227[1(1)](b):     [1(1).1](b):mod_recommend_ad     [1(1).2](b):          [1(1).2.2](i):9          [1(1).2.3](b):                 [1(1).2.3.1](i):5                 [1(1).2.3.2](i):1                 [1(1).2.3.3](b):                          [1(1).2.3.3.1](b):type.googleapis.com/com.****.protocol.pb.AdFeedImagePoster                          [1(1).2.3.3.2](b):                                     [1(1).2.3.3.2.1](b):                                                  [1(1).2.3.3.2.1.1](b):http://pgdt.gtimg.cn/gdt/0/EABeJclAPAAIcAAAQuTBiocBWCa2eKvgt.jpg/0?ck=f28abb5b10650481e1a4d76ba72d1a49                                                  [1(1).2.3.3.2.1.2](b):抢爆了!悄悄上线的300个经典英语短视频,0元抢!趣味学英语                                                  [1(1).2.3.3.2.1.3](b):英孚教育                                                  [1(1).2.3.3.2.1.4](b):                                                                 [1(1).2.3.3.2.1.4.1](i

那么UnifiedProtocolUtils类 不是走的这个地方

但是仔细观察 除了 gzip之外,其组包的方式是相同的

那么我们可以搜索组包的公共代码 发现下方有四处调用

某xun视频通信协议逆向分析

观察四个之后

初步确定 package com.***.**route.v3; QmProtocolTools类

QmProtocolTools类开始追踪 看到底做了什么

经过分析笔者画出来了其通信图

某xun视频通信协议逆向分析

#发送数据数据组包 bArr = QmfProtocolTools.packageQmfRequest(this.netContext, mockPBRequestData);    #protobuf组包    mockPBRequestData =>byte[] pkgProtocolData =pkgProtocolData();        bArr = PBProtocolTools.PbProtocolAsQmfBody.packageRequest(this.netContext);                #组装协议头 需要实现                packagePBFrameHead((short) packageRequestHead.length, pbBusinessReqBytes.length).array();               int length = packageRequestHead.length + 16 + pbBusinessReqBytes.length;                省略--------

因为

预先处理
acc25196req是 请求的二进制文件

将其转化为hex,中所周知gzip经过压缩后,头文件的标志为1f8b,并把二进制最后一个字节单独提出来

1f8b这段就是gzip压缩后的数据 ,我们先分析gzip压缩后的数据是如何产生的 然后再分析第一段1300开头的数据如何构造,其实也就完成了发包的请求

1300000b910001ff01626c00000000000000000035000002130000271c0000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000025d81f8bxxxxxxxxxxxx03

四.代码还原

解析gzip压缩的数据

import gzipif __name__ == '__main__':    hex1 = "1f8b0800000000000000ed5ac96f245719ef9e2da6218963401a5922b29c300af1b8fbed55cfc6686a6b4f8f778f673cf6a5525d9bcbeeee6a5757b597241244424a500e11ca29e280222171e64214258ac491235c728620c20189bf00f155b5b799c910100805a95b5eeabdf7bdf7adeffbfd4af6d750093edffdf4322e159f113ef6921bb7aba9df71fd4e5adddf6f457dbfda4de23476e356b5dbac3ade5d3fe947ae3fce6bffaa682df453cd33fdd4895ae4c7e5910f4646fffaecf50f2e4f965e2ecd54dd0011e1313f903250294332902a57b0a2b8cc0b9a8eea790c218411c10ac7581f7508a79431a1aa2af57dc2ef5c596a4ca8abe5ed09411816bed2f43ddfc5d87755e97ac295a41930b5e936c92ba59d5272ed41e4c4ed688657bea1566955a02ac1928bb1abc5afeb97272bf9713789bc092aaf622c309b790aa3fcc36f95f46f8d5c1e2d8f3f4308ad2aa88a19ae6245bd53f9761ebeefe43fd6af8c94464bdb5747fef2d45869177f994db7b0e05c9158128e54768bd3e40fe5caa765693043612a68c78a59975c1a5c63266754a15a1daba6a406a786610a5d97583724e31499c8acd7eb58e375a611cad5bac5b13414a2720b5155d4996ed67552d775811503234674824d8d33d5e496d4f3182ba6c91037a86e69dc8424803e5ed738d14d13e5a64845ea9c5b0637a46a5253a526cc4ac4292748c7481716434ca95b8602c2dc34558b68521a583328a186260c3a5afa5bb9345e3aae559e5a6b2c590d2ac65ea48a4b039535b14b691008465d4f5287b13ce8388018c061c751e5e9344ba24e68a791bbe7a7630fa024b0a680a99a863553e18223c550b055d7552e4d222df08ad6b98918932a31306396243aa39a4615a2883a46d2c44addd490412d9383f30617c4508f472b23aed36a6d1c75fdb12b3dbf151c5faf5cc97a9137367a962c41a4108c559eaf7c3d4208fca78edfdf197bb627d36696e0fd3d7918527c38f6623bf6ecc4879bd2f63b9eed7873f2463e95267017fc249f98c6e3bf302a1f5dabbc02ae6c0977c5378ecc29ddd8bddb8a0da3be6bacedf53a0de37837e0fd9500d5369bc91a6ef4d5e61d16de5fd3eaa1b6a519b073fe4075e6ddeeb671200ee61bda5690c82cabd1d5db0e5e9b5fd3d6b4b94acb5a11bb3b0c59f30bcda9f4200e5d6357434e045a4c1caad9bcb9111d76b756fabbfbc2cdb5ec67cdfe9d96a66d6a7aa83534fd406cf2d8255b2d86ad48bbdda7b57ead26a95a6badac69cdf9c6413759db776e276168e5dac0aaa91523017fccf9a3a8d3f3f62dd054539689a51defd60f1565b527069a7656a77a8761f7dc9fc0f4bbbd5da3dd131b7a23d46b99c053a236d5d94f56b46d4dcfc4427b6f7b31142bfd485b9b9babbc5b76bcbe9fa451cf4fe60855105c1a7c23ea78592f4d8ee61845e40674272f73d339aaaa8a541157941b4ee4cd81a060aa545474e3fc0cbbe3b47d7bc7e9edf89edd775a993f071583a450289ceb26be9342c3b303284910ee4269a67352100c552b115c2e2a89e4a4f266398fc2c1e2e68616e9e9c2aab12c1b6c7969f9b69a6dc5d6ca1209536f77a1bbe5a4e6bd4864d9fc9a5e37945a2de03ace23a11f996ba16eadd620d2533453e7b5e3b07e646aa161adcc73355d8871b7bdb909b9d98ba37de66d62b190ae45dafcd454164cd1fe83a43f85f43dcdd206f9e879c9eaa0be22fd78c1b9505f91d16d3867993f6a044bed70f93c1fee6614668b4677db713758a88be0414d098e93feb6f220cf47b8b5b8d4bb7357135bf3eb793ec6feb7dafe7ea9f262c0a41320c79b0e5444a699a77ad3900939cd5893369b8c7005d1b16b04ba8aa0e3bfbee474bb36247b6e8002b36d27ead8ad388c3a739db8e3cf2e6e1ad0703a734492d9d86ee78504a5d2b967ed04e4bebbb8615877378c3bc7d9ca6abcbab91df5b73363a9b107dbee2f16fb24c230b8533c334ce059bf5b0c54acce2ede6f2c17034a25acacea83812a665b7dbbeda47e12392d3b4ce2ac3b373b380f1a6d6ed3f6c02a2ed5597020cb8bdd4475a1222a04158a25b10962b71707ba18cd8d58ac1703456530581818c1113c9b830508170cee0e6c154899dd3fb6432f9ddbf329758ef643c77102de0a591cc7ceec4489946646738cbbfec377defde5a5891fbdf1ce9b97c67f7fb972cd8bba5d3f192bf078fcb2a8921ce0c97388cc20f4d0d733dfcf3a7b9df8a033d183b6fa03fd0493ef3ca7b1198e66989831614f7d86c9f5c7e07ebb8c9aa5dd5272952142c9f144402815c8038c00d4c034f002a950ea3b8c10ce3d82de289f9cfe937261d84fcb0572a84202b2095a670aa0a962321d00981a16e6ba2298a48253806e43811543a1b8ce54a56e48ac48039010ee37a0a3958336ab5b8a29095320f4ef95092c1a4862ca754b5a8c63bd0e0dc33204174803b580df02613812e056981ab38478bf3c81b0ae49a221956266524d3053609320ceeb5221d8621f964bbf29977e5b9ef069c0c12e0768870afe3619f2034f003d0ab0871ce6ffae5cd13a5e1247de0446ef5fba653aad7eb45723555c45132f2d469dec7076e2deecc4b9d0ec441e13f871af51bb8f4915c16540d5354b33961f2c7defe5b745e58fbc72cdcda0c385639ff25727bba1dd4bbb933318dfcc9fddc89b9c997c04f5266f4e267e60fb2d7f72e65578ccd1d4765a21487286312c07adf8c00e92b80d5314c64ebe6c479edd8a7ae9b9182065d6f201f1d3fca8c93fbffdb3cf3efef9671fbdf7f9271fc36a0f88272c024cc35a2ede728ee22cbd30d14b5c7bcf3fca474025242e34fdf343cfd60bc7e066c0c662fa316d5927171dc825000418294d817d5fe226c38c379b943499ab785c0d80d170d8e1e7e1b2bb60a65f1c3ef0104e383c39d2b71dd7f57b3ddb8d7b2958d82e742968b0f44511f2737201df4e2fee3c9e8817f29dadd8f14eed46275b12a7b3f79012921b13a57efbc41a34f0d9dfef64798ebe8cc5dae72cb6ca5441b8b40bf31cb00cf478851f700730c6059586a53071ba3b763772cf33f1e1fb9fbff52b48c39fdefa044b26f304fa6e1ac59d0b218a7a76d689822370e22c68e751b531824e9d8727dfdcf5ddbc8de64df2c4a5530fa1c7e6078ab30c0c727896ee27d5c0e3f5e49fd5d320c267d230e324f0e253505627ecc19ab723ed4e9cdafda87bd3dba1f0addc3c19171b809e04c00a1fce3e7ad445e022855d6290cb4733c94e9d7a42813fe9c6fac57c174e826841f0d2a396ff50d5f81dc0c6478c13ac48d27f5825cd56ecee5dd0755e1a59d282b99d34edced46add2c8baafb305d753bb5be1b0378db3bc7b95c0dd51e71087ab42214c404bc5b8a9ac251d1937280b38b1a18184cc4798d5db8d9fe40e66486e45b4f9ef3e01539ffa220be5034b6acb773727a11b6c3eea08a340308c3dd698c38c22f18daba39dd5836ad07d32a705181e4c5296365d1bc28b8ba6ead6bcb0b0f4fadd41b8bd6c5a9424465f9bb8818ccdcb5162d636365fda2d4c6d2c9c85a9e6f2c9f1e30d03b787e58dbc38a4e5ed9a68ddb96712a7141787de5de8635bd7eef4cfecc029502bb16fc7ce2828fa7265d8081f3fe96f8fb45b1f552a7dd2d2aeeb48260b1eb244ebb67379db0b8bea72f59adb813be96278cbcd6747a5045c5440139f9d379829f7013c08a27b72d48289033d0939e748713cf06be9c66f3240f1720ec91ee3028f182e00dce29f40eabe5dfa99602fb726a71b12571e5b4cdf7dcb8c0085445c096a99c7c7d404bba61ce4a1e45c5335e83f2e7412f744278018ce12dd0dd713a1dbf0562c769b194b77f34a01ca0da6db97b43b633643b43b633643b43b633c4af21db19b29daf02dbc95b68333e3c87439873a1f10f19d090010d19d090010d19d090010d19d09001fd9f54cb7f89015de4365ef13f4993af575eac3c0da8011dc6745267c13f1afbe660c92ec48ae63887274a2f7f75fe9c4fc62ba38ffe73c9d8b591e7474bd7cbff001a0533a4d8250000"    deData = gzip.decompress(bytes.fromhex(hex1))    hexStr3 = deData.hex()    print(hexStr3)

某xun视频通信协议逆向分析

09300000000025d80331000000000000前16个字节000025d8:第一个protobuf的字节长度+ 16 +第二个字节的protobuf长度0331:第一个字节的protobuf的数据长度08351228636f6d2e74656e63656e742e71716c6976652e70726f746f636f6c2e70622e6164536572766963651a352f636f6d2e74656e63656e742e71716c6976652e70726f746f636f6c2e70622e6164536572766963652f676574416444657461696c32850108b80810ed0f18b80322002a003a2e636630323664346566393966383334303966393835373137376334646662613864643430303031303231373531314210613235333334343638383833656532354a044d49203850015a203632343136653762656465

组装的代码如下所示:

rom appReverse.tencent.txlive.bytebuffer import ByteBufferimport  gzipclass Pbpa:    def __init__(self):        pass    #拼接gzip压缩前的头    def packagePBFrameHead(self, packageRequestHead_len,pbBusinessReqBytes_len):        allocate = ByteBuffer.allocate(16)        allocate.put_UBInt16(0x0930)        allocate.put_UBInt8(0)        allocate.put_UBInt8(0)        allocate.put_UBInt32(packageRequestHead_len +16 +pbBusinessReqBytes_len)        allocate.put_UBInt16(packageRequestHead_len)        allocate.put_UBInt16(0)        allocate.put_UBInt32(0)        logger.info((allocate._array).hex())        return allocate._array    def packageRequest(self):        #protobuf组包的第一个包        packageRequestHead = "123".encode()        #protobuf组包的第二个包        pbBusinessReqBytes  = "456".encode()        allocate = ByteBuffer.allocate(len(packageRequestHead) + 16 +len(pbBusinessReqBytes))        headerdata = self.packagePBFrameHead(len(packageRequestHead) ,len(pbBusinessReqBytes))        allocate.put(headerdata)        allocate.put_bytes(packageRequestHead)        allocate.put_bytes(pbBusinessReqBytes)        logger.info((allocate._array).hex())        #gzip压缩        deData = gzip.compress(allocate._array)        logger.info(deData.hex())        return

组装request 请求的二进制的头

上面得到的数据就是 中间的数据 ;
完整的请求数据应该是

头数据 + gzip压缩后的数据 + 0x03

头数据的组装涉及到

import gzipfrom loguru import loggerfrom appReverse.tencent.txlive.bytebuffer import ByteBufferimport hexdumpclass QmfProtocolTools:    def __init__(self):        pass    @staticmethod    def packageQmfRequest(gzipdata=b"helloword"):        CMD = 65281        QMF_PB_CMD = 0x626c        allocate = ByteBuffer.allocate(9999)        allocate.put_UBInt8(19)        allocate.put_UBInt32(0)        allocate.put_UBInt16(1)        CMD = 65281        allocate.put_UBInt16(CMD)        allocate.put_UBInt16(QMF_PB_CMD)        allocate.put_UBInt16(0)        getRequestId = 0x35        allocate.put_UBInt64(getRequestId)        allocate.put_UBInt32(531)        QmfAppId = 0x271c        allocate.put_UBInt32(QmfAppId)        LoginQQUin =0x0        allocate.put_UBInt64(LoginQQUin)        allocate.put_UBInt64(0x0)        allocate.put_UBInt64(0x0)        allocate.put_UBInt64(0x0)        allocate.put_UBInt64(0x0)        allocate.put_UBInt16(0x0100)        allocate.put_UBInt64(0x0)        allocate.put_UBInt32(0x0)        allocate.put_UBInt16(0x0)        #这个位置压入四字节的长度        allocate.put_UBInt32(len(gzipdata))        enData = gzip.compress(gzipdata)        allocate.put_bytes(enData)        #压入结尾        allocate.put_UBInt8(3)        hexdump.hexdump(bytes.fromhex((allocate._array).hex()[:allocate._position *2]))        logger.info((allocate._array).hex()[:allocate._position *2])if __name__ == '__main__':    QmfProtocolTools.packageQmfRequest()

解析gzip压缩后的protobuf:

第一个protobuf:
package com.tencent.qqlive.protocol.vb.pb; =>RequestHead

通过还原的第一部分的protobuf的可以确认第一个为这个

那么我们将其还原

第二个protobuf

根据第一个protobuf

可以判断出来走的是这个接口,那么我们直接去寻找

某xun视频通信协议逆向分析

剩下的都是苦力活了 自己拼装probuf结构即可,真是个苦力活。。

然后组装完了发包,搞定

某xun视频通信协议逆向分析

总结:

加大通信逻辑的复杂度也会增长分析的时间,如果再加上一些vmp就真的没得看了。

我是BestToYou,分享工作或日常学习中关于二进制逆向和分析的一些思路和一些自己闲暇时刻调试的一些程序,文中若有错误的地方,恳请大家联系我批评指正。

某xun视频通信协议逆向分析

原文始发于微信公众号(二进制科学):某xun视频通信协议逆向分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月6日22:57:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   某xun视频通信协议逆向分析https://cn-sec.com/archives/1886603.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息