开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2927|回复: 22
收起左侧

[技术专题] pdd 直播弹幕解析逆向记录

[复制链接]
结帖率:97% (29/30)
发表于 2024-3-17 22:22:19 | 显示全部楼层 |阅读模式   北京市北京市
前几天有位老哥找我说要做pdd弹幕获取,他说pdd弹幕有加密,我就看了一下,发现并没有加密,相对来说,挺简单的,在这里发出分析记录


首先介绍一下现代直播间弹幕的实现原理

通信方面,普遍是websocket,也有http轮询的,但是由于效率低开销大所以非常少

数据方面

普遍是protobuf

其次是数据头+(protobuf/jcestream)+数据AES加密/数据gzip压缩/数据lz4压缩

然后便是 自定义结构包装json(如bilibili)

最冷门的就是极为抽象但是又节省流量又方便解析的自定义文本结构(如斗yu)


所以,我们对直播间网页分析的时候,先看看是不是http轮询,不是那就监听ws数据,然后把hex转文本,如果可以看到明文部分,那恭喜,没有加密

如果不能看到明文部分,那么检查是否存在gzip压缩头/lz4压缩头,存在那就是压缩了,不存在那就是加密了...

总之,原理就那些,分析的时候带着原理去分析,就能一点点解开


接下来就讲讲pdd实战,首先通过浏览器打开pdd直播间分享链接,查看网络请求,发现很明显不是http轮询,那就要考虑是websocket了,打开性能窗口并录制

1.jpg

2.jpg

找函数调用,一个一个排查,首先看这里有对函数i的调用,i内调用了f,我们点进f看看f的代码


3.jpg

这里有一个decode的调用,并且输出了格式化数据l,很明显,这里存在对ws数据的解析处理,我们在decode下一个断点,看看数据


4.jpg
可以看到输入了ws的buffer数据,在内存检查器内可以看到具体数据
结合下面的返回数据格式,显然,收到ws数据后,执行了:

[JavaScript] 纯文本查看 复制代码
 let magic = bytes.readInt16BE(0);
            let cmd = bytes.readInt16BE(2);
            let ctx = bytes.readInt32BE(4);
            let reserve = bytes.readInt32BE(8);
            let bodyLen = bytes.readInt32BE(12);
            let data = bytes.subarray(16, 16 + bodyLen);

data 就是 decode函数处理之前的payload

现在我们跳到decode函数,看看它的实现,如图:

5.jpg
6.jpg
粗略一看就可以发现,skipType很显眼,再观察一下收到的数据,这显然是一个protobuf数据的解析过程,我们下几个断点,看看执行过程


7.png
发现t定义了一个protobuf节点表,而这个函数循环解析,取出数据内的所有节点(字段)

根据这个节点表,我们可以手搓下表层的proto


ss.jpg
好了,这样表层就分析结束了,使用此.proto对data进行解析,就实现了第一个decode函数
我们继续往下执行,发现下面有一个解压缩的判断:


7.jpg
当compress属性==1时,对第一个函数的返回结果l的body属性解gzip

但到这里我们还没拿到弹幕数据,因为body也是个proto


8.jpg
那么网页必然在其他地方对payload.body进行了解析,所以我们搜索:payload.body


9.jpg
找到它后,果然发现了另一个decode函数,而且也是返回格式化数据,那必然也是个proto解析函数了
下个断点跟进函数


10.jpg
果然,和第一个decode函数大差不差,那么下个断点,看看t,应该也是个proto节点列表


11.png
果然,那么再次根据列表搓proto


13.jpg
实现body的定义
继续往下执行


12.jpg
可以看到,经过第二个函数的反序列化后,string类型的payload已经是我们需要的弹幕数据了
说是弹幕数据,实际上,这是个json,包括了弹幕等其他事件


那么pdd的ws数据结构就完全透明了,nodejs代码实现如下:
[JavaScript] 纯文本查看 复制代码
    async decodemessage_pdd(bytes) { //逆向 react_live_room_xxx.js s.decode = function(e, r)
        if (bytes.length <= 16) return;
        try {
            let magic = bytes.readInt16BE(0);
            let cmd = bytes.readInt16BE(2);
            let ctx = bytes.readInt32BE(4);
            let reserve = bytes.readInt32BE(8);
            let bodyLen = bytes.readInt32BE(12);
            let data = bytes.subarray(16, 16 + bodyLen);
            let result = pddCommand.decode(data);
            data = null;
            if (!result.body) return;
            if (result.compress === 1) {
                if (result.body && result.body.length > 0) result.body = await new Promise((resolve) => {
                    zlib.gunzip(result.body, (err, rr) => { if (err) { resolve(false); } else { resolve(rr); } });
                });
                if (result.extension && result.extension.length > 0) result.extension = await new Promise((resolve) => {
                    zlib.gunzip(result.extension, (err, rr) => { if (err) { resolve(false); } else { resolve(rr); } });
                }); 
            }
            if (!result.body || !result.body.length) return;
            result = pddBody.decode(result.body);
            if (result.payload) {
                result = JSON.parse(result.payload); //原始数据
            }
            result = null;
        } catch (err) { }

        return false;
    }

这是不能直接运行的,得自己写proto文件,利用protobufjs引入proto,再调用decode


proto文件,你们可以照着我的抄,或者回复拿我写好的现成的.proto
需要注意的是,我这个proto仅支持直播间的事件,实际上pdd网页还有一些其他东西也是ws,所以要加try


本主题是记录下分析过程,不建议真的拿来使用,因为pdd直播间网页是有风控的,比如登录频繁你就看不见直播间了,以及其他的乱七八糟的风控

其他的直播平台其实原理都大差不差,包括Tao宝、zfb、京东等,都是同一个思路
syntax = "proto3";

message Command {
        string command = 1;
        uint32 protocol = 2;
        uint32 errorCode = 3;
        uint32 bizCode = 4;
        string bizErrorMsg = 5;
        uint32 compress = 6;
        bytes extension = 9;
        bytes body = 10;
        uint64 downstreamSeq = 11;
        uint64 conId = 12;
        uint64 ctxId = 13;
}

message Body {
        uint32 bizType = 1;
        string groupId = 2;
        string msgId = 3;
        string payload = 4;
        bool needAck = 5;
}


func.jpg
14.jpg

评分

参与人数 1精币 +2 收起 理由
冷寒冰 + 2 YYDS~!

查看全部评分


本帖被以下淘专辑推荐:

  • · 好帖|主题: 1219, 订阅: 41
结帖率:83% (10/12)

签到天数: 25 天

发表于 2024-4-17 19:37:42 | 显示全部楼层   北京市北京市
谢谢分享
回复 支持 反对

使用道具 举报

签到天数: 24 天

发表于 2024-4-15 15:57:57 | 显示全部楼层   广东省东莞市
谢谢分享
回复 支持 反对

使用道具 举报

结帖率:33% (1/3)

签到天数: 6 天

发表于 2024-4-14 06:19:52 | 显示全部楼层   黑龙江省哈尔滨市
回复 支持 反对

使用道具 举报

结帖率:98% (334/340)

签到天数: 7 天

发表于 2024-4-12 09:24:33 | 显示全部楼层   重庆市重庆市
6666666666666666
回复 支持 反对

使用道具 举报

结帖率:0% (0/5)

签到天数: 7 天

发表于 2024-4-10 03:42:55 高大上手机用户 | 显示全部楼层   广西壮族自治区贵港市
有联系方式吗?
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 22 天

发表于 2024-4-7 12:30:03 | 显示全部楼层   福建省泉州市
这个教程让我受益良多,期待更多好作品!
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 22 天

发表于 2024-4-7 04:30:03 | 显示全部楼层   福建省泉州市
很喜欢这种一步一步指导的方式,容易理解。
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 22 天

发表于 2024-4-6 18:59:32 | 显示全部楼层   福建省泉州市
期待更多类似的好教程,支持你!
回复 支持 反对

使用道具 举报

签到天数: 4 天

发表于 2024-3-26 12:57:50 | 显示全部楼层   湖南省常德市
大佬 v多少想整一套多少钱
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表