QQMusicApi icon indicating copy to clipboard operation
QQMusicApi copied to clipboard

无法获取到歌曲的下载地址

Open callng opened this issue 3 years ago • 11 comments

使用接口 /user/setCookie 设置Cookie {"result":100,"data":"操作成功"},调用接口/song/url 无法获取到歌曲下载地址

/song/url?id=001FFZvO26HzcR&type=flac

{ "result": 400, "errMsg": "获取播放链接出错" }

测试其他mid也无法获取到(001FFZvO26HzcR)

callng avatar Feb 27 '21 22:02 callng

经过研究发现QQ音乐现在的api参数新增了一个sign 具体分析方法:https://blog.csdn.net/qq_23594799/article/details/111477320

callng avatar Feb 28 '21 18:02 callng

@jsososo 大佬看到修复下。

callng avatar Feb 28 '21 18:02 callng

获取下载地址这个,在app.js 里62行吧大概,有个 ownCookie 强行改为1的,去掉就行了,但是现在公用cookie有封号的风险,所以不太建议,如果传入的是带了cookie的那不会有问题。加密的会研究一下,但是最近可能没空,主要现在也不太急😂

jsososo avatar Mar 01 '21 02:03 jsososo

获取下载地址这个,在app.js 里62行吧大概,有个 ownCookie 强行改为1的,去掉就行了,但是现在公用cookie有封号的风险,所以不太建议,如果传入的是带了cookie的那不会有问题。加密的会研究一下,但是最近可能没空,主要现在也不太急😂

好的

callng avatar Mar 01 '21 13:03 callng

获取下载地址这个,在app.js 里62行吧大概,有个 ownCookie 强行改为1的,去掉就行了,但是现在公用cookie有封号的风险,所以不太建议,如果传入的是带了cookie的那不会有问题。加密的会研究一下,但是最近可能没空,主要现在也不太急😂

研究了两天, 最新的zzb签名

把提交的json使用md5加密

json

{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":"0","g_tk_new_20200303":208185208,"g_tk":208185208},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"551399144","songmid":["000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf"],"filename":["F000000Xx7FB0O2szE.flac","M800000Xx7FB0O2szE.mp3","C600000Xx7FB0O2szE.m4a","M500000Xx7FB0O2szE.mp3","C400000Xx7FB0O2szE.m4a","C200000Xx7FB0O2szE.m4a","C100000Xx7FB0O2szE.m4a"],"songtype":[0,0,0,0,0,0,0],"uin":"0","loginflag":1,"platform":"20","ctx":1,"musicfile":["F000000HXOpL2GGYPf.flac","M800000HXOpL2GGYPf.mp3","C600000HXOpL2GGYPf.m4a","M500000HXOpL2GGYPf.mp3","C400000HXOpL2GGYPf.m4a","C200000HXOpL2GGYPf.m4a","C100000HXOpL2GGYPf.m4a"]}}}

md5

7bb760eb0b3c7af620d75bd263335f21

然后md5字符串的[21, 4, 9, 26, 16, 20, 27, 30]这几位存为a

b6b32532

md5字符串的[18, 11, 3, 2, 1, 7, 6, 25]这几位作为c

dc7bbbe3

然后md5每两位的10进制值

[123,183,96,235,11,60,122,246,32,215,91,210,99,51,95,33]

与[212, 45, 80, 68, 195, 163, 163, 203, 157, 220, 254, 91, 204, 79, 104, 6]对应的值进行异或(^)

连接对应异或结果值对应的字符, 得到一个16位的字符串, 然后将这个字符串base64编码, 再去掉+/=这三个字符, 再传为小写, 得出b

r5owr8if2t29c6wjr3w3jw

最后签名为 'zzb' + a + b + c

zzbb6b32532r5owr8if2t29c6wjr3w3jwdc7bbbe3

swearl avatar Sep 15 '21 06:09 swearl

获取下载地址这个,在app.js 里62行吧大概,有个 ownCookie 强行改为1的,去掉就行了,但是现在公用cookie有封号的风险,所以不太建议,如果传入的是带了cookie的那不会有问题。加密的会研究一下,但是最近可能没空,主要现在也不太急😂

研究了两天, 最新的zzb签名

把提交的json使用md5加密

json

{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":"0","g_tk_new_20200303":208185208,"g_tk":208185208},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"551399144","songmid":["000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf"],"filename":["F000000Xx7FB0O2szE.flac","M800000Xx7FB0O2szE.mp3","C600000Xx7FB0O2szE.m4a","M500000Xx7FB0O2szE.mp3","C400000Xx7FB0O2szE.m4a","C200000Xx7FB0O2szE.m4a","C100000Xx7FB0O2szE.m4a"],"songtype":[0,0,0,0,0,0,0],"uin":"0","loginflag":1,"platform":"20","ctx":1,"musicfile":["F000000HXOpL2GGYPf.flac","M800000HXOpL2GGYPf.mp3","C600000HXOpL2GGYPf.m4a","M500000HXOpL2GGYPf.mp3","C400000HXOpL2GGYPf.m4a","C200000HXOpL2GGYPf.m4a","C100000HXOpL2GGYPf.m4a"]}}}

md5

7bb760eb0b3c7af620d75bd263335f21

然后md5字符串的[21, 4, 9, 26, 16, 20, 27, 30]这几位存为a

b6b32532

md5字符串的[18, 11, 3, 2, 1, 7, 6, 25]这几位作为c

dc7bbbe3

然后md5每两位的10进制值

[123,183,96,235,11,60,122,246,32,215,91,210,99,51,95,33]

与[212, 45, 80, 68, 195, 163, 163, 203, 157, 220, 254, 91, 204, 79, 104, 6]对应的值进行异或(^)

连接对应异或结果值对应的字符, 得到一个16位的字符串, 然后将这个字符串base64编码, 再去掉+/=这三个字符, 再传为小写, 得出b

r5owr8if2t29c6wjr3w3jw

最后签名为 'zzb' + a + b + c

zzbb6b32532r5owr8if2t29c6wjr3w3jwdc7bbbe3

大佬,最终签名‘zzb’ + a + b + c,我一直卡在b这里。请问这一步操作是怎么看出来的,可以给个提示吗?非常感谢!!

Sachs92 avatar Nov 01 '21 14:11 Sachs92

获取下载地址这个,在app.js 里62行吧大概,有个 ownCookie 强行改为1的,去掉就行了,但是现在公用cookie有封号的风险,所以不太建议,如果传入的是带了cookie的那不会有问题。加密的会研究一下,但是最近可能没空,主要现在也不太急😂

研究了两天, 最新的zzb签名 把提交的json使用md5加密 json

{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":"0","g_tk_new_20200303":208185208,"g_tk":208185208},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"551399144","songmid":["000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf","000HXOpL2GGYPf"],"filename":["F000000Xx7FB0O2szE.flac","M800000Xx7FB0O2szE.mp3","C600000Xx7FB0O2szE.m4a","M500000Xx7FB0O2szE.mp3","C400000Xx7FB0O2szE.m4a","C200000Xx7FB0O2szE.m4a","C100000Xx7FB0O2szE.m4a"],"songtype":[0,0,0,0,0,0,0],"uin":"0","loginflag":1,"platform":"20","ctx":1,"musicfile":["F000000HXOpL2GGYPf.flac","M800000HXOpL2GGYPf.mp3","C600000HXOpL2GGYPf.m4a","M500000HXOpL2GGYPf.mp3","C400000HXOpL2GGYPf.m4a","C200000HXOpL2GGYPf.m4a","C100000HXOpL2GGYPf.m4a"]}}}

md5

7bb760eb0b3c7af620d75bd263335f21

然后md5字符串的[21, 4, 9, 26, 16, 20, 27, 30]这几位存为a

b6b32532

md5字符串的[18, 11, 3, 2, 1, 7, 6, 25]这几位作为c

dc7bbbe3

然后md5每两位的10进制值

[123,183,96,235,11,60,122,246,32,215,91,210,99,51,95,33]

与[212, 45, 80, 68, 195, 163, 163, 203, 157, 220, 254, 91, 204, 79, 104, 6]对应的值进行异或(^) 连接对应异或结果值对应的字符, 得到一个16位的字符串, 然后将这个字符串base64编码, 再去掉+/=这三个字符, 再传为小写, 得出b

r5owr8if2t29c6wjr3w3jw

最后签名为 'zzb' + a + b + c

zzbb6b32532r5owr8if2t29c6wjr3w3jwdc7bbbe3

大佬,最终签名‘zzb’ + a + b + c,我一直卡在b这里。请问这一步操作是怎么看出来的,可以给个提示吗?非常感谢!!

b是多次跟踪看出来了...

swearl avatar Nov 02 '21 04:11 swearl

大佬,最终签名‘zzb’ + a + b + c,我一直卡在b这里。请问这一步操作是怎么看出来的,可以给个提示吗?非常感谢!!

<?php
function tencent_sign($content) {
        $md5         = md5($content);
        $indexPrefix = [21, 4, 9, 26, 16, 20, 27, 30];
        $indexSuffix = [18, 11, 3, 2, 1, 7, 6, 25];
        $base        = [212, 45, 80, 68, 195, 163, 163, 203, 157, 220, 254, 91, 204, 79, 104, 6];
        $sign        = $signPrefix        = $signSuffix        = '';
        for ($i = 0; $i < 8; ++$i) {
            $signPrefix .= $md5[$indexPrefix[$i]];
            $signSuffix .= $md5[$indexSuffix[$i]];
        }
        foreach ($base as $k => $v) {
            $sign .= chr(hexdec(substr($md5, $k * 2, 2)) ^ $v);
        }
        $sign = strtolower(str_replace(['+', '/', '='], '', base64_encode($sign)));

        return 'zzb' . $signPrefix . $sign . $signSuffix;
}

swearl avatar Nov 02 '21 08:11 swearl

大佬,最终签名‘zzb’ + a + b + c,我一直卡在b这里。请问这一步操作是怎么看出来的,可以给个提示吗?非常感谢!!

<?php
function tencent_sign($content) {
        $md5         = md5($content);
        $indexPrefix = [21, 4, 9, 26, 16, 20, 27, 30];
        $indexSuffix = [18, 11, 3, 2, 1, 7, 6, 25];
        $base        = [212, 45, 80, 68, 195, 163, 163, 203, 157, 220, 254, 91, 204, 79, 104, 6];
        $sign        = $signPrefix        = $signSuffix        = '';
        for ($i = 0; $i < 8; ++$i) {
            $signPrefix .= $md5[$indexPrefix[$i]];
            $signSuffix .= $md5[$indexSuffix[$i]];
        }
        foreach ($base as $k => $v) {
            $sign .= chr(hexdec(substr($md5, $k * 2, 2)) ^ $v);
        }
        $sign = strtolower(str_replace(['+', '/', '='], '', base64_encode($sign)));

        return 'zzb' . $signPrefix . $sign . $signSuffix;
}

哦哦,非常感谢哈!我前面说的卡在b那里,是调试的时候,一直看不出来b是怎么生成,我太菜了。

Sachs92 avatar Nov 02 '21 10:11 Sachs92

哦哦,非常感谢哈!我前面说的卡在b那里,是调试的时候,一直看不出来b是怎么生成,我太菜了。

我也是坑了一天, 主要是base64干扰了, 后来看了一下, 发现好像是base64, 然后就省了很多东西了

swearl avatar Nov 03 '21 01:11 swearl

如果有人好奇这个堆栈虚拟机怎么静态分析(或配合动态分析 😄):

jixunmoe avatar Dec 23 '21 00:12 jixunmoe