0


web逆向笔记:js逆向案例四 QQ音乐 sign值(webpack打包代码如何扣取)

web逆向笔记:js逆向案例四 QQ音乐 sign值(webpack打包代码如何扣取)

一、webpack介绍:

​ Webpack 是一个模块打包工具,主要用于 JavaScript 应用程序。它可以将许多模块打包成一个或多个 bundle,从而优化加载速度和减少加载时间。Webpack 可以处理各种资源,包括 JavaScript、CSS、图片、字体等,并且可以将其转换为浏览器可以理解的格式。

Webpack 的主要特点包括:

  1. 模块化:Webpack 允许你将应用程序划分为许多小的、独立的模块,这些模块可以被重复使用,并且可以轻松地进行更改和更新。
  2. 高效性:Webpack 使用高级优化算法来最小化生成的 bundle 的大小,从而加快加载速度。它还支持代码拆分、懒加载等功能,以便进一步优化性能。
  3. 灵活性:Webpack 支持各种插件和加载器,可以用于处理不同类型的资源,并且可以扩展其功能以适应不同的项目需求。
  4. 可配置性:Webpack 提供了丰富的配置选项,可以根据项目需求进行灵活的配置,以满足不同的构建要求。

总的来说,Webpack 是一个强大的工具,可以帮助开发人员更高效地构建和维护 JavaScript 应用程序。它已经成为前端开发中不可或缺的一部分,被广泛使用于各种项目中。

二、
webpack

打包简介

在这里插入图片描述

1、
webpack

数组形式

!function(e){var t ={};// 加载器  所有的模块都是从这个函数加载 执行functionn(r){if(t[r])return t[r].exports;var o = t[r]={i: r,l:!1,exports:{}};return e[r].call(o.exports, o, o.exports, n),
            o.l =!0,
            o.exports
    }n(0)}([function(){
            console.log('123456')},function(){
            console.log('模块2')},])
2、
webpack

对象形式

!function(e){var t ={};//  所有的模块 都是从这个加载器 执行的  分发器functionn(r){if(t[r])return t[r].exports;var o = t[r]={i: r,l:!1,exports:{}};return e[r].call(o.exports, o, o.exports, n),
        o.l =!0,
        o.exports
    }n('xialuo')// 对象 根据KEY 找模块}({0:function(){
            console.log('我是模块1  负责加密')},'xialuo':function(){
            console.log('我是模块2  负责解密')},2:function(){
            console.log('我是模块3  负责爬数据')}});
三、多个
JS

文件打包

​ 如果模块比较多,就会将模块打包成JS文件, 然后定义一个全局变量 window[“webpackJsonp”] = [ ],它的作用是存储需要动态导入的模块,然后重写 window[“webpackJsonp”] 数组的 push( ) 方法为 webpackJsonpCallback( ),也就是说 window[“webpackJsonp”].push( ) 其实执行的是 webpackJsonpCallback( ),window[“webpackJsonp”].push( )接收三个参数,第一个参数是模块的ID,第二个参数是 一个数组或者对象,里面定义大量的函数,第三个参数是要调用的函数(可选)

在这里插入图片描述

四、QQ音乐sign值获取
1、接口分析

在这里插入图片描述

在这里插入图片描述

// sign值生成// n方法为加载器
o =n(147).default;
i =o(e.data);
sign = i;

在这里插入图片描述

在这里插入图片描述

2、扣取加载器方法
window = global;// 加载器!function(e){functiont(t){for(var r, n, f = t[0], c = t[1], i = t[2], l =0, u =[]; l < f.length; l++)
            n = f[l],Object.prototype.hasOwnProperty.call(o, n)&& o[n]&& u.push(o[n][0]),
            o[n]=0;for(r in c)Object.prototype.hasOwnProperty.call(c, r)&&(e[r]= c[r]);for(b &&b(t); u.length;)
            u.shift()();return d.push.apply(d, i ||[]),a()}functiona(){for(var e, t =0; t < d.length; t++){for(var a = d[t], r =!0, n =1; n < a.length; n++){var c = a[n];0!== o[c]&&(r =!1)}
            r &&(d.splice(t--,1),
            e =f(f.s = a[0]))}return e
    }var r ={}, n ={21:0}, o ={21:0}, d =[];functionf(t){if(r[t])return r[t].exports;var a = r[t]={i: t,l:!1,exports:{}};return e[t].call(a.exports, a, a.exports, f),
        a.l =!0,
        a.exports
    }// 定义全局变量介绍加载器方法
    window.xiaopacai = f;
    f.e=function(e){var t =[];
        n[e]? t.push(n[e]):0!== n[e]&&{1:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1,10:1,11:1,12:1,13:1,14:1,15:1,16:1,17:1,18:1,19:1,20:1,22:1,23:1,24:1,25:1,26:1}[e]&& t.push(n[e]=newPromise((function(t, a){for(var r ="css/"+({1:"common",3:"album",4:"albumDetail",5:"album_mall",6:"category",7:"cmtpage",8:"download_detail",9:"index",10:"msg_center",11:"mv",12:"mvList",13:"mv_toplist",14:"notfound",15:"player",16:"player_radio",17:"playlist",18:"playlist_edit",19:"profile",20:"radio",22:"search",23:"singer",24:"singer_list",25:"songDetail",26:"toplist"}[e]|| e)+"."+{1:"2e3d715e72682303d35b",3:"5cf0d69eaf29bcab23d2",4:"798353db5b0eb05d5358",5:"df4c243f917604263e58",6:"20d532d798099a44bc88",7:"e3bedf2b5810f8db0684",8:"e3bedf2b5810f8db0684",9:"ea0adb959fef9011fc25",10:"020422608fe8bfb1719a",11:"8bdb1df6c5436b790baa",12:"47ce9300786df1b70584",13:"4aee33230ba2d6b81dce",14:"e6f63b0cf57dd029fbd6",15:"1d2dbefbea113438324a",16:"d893492de07ce97d8048",17:"9484fde660fe93d9f9f0",18:"67fb85e7f96455763c83",19:"5e8c651e74b13244f7cf",20:"3befd83c10b19893ec66",22:"b2d11f89ea6a512a2302",23:"c7a38353c5f4ebb47491",24:"df0961952a2d3f022894",25:"4c080567e394fd45608b",26:"8edb142553f97482e00f"}[e]+".chunk.css?max_age=2592000", o = f.p + r, d = document.getElementsByTagName("link"), c =0; c < d.length; c++){var i =(b = d[c]).getAttribute("data-href")|| b.getAttribute("href");if("stylesheet"=== b.rel &&(i === r || i === o))returnt()}var l = document.getElementsByTagName("style");for(c =0; c < l.length; c++){var b;if((i =(b = l[c]).getAttribute("data-href"))=== r || i === o)returnt()}var u = document.createElement("link");
            u.rel ="stylesheet",
            u.type ="text/css",
            u.onload = t,
            u.onerror=function(t){var r = t && t.target && t.target.src || o
                  , d =newError("Loading CSS chunk "+ e +" failed.\n("+ r +")");
                d.code ="CSS_CHUNK_LOAD_FAILED",
                d.request = r,delete n[e],
                u.parentNode.removeChild(u),a(d)},
            u.href = o,0!== u.href.indexOf(window.location.origin +"/")&&(u.crossOrigin ="anonymous"),
            document.getElementsByTagName("head")[0].appendChild(u)})).then((function(){
            n[e]=0})));var a = o[e];if(0!== a)if(a)
                t.push(a[2]);else{var r =newPromise((function(t, r){
                    a = o[e]=[t, r]}));
                t.push(a[2]= r);var d, c = document.createElement("script");
                c.charset ="utf-8",
                c.timeout =120,
                f.nc && c.setAttribute("nonce", f.nc),
                c.src=function(e){return f.p +"js/"+({1:"common",3:"album",4:"albumDetail",5:"album_mall",6:"category",7:"cmtpage",8:"download_detail",9:"index",10:"msg_center",11:"mv",12:"mvList",13:"mv_toplist",14:"notfound",15:"player",16:"player_radio",17:"playlist",18:"playlist_edit",19:"profile",20:"radio",22:"search",23:"singer",24:"singer_list",25:"songDetail",26:"toplist"}[e]|| e)+".chunk."+{1:"0b15a31f7bc269ea76ff",3:"b3395a2d475262b98fa7",4:"dea94b21a47cdb6d0f65",5:"f5b6937e84f33133b31d",6:"6c4ac3718d0230ac3b1c",7:"ae411fac801093307ebc",8:"f1c40f6b3a431ca4c9ac",9:"52f2369df6a4a3649011",10:"90aef56793aff533bf57",11:"4c23320d028878580c26",12:"b43316a48154164d557b",13:"8adf08693025ab48224f",14:"89eb6da604ebcf2dda2d",15:"c9d5d7c9966dea2b213c",16:"07b3290e08abf8a4e901",17:"6838a647ca4abb619832",18:"9d2cbd13db3328dcd357",19:"ce6940fdeda857506a27",20:"8af74f665077243ecefa",22:"5a013d73a1da88cc221e",23:"469f622f5dffdeee26eb",24:"9df420e7d63b8d867fd2",25:"9bea17905ada32dde9b5",26:"bcb481bd9dd2001370ac"}[e]+".js?max_age=2592000"}(e),0!== c.src.indexOf(window.location.origin +"/")&&(c.crossOrigin ="anonymous");var i =newError;d=function(t){
                    c.onerror = c.onload =null,clearTimeout(l);var a = o[e];if(0!== a){if(a){var r = t &&("load"=== t.type ?"missing": t.type), n = t && t.target && t.target.src;
                            i.message ="Loading chunk "+ e +" failed.\n("+ r +": "+ n +")",
                            i.name ="ChunkLoadError",
                            i.type = r,
                            i.request = n,
                            a[1](i)}
                        o[e]=void0}};var l =setTimeout((function(){d({type:"timeout",target: c
                    })}),12e4);
                c.onerror = c.onload = d,
                document.head.appendChild(c)}return Promise.all(t)},
    f.m = e,
    f.c = r,
    f.d=function(e, t, a){
        f.o(e, t)|| Object.defineProperty(e, t,{enumerable:!0,get: a
        })},
    f.r=function(e){"undefined"!==typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag,{value:"Module"}),
        Object.defineProperty(e,"__esModule",{value:!0})},
    f.t=function(e, t){if(1& t &&(e =f(e)),8& t)return e;if(4& t &&"object"===typeof e && e && e.__esModule)return e;var a = Object.create(null);if(f.r(a),
        Object.defineProperty(a,"default",{enumerable:!0,value: e
        }),2& t &&"string"!=typeof e)for(var r in e)
                f.d(a, r,function(t){return e[t]}.bind(null, r));return a
    },
    f.n=function(e){var t = e && e.__esModule ?function(){return e.default
        }:function(){return e
        };return f.d(t,"a", t),
        t
    },
    f.o=function(e, t){returnObject.prototype.hasOwnProperty.call(e, t)},
    f.p ="/ryqq/",
    f.oe=function(e){throw e
    };var c = window.webpackJsonp = window.webpackJsonp ||[], i = c.push.bind(c);
    c.push = t,
    c = c.slice();for(var l =0; l < c.length; l++)t(c[l]);var b = i;a()}([]);
3、模块扣取(可以单个模块扣取,然后运行,缺什么补什么就可以了;也可以扣取整个js文件,然后通过require(‘./webpack.js’)形式引用即可)。这里为了方便采用了引用的方式。运行结果与网页对比,发现不一致情况。

在这里插入图片描述

这里出现这种情况,应该是有浏览器环境检测,我们没有补充。可以放到补环境框架中运行,然后补充对应所需环境;也可以手动补几个常见的浏览器环境(如:document、navigator、location等)并给手动补充的环境挂上代理。
// 挂代理代码(主要监听get、set方法)
ld ={}; 
ld.config ={}; 
ld.config.proxy =true;// 增加属性,用于执行是否开启代理操作// 获取对象类型操作
ld.typeObject=functiontypeObject(obj){returnObject.prototype.toString.call(obj);}// 代理函数
ld.proxy=functionproxy(obj, objName){if(!ld.config.proxy){return obj;}let handler ={get:function(target, prop, receiver){let result;try{// 防止报错
                result = Reflect.get(target, prop, receiver);// 使用映射的方法,来调用get方法// 获取对象类型let type = ld.typeObject(result);if(result instanceofObject){
                    console.log(`{get操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回类型:[${type}]}`);
                    result = ld.proxy(result,`${objName}.${prop.toString()}`);}elseif(typeof result ==="symbol"){
                    console.log(`{get操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回结果:[${result.toString()}]}`);}else{
                    console.log(`{get操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回结果:[${result}]}`);}}catch(e){
                console.log(`{get操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 错误信息:[${e.message}]}`);}return result
        },set:function(target, prop, value, receiver){let result
            try{// 防止报错
                result = Reflect.set(target, prop, value, receiver);// 使用映射的方法,来调用set方法// 获取对象类型let type = ld.typeObject(value);if(value instanceofObject){
                    console.log(`{set操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回类型:[${type}]}`);}elseif(typeof value ==="symbol"){
                    console.log(`{set操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回结果:[${value.toString()}]}`);}else{
                    console.log(`{set操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 返回结果:[${value}]}`);}}catch(e){
                console.log(`{set操作| 对象名:[${objName}] -->属性名:[${prop.toString()}], 错误信息:[${e.message}]}`);}return result
        }};returnnewProxy(obj, handler);}

在这里插入图片描述

补齐缺少的属性值,结果就和浏览器一样了。
3、构造请求,获取所需数据
import requests
import time
import execjs

headers ={'authority':'u6.y.qq.com','accept':'application/json','accept-language':'zh-CN,zh;q=0.9','cache-control':'no-cache','content-type':'application/x-www-form-urlencoded','pragma':'no-cache','referer':'https://y.qq.com/','sec-ch-ua':'"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"','sec-ch-ua-mobile':'?0','sec-ch-ua-platform':'"Windows"','sec-fetch-dest':'empty','sec-fetch-mode':'cors','sec-fetch-site':'same-site','user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',}
data ='{"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":"5630580667","songmid":["001Xs1NW3wgWpq","0027Z2qE0pDuKY"],"songtype":[0,0],"uin":"0","loginflag":1,"platform":"20"}},"req_2":{"module":"music.musicasset.SongFavRead","method":"IsSongFanByMid","param":{"v_songMid":["0016aXcd24qSC8","001Xs1NW3wgWpq","0027Z2qE0pDuKY","003V4xd80ty2df"]}},"req_3":{"module":"music.musichallSong.PlayLyricInfo","method":"GetPlayLyricInfo","param":{"songMID":"0016aXcd24qSC8","songID":457240977}},"req_4":{"method":"GetCommentCount","module":"music.globalComment.GlobalCommentRead","param":{"request_list":[{"biz_type":1,"biz_id":"457240977","biz_sub_type":0}]}},"req_5":{"module":"music.musichallAlbum.AlbumInfoServer","method":"GetAlbumDetail","param":{"albumMid":"001ln9YB420a7b"}},"req_6":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"9307341590","songmid":["0016aXcd24qSC8"],"songtype":[0],"uin":"0","loginflag":1,"platform":"20","filename":["RS020640pBtN0etKNM.mp3"]}}}'withopen('./get_sign.js','r', encoding='utf-8')as f:
    code_js = f.read()
sign = execjs.compile(code_js).call('get_sign', data)
params ={'_':round(time.time()*1000),'sign': sign,}

response = requests.post('https://u6.y.qq.com/cgi-bin/musics.fcg', params=params, headers=headers, data=data)print(response.json()["req_1"]['data']["midurlinfo"])
总结:
1、webpack打包的js文件,无论是单文件还是多文件,在逆向时首先需要找到对应的加载器。
2、加载器获取完成后,可以单个模块扣取代码并进调试,也可以扣取整个js文件,进行加载使用。
3、扣取完整代码后,出现结果与网页不一致时,大多数情况下是缺少浏览器环境;可以尝试补充一些常用的环境,并挂上代理方法查看缺少内容。
4、可以将扣取的完整代码,现在浏览器中运行,查看结果是否正确;在将代码在本地运行进行对比,可以快速确认是否是缺少环境导致结果不一样的。

本文转载自: https://blog.csdn.net/qq_49268524/article/details/136817186
版权归原作者 小爬菜 所有, 如有侵权,请联系我们删除。

“web逆向笔记:js逆向案例四 QQ音乐 sign值(webpack打包代码如何扣取)”的评论:

还没有评论