web逆向-B站弹幕protobuf协议的逆向分析
目标是B站弹幕的数据还原,随便打开一个视频,直接三连

能看到真实文本,但也有一些乱码,看一下 content-type
1 | content-type: application/octet-stream |
参考这篇可知,这是一个字节流文件,但浏览器也不知道如何处理
算了,直接google 就可知,这是一个使用了protobuf协议编码 的文件,使用这种协议的好处就是数据量小,传输快,坏处也显而易见,就是使用麻烦!!!
配置
这里统一选的版本是:3.20.0
先下载两个压缩包:https://github.com/protocolbuffers/protobuf/releases/tag/v3.20.0
再安装相关库:pip install protobuf==3.20.0
最后把 protoc.exe 配置到环境变量
protobuf 初体验
然后可以写一个小demo玩一玩,首先是自定义 .proto文件
1 | syntax = "proto3"; |
然后编译生成python代码,目录下就多了一个 person_pb2.py
1 | protoc --python_out=./ person.proto |
然后就可以导入模块, import 的时候可能会报错:
ImportError: cannot import name 'builder' from 'google.protobuf.internal'
这时候需要升级:pip3 install --upgrade protobuf
1 | In [4]: from person_pb2 import Person |
so文件逆向
有了上面的经验,要来逆向就比较容易上手了,首先下载弹幕的二进制文件:
https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=555856394&pid=809421068&segment_index=2
然后运行命令:protoc --decode_raw < seg.so,先看一下大体内容是怎么样的:

再打断点调试看看:


直接搜索还原后的key值,midHash

格式化一下,答案呼之欲出:

这下可以开始编写 .proto文件了,把整个字典扣下来,用代码生成:

1 | for k, v in d.items(): |
bili.proto 文件如下:
1 | syntax = "proto3"; |
再走一遍上面的流程:
生成 pb2.py 文件
protoc --python_out=./ bili.proto导入模块
from bili_pb2 import BiliDanmu解析字节流
1
2
3In [2]: bili_decoder = BiliDanmu()
In [3]: pb_bytes = open("seg.so", "rb").read()
In [4]: bili_decoder.ParseFromString(pb_bytes)转换成字典
1
2
3from google.protobuf.json_format import MessageToDict
MessageToDict(bili_decoder, preserving_proto_field_name=True)