(编辑:jimmy 日期: 2025/11/6 浏览:2)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132331sicd1dmkvld1p6k6.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132416wyz2bmmgiz33tim8.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132557iivhifjdi04hhjs7.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132622pxmzm9mqzm6bm9f9.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132658tkyrkjchnhavjxii.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132806fnhxsn01eszp94xs.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/132935j8l68zj7h1h6z1ll.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133024o4hx1admybaka4gh.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133039j2c1zp8a13elz1zv.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133215vjnd32z8rp89ljr0.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133304qwa88s8z911w1w61.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133326ps0655fg6pp665z0.jpg)
{ "code": 200, "privileges": [{...}], "songs": [{...}]}
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/133426nu6imk96mx6xo77i.jpg)
(function () { window.hooker = new Hooker(); function Hooker() { const H = this; const makeid = idmaker(); const map = H.map = {}; H.hook = hook; H.unhook = unhook; function hook(base, path, log=false, apply_debugger=false, hook_return=false) { // target path = arrPath(path); let parent = base; for (let i = 0; i < path.length - 1; i++) { const prop = path[i]; parent = parent[prop]; } const prop = path[path.length-1]; const target = parent[prop]; // Only hook functions if (typeof target !== 'function') { throw new TypeError('hooker.hook: Hook functions only'); } // Check args valid if (hook_return) { if (typeof hook_return !== 'object' || hook_return === null) { throw new TypeError('hooker.hook: Argument hook_return should be false or an object'); } if (!hook_return.hasOwnProperty('value') && typeof hook_return.dealer !== 'function') { throw new TypeError('hooker.hook: Argument hook_return should contain one of following properties: value, dealer'); } if (hook_return.hasOwnProperty('value') && typeof hook_return.dealer === 'function') { throw new TypeError('hooker.hook: Argument hook_return should not contain both of following properties: value, dealer'); } } // hooker function const hooker = function hooker() { let _this = this === H ? null : this; let args = Array.from(arguments); const config = map[id].config; const hook_return = config.hook_return; // hook functions config.log && console.log([base, path.join('.')], _this, args); if (config.apply_debugger) {debugger;} if (hook_return && typeof hook_return.dealer === 'function') { [_this, args] = hook_return.dealer(_this, args); } // continue stack return hook_return && hook_return.hasOwnProperty('value') ? hook_return.value : target.apply(_this, args); } parent[prop] = hooker; // Id const id = makeid(); map[id] = { id: id, prop: prop, parent: parent, target: target, hooker: hooker, config: { log: log, apply_debugger: apply_debugger, hook_return: hook_return } }; return map[id]; } function unhook(id) { // unhook try { const hookObj = map[id]; hookObj.parent[hookObj.prop] = hookObj.target; delete map[id]; } catch(err) { console.error(err); DoLog(LogLevel.Error, 'unhook error'); } } function arrPath(path) { return Array.isArray(path) ? path : path.split('.') } function idmaker() { let i = 0; return function() { return i++; } } }}) ();
hooker.hook(window.XMLHttpRequest.prototype, 'open', true, true);hooker.hook(window.XMLHttpRequest.prototype, 'send', true, true);
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134050r981sdul97yjlsob.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134104m69w4z9w4wze4ww7.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134128szawvkwa5wvvhhph.jpg)
// hook top windowhooker.hook(window.XMLHttpRequest.prototype, 'open', true, true);hooker.hook(window.XMLHttpRequest.prototype, 'send', true, true);// iframe.contentWindowhooker.hook(document.querySelector('#g_iframe').contentWindow.XMLHttpRequest.prototype, 'open', true, true);hooker.hook(document.querySelector('#g_iframe').contentWindow.XMLHttpRequest.prototype, 'send', true, true);
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134245of6zikgshsfmqrs3.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134451lqy2g4y68ac1dqnc.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134524oe62eg7y22j9jqoz.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/134946f3mmlvk8eggohb8k.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/135112zyk1wuz1bn110t1u.jpg)
(function() { let xhr; const AEL = getPureAEL(); // hook top window hooker.hook(window.XMLHttpRequest.prototype, 'open', false, false, { dealer: onOpen }); hooker.hook(window.XMLHttpRequest.prototype, 'send', false, false, { dealer: onSend }); // iframe.contentWindow hooker.hook(document.querySelector('#g_iframe').contentWindow.XMLHttpRequest.prototype, 'open', false, false, { dealer: onOpen }); hooker.hook(document.querySelector('#g_iframe').contentWindow.XMLHttpRequest.prototype, 'send', false, false, { dealer: onSend }); function onOpen(_this, args) { if (args[1].includes('/weapi/v3/song/detail')) { // 记录detail api的xhr xhr = _this; } return [_this, args]; } function onSend(_this, args) { if (xhr === _this) { AEL.call(_this, 'load', function(e) { debugger; }); } return [_this, args]; } // Get unpolluted addEventListener function getPureAEL(parentDocument=document) { const ifr = makeIfr(parentDocument); const oWin = ifr.contentWindow; const oDoc = ifr.contentDocument; const AEL = oWin.XMLHttpRequest.prototype.addEventListener; return AEL; } // Get unpolluted removeEventListener function getPureREL(parentDocument=document) { const ifr = makeIfr(parentDocument); const oWin = ifr.contentWindow; const oDoc = ifr.contentDocument; const REL = oWin.XMLHttpRequest.prototype.removeEventListener; return REL; } function makeIfr(parentDocument=document) { const ifr = parentDocument.createElement('iframe'); ifr.srcdoc = '<html></html>'; ifr.style.width = ifr.style.height = ifr.style.border = ifr.style.padding = ifr.style.margin = '0'; parentDocument.body.appendChild(ifr); return ifr; }}) ();
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/135504vf3sn9dkiu4b60tz.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/135518sgp96c6uvngc6lz6.jpg)
function onSend(_this, args) { if (xhr === _this) { AEL.call(_this, 'load', function(e) { debugger; }); debugger; } return [_this, args];}
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/135636a7tx142m26qukxiq.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/140027d48494coeao9javs.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/140030pxnyplz9u99yx8d9.jpg)
function onSend(_this, args) { if (xhr === _this) { AEL.call(_this, 'readystatechange', function(e) { _onreadystatechange = _this.onreadystatechange; _this.onreadystatechange = onProgress; debugger; }, {once: true}); // once参数指定事件监听器仅仅触发一次 } return [_this, args];}function onProgress(e) { debugger;}
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/140238ccnkn77hww3xy07s.jpg)
function onProgress(e) { const xhr = e.target; if (xhr.readyState === 4) { const RATES = { 'none': 0, 'standard': 128000, 'exhigh': 320000,'lossless': 999000, }; // br-level 对照表,可从普通单曲的请求中收集到 const json = JSON.parse(xhr.response); const privilege = json['privileges'][0]; dlLevel = privilege['downloadMaxBrLevel']; dlRate = RATES[dlLevel]; plLevel = privilege['playMaxBrLevel']; plRate = RATES[plLevel]; privilege['dlLevel'] = dlLevel; // Download privilege['dl'] = dlRate; // Download privilege['plLevel'] = plLevel; // Play privilege['pl'] = plRate; // Play const response = JSON.stringify(json) const propDesc = { value: response, writable: false, configurable: false, enumerable: true } Object.defineProperties(xhr, { 'response': propDesc, 'responseText': propDesc }); } // 别忘了继续执行页面前端js _onreadystatechange(e);}
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/141045bcqnnnhedneocchk.jpg)
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/141104ttg5xpfw8x88y18x.jpg)
GM_xmlhttpRequest({ method: "GET", url: api_got_url, // 第三方接口返回的url onprogress: function(e) { json.data[0].url = e.finalUrl; // 填入其他属性 onreadystatechange.apply(_this, args); // 继续执行页面前端代码 }})
![[新人试投]某云音乐前端播放器逆向](/UploadFiles/2021-04-26/141243pjukpykjujjct1cj.jpg)