本文章中所有内容仅供学习交流使用,不用于其他任何目的.
了解过的朋友应该都知道直播大多采用wss协议来传输protobuf数据来实现弹幕功能,于是便有了使用python来发送wss获取protobuf数据并解析的想法。说的比较简单,实现过程中遇到很多问题,我把遇到的问题及解决过程记录在下面,方便朋友们遇到问题时可以得到些许帮助。
使用的第三方库 websocket-client
def on_open(self, ws):
def run(*args):
# popen = pb.Wsspopen()
# popen.hb = 'hb'
# proto_data = popen.SerializeToString()
# ws.send(proto_data)
_thread.start_new_thread(run, ())
这个接口不出意外涉及两个大名鼎鼎的X-Bogus及_signuture参数,聪明的小伙伴们有各自的办法解决这两个参数,我rpc不想用,扣代码补环境也有一个绕不过去的坎(在js发送xhr请求时导出这两个参数,js功底不够强),所以我用的是纯算法还原的办法。过程网上都有,插桩打断点,根据日志分析加密过程,这个过程也是考验耐心和经验。X-Bogus的破解网上已有很详细的文章,我这里简单记录一下_signature的分析过程
_signature 一共分为五部分
第一部分为定值:_02B4Z6wo00001
第二部分为31位字符串,分为六组:iAKJP wAAID CoAjev pRKwV 4gCiB AAOt1
第三部分位4位随机字符串
第四部分为localstorage中tt_scid的值,若没有则使用cookie生成
第五部分为前四部分的加密值
其中第三四部分可省略
那看来最重要的就是第二部分,具体生成逻辑(主要是移位,异或等运算)还是要自己通过日志分析,提示一下涉及的关键点
big_num:固定字符串10000000110000+当前时间戳的相关操作
每组都有一个公共码(通过日志分析),参与字符的生成
第四组的生成:涉及 请求参数及user-agent参与运算,再生成公共码
部分代码
big_num_num = _0x28420a(0, big_num.toString());
console.log(big_num_num);
ua_num = _0x28420a(big_num_num, ua);
param_num = _0x28420a(big_num_num, sorted_param_str);
for_5 = ((ua_num % 65521) << 16) ^ (param_num % 65521);
这里其实没有大坑,看js代码找数据反序列化的地方,部分还原proto文件即可。需要注意的是响应的protobuf不能直接通过命令protoc --decode_raw < person_protobuf_data
反编译,看js代码发现是调用了函数解密响应数据,把代码扣出来调用即可
遇到的问题很多,以上列出的是困扰我时间比较长的问题,希望看到的朋友可以少走弯路,写的也不是很详细,有疑问可以给我留言。