如何逆向加密参数:某音乐平台歌曲信息逆向之webpack扣取-CSDN博客
参数构建
{
"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": 5381,
"g_tk": 5381
},
"req_1": {
"module": "vkey.GetVkeyServer",
"method": "CgiGetVkey",
"param": {
"guid": "7146813132",
"songmid": ["002dw4gv1ZmiGt"],
"songtype": [0],
"uin": "0",
"loginflag": 1,
"platform": "20"
}
},
"req_2": {
"module": "music.musicasset.SongFavRead",
"method": "IsSongFanByMid",
"param": {
"v_songMid": ["002dw4gv1ZmiGt"]
}
},
"req_3": {
"module": "music.musichallSong.PlayLyricInfo",
"method": "GetPlayLyricInfo",
"param": {
"songMID": "002dw4gv1ZmiGt",
"songID": 372639235
}
},
"req_4": {
"method": "GetCommentCount",
"module": "music.globalComment.GlobalCommentRead",
"param": {
"request_list": [{
"biz_type": 1,
"biz_id": "372639235",
"biz_sub_type": 0
}]
}
},
"req_5": {
"module": "music.musichallAlbum.AlbumInfoServer",
"method": "GetAlbumDetail",
"param": {
"albumMid": "003QIVDT3UB8zG"
}
},
"req_6": {
"module": "vkey.GetVkeyServer",
"method": "CgiGetVkey",
"param": {
"guid": "9868485411",
"songmid": ["002dw4gv1ZmiGt"],
"songtype": [0],
"uin": "0",
"loginflag": 1,
"platform": "20"
}
}
}
分析参数
-
req_1 中参数 【guid】,【songmid】,
-
req_2中参数【v_songMid】,
-
req_3中参数【songMID】,【songID】
-
req_4中参数【biz_id】
-
req_5 中参数【albumMid】
-
req_6中参数【guid】,【songmid】
由请求参数中可看出:
songmid == v_songMid == songMID == biz_id
那么这几个可以根据歌曲详情页链接后缀得到
问题参数
guid
songID 歌曲编号
albumMid 专辑短链
guid 参数逆向
调试跟栈可定位到giud生成位置
function getGuid() {
a = (new Date).getUTCMilliseconds()
return String(Math.round(2147483647 * Math.random()) * a % 1e10);
}
那么其余参数如何获取呢 ??? 带着这个问题开始寻找之路
寻找接口
来到歌曲详情页面开始各种搜索发现前文章中提到得接口被反复请求,仔细观察之下发现有需要得结果。
请求参数
{
"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": 5381,
"g_tk": 5381
},
"req_1": {
"module": "music.musicsearch.HotkeyService",
"method": "GetHotkeyForQQMusicMobile",
"param": {
"searchid": "26594278617551874",
"remoteplace": "txt.yqq.top",
"from": "yqqweb"
}
},
"req_2": {
"method": "get_song_detail_yqq",
"module": "music.pf_song_detail_svr",
"param": {
"song_mid": "002dw4gv1ZmiGt"
}
},
"req_3": {
"module": "music.paycenterapi.LoginStateVerificationApi",
"method": "GetChargeAccount",
"param": {
"appid": "mlive"
}
}
}
参数刨析
-
req_1 中参数 【searchid】
-
req_2中参数【song_mid】,
由首次分析可知 song_mid 为歌曲得短链,可有歌曲详情页中链接提取到
调试取参
【searchid】26594278617551874
断点跟栈
如上方式跟栈大概到 k.request 处发现关键位置
this.request = function(t) {
var n = t instanceof Array ? t : [t];
e.wait || (e.wait = e.sendRequest());
var r = {};
return n.forEach((function(t) {
e.index += 1,
t.param || (t.param = {}),
r["req_" + e.index] = t
}
)),
e.reqData = Object.assign(Object.assign({}, e.reqData), r),
e.wait.then((function(t) {
var e = Object.keys(r);
return 0 === e.length ? [] : e.map((function(e) {
return t[e]
}
))
}
))
}
e.reqData = Object.assign(Object.assign({}, e.reqData), r),
此处打上断点看变量 r 值结果
存在需要得变量 【searchid】
进一步跟栈可跟踪到我们需要得位置: searchid: Object(_.a)(1)
扣取代码
, function(e, t, n) {
"use strict";
n.d(t, "a", (function() {
return i
}
));
var a = function(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = [], i = n.length, o = a.length, c = 0, s = i + o - 1; c <= s; c++)
r[c] = 0;
for (var l = 0; l < o; l++)
for (var u = 0; u < i; u++)
r[u + l] += parseInt(n[u], 10) * parseInt(a[l], 10),
r[u + 1 + l] += Math.floor(r[u + l] / 10),
r[u + l] = r[u + l] % 10;
return r.reverse(),
0 == r[0] && r.shift(),
r.join("")
}
, r = function(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = n.length, i = a.length, o = 0, c = 0, s = 0, l = 0, u = 0, m = Math.max(r, i); u < m; u++)
c = u < r ? parseInt(n[u], 10) : 0,
s = u < i ? parseInt(a[u], 10) : 0,
l = Math.round(c) + Math.round(s) + o,
n[u] = "".concat(l % 10),
o = l >= 10 ? 1 : 0;
return 1 == o && n.push("1"),
n.reverse().join("")
}
, i = function(e) {
var t = a(e, "18014398509481984")
, n = a(Math.round(Math.random() * parseInt("4194304", 10)), "4294967296")
, i = new Date
, o = 1e3 * (3600 * i.getHours() + 60 * i.getMinutes() + i.getSeconds()) + i.getMilliseconds();
return r(r(t, n), o)
}
}
通看下来 没有进行其余操作, 我们可以将该内容加入到前文webpack加载器中,也可自行更改函数,
方式二实现
function getSearchId( e ){
var a = function(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = [], i = n.length, o = a.length, c = 0, s = i + o - 1; c <= s; c++)
r[c] = 0;
for (var l = 0; l < o; l++)
for (var u = 0; u < i; u++)
r[u + l] += parseInt(n[u], 10) * parseInt(a[l], 10),
r[u + 1 + l] += Math.floor(r[u + l] / 10),
r[u + l] = r[u + l] % 10;
return r.reverse(),
0 == r[0] && r.shift(),
r.join("")
}
, r = function(e, t) {
for (var n = "".concat(e).split("").reverse(), a = "".concat(t).split("").reverse(), r = n.length, i = a.length, o = 0, c = 0, s = 0, l = 0, u = 0, m = Math.max(r, i); u < m; u++)
c = u < r ? parseInt(n[u], 10) : 0,
s = u < i ? parseInt(a[u], 10) : 0,
l = Math.round(c) + Math.round(s) + o,
n[u] = "".concat(l % 10),
o = l >= 10 ? 1 : 0;
return 1 == o && n.push("1"),
n.reverse().join("")
};
var t = a(e, "18014398509481984")
, n = a(Math.round(Math.random() * parseInt("4194304", 10)), "4294967296")
, i = new Date
, o = 1e3 * (3600 * i.getHours() + 60 * i.getMinutes() + i.getSeconds()) + i.getMilliseconds();
return r(r(t, n), o)
}
调用方式
整合调试
详情接口
组建参数
【searchid】,【song_mid】
发起请求
_ 为时间戳, sign 值为前文逆向出来将请求参数传递进入可得到加密后得结果
歌曲id = result['req_2'][ 'data' ][ 'track_info' ][ 'id' ]专辑短链 = result['req_2'][ 'data' ][ 'track_info' ][ 'album' ][ 'mid' ]
播放接口
将上述拿到得信息写入对应参数位置后,则可发起请求
songID = result['req_2'][ 'data' ][ 'track_info' ][ 'id' ]
albumMid = result['req_2'][ 'data' ][ 'track_info' ][ 'album' ][ 'mid' ]