bilibili web端sign分析

环境:未登录
经过初步简单分析,在访问下面这个JS后,才生成的含有sign的链接:

https://static.hdslb.com/player/js/bilibiliPlayer.min.js?v=6b8deee3
https://bangumi.bilibili.com/player/web_api/v2/playurl?cid=34108497&appkey=84956560bc028eb7&otype=json&type=&quality=80&module=bangumi&season_type=4&qn=80&sign=873ad4e420b51ce157f31733353ba397

多次尝试发现,这个链接的sign是一个固定值,只有改变qn(清晰度)的时候,sign才发生改变
比如

https://bangumi.bilibili.com/player/web_api/v2/playurl?cid=34108497&appkey=84956560bc028eb7&otype=json&type=&quality=64&module=bangumi&season_type=4&qn=64&sign=52a7209153346b02983bc98a74d39ace

在其他浏览器下操作也是如此

https://bangumi.bilibili.com/player/web_api/v2/playurl?cid=34108497&appkey=84956560bc028eb7&otype=json&type=&quality=80&module=bangumi&season_type=4&qn=80&sign=873ad4e420b51ce157f31733353ba397

进一步分析
对JS格式化之后,搜索web_api/v2/ 很快可以定位到


image.png

继续顺藤摸瓜
再返回的json数据中开头是 accept_format
搜索得到


image.png

可以判断,这里是对接收到的数据解析,对视频地址进行播放
那么在这里添加一句,重定向JS
image.png

确实是对数据解析


image.png

把这个函数收起来,刚好可以发现这和最开始搜索的链接挨着的,同时发现调用了解析数据的函数,那么接口请求的链接也应该在这里
image.png

image.png

通过console可以看到
b就是接口链接
f.Hc值为true
f.reject是一个函数
this.url没有值
重新更改js,在这三个地方比较b的不同之处
image.png

image.png

可以看到后面两个地方b的值并没有改变,而在通过函数 b = c.a.B(b);后b直接成为了完整的接口链接 (实际上在执行这个函数前b的值为定值6330776) 输出函数c.a.B
image.png

该函数如下

function m(b, c) {
    if (0 === c || !b) return "";
    for (var d = 0, e, f = 0;;) {
        e = T[b + f >> 0];
        d |= e;
        if (0 == e && !c) break;
        f++;
        if (c && f == c) break
    }
    c || (c = f);
    e = "";
    if (128 > d) {
        for (; 0 < c;) {
            d = String.fromCharCode.apply(String, T.subarray(b, b + Math.min(c, 1024)));
            e = e ? e + d : d;
            b += 1024;
            c -= 1024;
        }
        return e
    }
    return v.IC(b)
}

同样的,多次console.log后,有以下结果:
无论何种清晰度都会执行下面这个函数来得到请求接口的完整链接
c.a.$B(b)
且b总是6330776
在被调用函数中

        for (; 0 < c;) {
            d = String.fromCharCode.apply(String, T.subarray(b, b + Math.min(c, 1024)));
            e = e ? e + d : d;
            b += 1024;
            c -= 1024;
        }

此循环只循环了一次,d的初始值是127;c的初始值是定值192;
第一次循环,自减1024位-832,循环结束。
e为完整链接,d在一次循环结束,即

d = String.fromCharCode.apply(String, T.subarray(b, b + Math.min(c, 1024)));

这一句执行了一次之后就是完整链接了
对于循环:

    for (var d = 0, e, f = 0;;) {
        e = T[b + f >> 0];
        d |= e;
        if (0 == e && !c) break;
        f++;
        if (c && f == c) break
    }

添加console.log(b);console.log(f);
有如下结果:


image.png

image.png

image.png

即,b的值没有变化,f的值从1增加到192
对于console.log(e)结果如下(紧跟for循环中括号后)


image.png

image.png

实际上关键就是e,这一些数字是ASCII码,将其对应转换为字母数字,就是完整的视频接口请求链接


image.png

绕了半天,这里才是sign的算法入口,但是我也就止步于此了,完全没有明白这个函数是什么操作...
比如在
console.log(e)
for (var d = 0, e, f = 0;;) {

使用console.log(e),e是undefined

console.log(e)
e = T[b + f >> 0];

但这样在循环内使用使用console.log(e)
e又是有值的,为104
更神奇的是就算按下面这样

e = T[b + f >> 0];
console.log(e)

e首次的值也是104(没学JS,有理解错误请指正)
那这个T呢,又是什么
通过alert显示是这个,数据太多,无法显示完整,就是用console也没法完整输出

101,109,115,99,0,0,0,0,136,1,0,0,153,1,0,0,170,1,0,0,187,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,108,96,97,101,97,62,61,60,98,100,51,63,102,57,100,61,0,12,85,86,87,15,85,80,86,87,92,84,6,1,84,84,82,0,121,116,38,122,112,40,116,120,114,122,114,121,45,35,32,38,0,5,6,13,89,2,80,81,11,86,...,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

看起来是一组数字序列
根据
e = T[b + f >> 0];
来看,b是定值,f每次加1,如果说T是固定的,那么无论如何返回的链接应该是一样的,但没有,所以是每一次请求T就会有变化,但是这是如何进行的,不知从何下手。。
用了一个循环

for (var prop in T) {console.log("T." + prop + " = " + T[prop]);}

然后一直输出到1.3W,网页卡了,后面基本全是0
换了个姿势


image.png

切换清晰度,发现是一样的


image.png

但增加循环次数。发现似乎...T很长,没有规律
设定为12000次
这是最末尾的输出
image.png

根据对代码的统计,应该有10240个数
+1就是1024*10个数,JS前面有T.set([])
这种的东西,[]内有10240个数,应该和这个是对应的,但是没有发现什么关联...



完整的T序列
2018-7-10 新进展
W是一个长为16777216的数组(2^24,应该是一个没有上限的数组),通过取W的6330680到6330872位,即共192位的值,即ASCII码,再转换为字符即是接口链接。
现在的问题是W是在怎么产生的

v.RC = W = new Uint8Array(I);

这里W初始化(?)的长度为16777216,全0

在25861行左右有m([136, 1, 0, 0, 153, 1, 0, 0, 170, 1, 0这样的序列


image.png

调用的是25191行左右function m(c, d, f, g) {这个函数


image.png

注意这一句
if ("i8" === h) return c.subarray || c.slice ? W.set(c, l) : W.set(new Uint8Array(c), l), l;

那么此处是会改变W的值的,另有一处


image.png

这里验证了,应该是没起作用
需要考察的是下面这几个地方


!!!

5处是前面说的初始值
3处验证过,在sign有了之后才执行的,也可以不管
2处就是取W从6330680到6330872的值,随后按ASCII对应字符转换就是接口链接
4处的两个从表面看是不会对W有影响(修改之类),除非这个函数嵌套了1处的函数。
下面图是1处所在函数的情况


image.png

关注这几个地方
image.png

第一个地方,G.n是定值8
image.png

第二个地方,也是固定的东西


image.png

第三个地方
image.png

这个地方貌似也没执行,第四个地方也是。
最后一个明显是会执行函数m,但是是"i32",那么不会对W产生影响。
现在关心第一个。
。。
不过突然发现有漏了的,26112也是执行了m的
image.png

是固定的
测试发现这两个地方都只执行了一次,那就是固定值。
那现在分析这个地方
image.png

Fa.push只是也执行了一次
4次W.set中 ma均为1052144,同时测试了这四个地方的W在中间范围都是0

到现在好像还是没找到哪里真正改了W的值
把全部大写W的地方都大概看了下,,没发现什么东西。。好奇怪啊
这个函数l似乎也没有地方调用


image.png

难道是其他JS脚本调用?

其他发现,这个地方里面列表供256个数字


image.png

这个地方供2958个数字


image.png

有趣的是:
image.png

另外video.min.js也是有很多一样的部分的


image.png

也许是这个js?
先折腾到这里吧~~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,059评论 0 13
  • 前言 最先接触编程的知识是在大学里面,大学里面学了一些基础的知识,c语言,java语言,单片机的汇编语言等;大学毕...
    oceanfive阅读 2,988评论 0 7
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,517评论 0 38
  • 五月天又到了。 五月的天刚诞生的夏天 五月的天梦开始鲜艳 我是五月的孩子。 有过我最爱的五月,最快乐的五月,最幸运...
    cheerhoo阅读 294评论 0 0
  • 不论是春天或冬天;不论是晴天或雨天;不论顺境或逆境,不去在乎!不在乎!不论外面环境如何改变!都不去在乎。拾起起初的...
    上官以琳阅读 393评论 0 1