android 弹幕sdk,[原创]Protobuf协议解析文档-某音弹幕

0x00 : 前言

近期因为工作原因着手分析某音协议,在做到直播间这步的时候通过抓包发现其直播间内弹幕数据为protobuf协议,之前用xposed做wx的时候虽然接触过,但在下从来都是只要结果的人,直接调用wx内部函数转成对象即可,谁理你什么格式,但现在做的既然是协议,那自然是无端可用,什么东西都要自己处理,这里分享一下记录的分析流程.

0x01 : 准备工作

在开始分析之前需要准备好:

1.protobuf(安装方法百度即可);

2.直播间弹幕抓包;

3.通过protoc工具测试:将数据包里返回的弹幕内容复制到文本,通过指令

protoc --decode_raw < xxx.bin 查看解析后的效果:

5e11a711d4df6ffe4a95d8874c6d2183.png

可以被工具正常解析,到这里准备工作就完成了, 接下来本文档以图中数据为例,进入分析流程;

0x02 : 分析流程

上面通过protoc解析出了个大概,那么里面的数据究竟是什么意思呢? 1 2 3, 1: 2:这些都是什么呢? 网上所搜一番得知:解析出来的数据中开头的1 2 3..或 1: 2: 3:的均为protobuf的tag, 是解析数据的关键值,带":"号的是字段,没":"号的是 repeated 集合.

那么知道了这些,要怎么还原数据呢,逆向中是没有原始.proto文件的,对于protobuf的解析就需要依靠分析源码,自己生成一份.proto文件,以上图为例,在源码中定位到解析代码:

其中参数(b bVar)权当作http请求后的body即可,无关紧要,重点是com.bytedance.android.livesdkapi.message.f 这个类,进去看一下类里的结构:

对比一下解析出来的数据图,发现对应tag:2,3,4,5

e77731e85e12852f97e9c14f8e51aef9.png

tag1是个数组,类型是内部类a, 内部类中剩下的2个字段是用于动态定位接下来解析的类:

method => 解析剩下数据包中的类名, payload => 数据内容,method 也就是这部分:

25e6cc54698b3d5df597450cdd60d792.png

分析到此数据结构有了大致了解,com.bytedance.android.livesdkapi.message.f是某音弹幕数据的最外层,用来保存直播间弹幕所有的消息类型,从格式上不难理解,会有多种method,这里先以"WebcastRoomMessage"为例查找对应关系:

在代码里搜索一下很快找到了 com.bytedance.android.livesdkapi.depend.g.a:

7d3b20d8eb2f4cc8bb61b41c3ac4afc7.png

找到对这个枚举的引用,定位到 com.bytedance.android.livesdk.chatroom.bl.a:

9faebb235e29e2e88961a863ae2bbe12.png

对应关系找到,说明剩下byte[]是在 cl.class这个类中解析,看一下里面的结构:

"WebcastRoomMessage"中只有2个字段,"content"和"supprot_landscape",可是根据工具解析出来的数据可以看到,还有一大坨呢,剩下的数据在哪,并且这2个的tag排列关系又是什么? 那只能继续查找cl这个类是怎么解析的,经过一番查找,找到了解析对应关系,com.bytedance.android.live.base.model.proto.d ,在这里可以看到负责解析cl.class的类是 gw.class:

6fc40a70371f997b243e2898923fd301.png

进入gw.class:

7ea97f6cea05cda139a212f19a627ea0.png

在这里知道了"content"和"supprot_landscape"分别对应tag 2和3,还有第三个名为"baseMessage"的字段要解析,这个是cl.class的基类成员,通过多个数据包验证得知,所有method中,都继承同一个基类:

eb732fc2e33689da3d1ffcac77469f82.png

之前没解析出来的数据也在其中,看下这个名为baseMessage成员的内部结构,并找一下"tag表":

6a96db0117983a0745a1e947db1acec5.png

分析到此,弹幕结构渐渐清晰了, 如下图:

bb916ead6dd24e28be7aea08a5795c09.png

现在可以根据分析结果开始写proto文件了.

0x03 : proto文件编写

关于proto文件语法网上资料很多,这里先说几个关键的,proto语法有"proto2"和"proto3",我没看出来对于咱们逆向人员选择"proto3"有什么用处,并且3的语法是不需要字段修饰符的,这只会让我们在写proto文件的时候更加迷糊,所以我们选择"proto2"来写.

或许你已经发现,基类(baseMessage)有很多字段,怎么解析出来的就"method","msg_id","room_id","create_time"这么几个,其实这也是很正常的情况,并不是每一个字段都是必选的.proto有3个字段修饰符required(必选),optional(可选),repeated(重复),说白了就是咱们的proto文件不使用required,只用optional,因为咱们也不知道哪个字段什么时候才有值,如果是数组一律用repeated修饰.

注意proto的数据类型,以java为例.String => string ; int => int32; long => uint64;...更多类型可自行查找资料.

开始吧,先写一份 ProtoApiResult.proto,对应上面的

com.bytedance.android.livesdkapi.message.f ,用来保存弹幕整体数据:

692c4a5b5f83c7f4e6cc9bd81d0f1b8f.png

外层有了,现在写"WebcastRoomMessage"对应的类:

6508b1a0ac55c1a522313170fd46afb6.png

接下来最后一个"CommonMessageData":

798ad81ef5c9e2563e8f06844a378a3b.png

注意这里的display_text字段,这还是一个对象,里面又是N多字段,这里我已经解析过了, 大家自己在分析过程中如果不想解析那么多,可以删除不需要的字段,或者将类型定义为bytes即可.只要tag不乱就行.

OK,将.proto打包成java文件: protoc --java_out=out .*.proto

之后在out目录就生成了可以使用的java文件, 导入到项目中即可,最后看下解码效果:

e666f71a97cb9b1fef392dc7414d4d23.png

嗯,费了一大堆事最后只解码一个系统提示...,这也没办法,某音一次请求动辄数万字节的返回数据,用那些做例子的话,我这图都没法截,迫不得已找了个最小的,根据上述流程其实其他类型的数据解析都是一样的,没什么区别,最后上个最终演示效果:

652a131d15e6a8a6a99418ed35159031.png

0c660c64bfea4971ef69547c8c4de7ef.png

首次发帖,多多关照.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值