声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关
注意:
由于该文章是存了很久的文章,忘记发了,找源代码时已经找到,无法验证是否有效,不过逆向最重要的还是理解原理,没有什么是一成不变的,有需要的同学本文可以用于参考
一、webpack打包方式
webpack 是 JavaScript 应用程序的模块打包器,可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和 plugins (插件)对资源进行处理,打包成符合生产环境部署的前端资源。所有的资源都是通过 JavaScript 渲染出来的。
1.整个打包的文件是一个自执行函数
2.方法里面是webpack
3.存放的模块就是js的每个功能,可以有两中方式,数组和键值对的形式
二、webpack打包后加载器代码示例
加载器是网站的开发人员用工具生成的我们可以不用管直接拿过来用就好,一般加载器都会有类似 n.m = e 的代码
1.webpack数组形式,给需要处理业务的模块进行打包,通过下标取值
!function (e) {
// 存放加载器
var c = {}
function n(t) {
var a = c[t] = {
i: t,
l: !1,
exports: {}
};
console.log(a)
return e[t].call(a.exports, a, a.exports, n),
a.l = !0,
a.exports
}
n.m = e
n(2)
}([
// 存放模块
function () {
console.log('负责登陆')
},
function () {
console.log('负责注册')
},
function () {
console.log('负责注册')
}
])
2.webpack对象格式,给需要处理业务的模块进行打包,通过 key 取值
!function (e) {
var t = {};
// 所有的模块 都是从这个加载器 执行的 分发器
function n(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 负责爬数据')
}
}
);
三、找出加密参数
1.js运行 atob(‘aHR0cHM6Ly9rdWFqaW5nLnBpbmR1b2R1by5jb20vbG9naW4=’) 拿到网址,F12打开调试工具,访问网站随便输入手机号和密码点击登录,找到 bg/quiet/api/mms/login 请求,分别切换headers、payload、preview,会发现 header、payload中没有经过特别处理的字段,preview 响应结果加密,鼠标右击请求找到Copy>Copy as cUrl(cmd)
2.打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码
3.新建pinduoduo.py文件,把代码复制到该文件内,把请求中的参数拷贝给data,请求中的data参数换成json,运行文件,发现请求成功并成功获取到数据
4.新建 pinduoduo.js、webpackload.js 用于放扣下的代码和webpack加载器
四、定位参数位置
1.关键字搜索 encryptPassword,会发现 encryptPassword 赋值的地方
2.右击该文件,点击在sources中打开
3.在sources中打开文件后,Ctrl+F在文件内搜索 encryptPassword,会找到 encryptPassword 赋值的地方,打上断点,随便输入账号密码登录,会进入该断点,在控制台打印出 Object(P.a)(b.password, G.current),会发现加密信息是由 Object(P.a)(b.password, G.current) 生成,加密位置定位成功
五、分析加密代码
1.把 P.a、b.password、G.current在控制台打印,会发现 P.a 是加密方法、b.password是加密明文、G.current是一个包含公钥和版本号的json,把代码拷贝到 pinduoduo.js
2.需要注意的是 G.current 是前置请求 bg/quiet/api/mms/key/login 生成的,在分析加密的过程中可能遇到密钥是请求返回的,可以把生成的密钥搜索下可以判断是请求生成还是 js 写死,如果请求中没有,那就是 js 写死
3.鼠标悬浮到 P.a,点击蓝色部分会找到该方法,在 try 代码内部打上断点
4.结束此次断点调试,点击登录重新发送请求,点击跳过断点,看见刚才的断点,会发现 加密代码是由 t.encrypt(e) 生成,其中参数e、n分别是密码明文和密钥对象,t = new o.a,而 o = t(1395),t(1395)就是webpack打包后的加载器,把代码拷贝到 pinduoduo.js
六、分析webpack加载器代码
1.在 o = t(1395) 打上断点,加载器一般是网站初始化加载的,刷新页面会进入该断点
2.鼠标悬浮到 t 点击蓝色部分,会找到加载器位置
3.分析代码,会发现和加载器示例代码中 n.m = e 类似的代码 f.m = e,说明 f 就是加载器,把 t.m 输出控制台,就会由加载器的函数
4.把加载器整个代码拷贝到 webpackload.js,并把加载器导出
5.运行 webpackload.js 会发现报错,之所以报错是因为window是浏览器的对象,在node环境是没有该对象的,在代码最上面声明 window = global,可解决该报错
七、webpack打包后扣代码:只扣需要的加载器代码
1.之前分析加密函数 o = t(1395),在控制台上打印 t.m 上找到1395,点击蓝色部分就能找到该函数位置
2.把 1395 函数拷贝到 webpackload.js
3.执行 load(1395),点击运行文件会报以下错误,这个错误是因为某个函数未找到,在 f 函数把 t 打印出来,点击运行文件,会发现 1601 是未找到的加载器,然后重复步骤 1 找到 1601 函数,直到无报错,说明加载器已经全部扣出
八、webpack打包后扣代码:全扣,全扣代码量大,一般适用于需要加载器函数特别多的时候,比如十几二十个的
1.之前分析加密函数 o = t(1395),在控制台上打印 t.m 上找到1395,点击蓝色部分就能找到该函数位置
2.建个临时的js文件,把该文件所有代码拷贝到该文件
3.把1388、1395、1601一起拷贝到 webpackload.js,该文件代码少,全扣也没问题,有的文件有几万行代码,如果全扣,电脑可能会卡死,所以没必要全扣的时候别全扣,实在不行再考虑全扣
九、验证加密
1.补全 pinduoduo.js代码,点击运行 pinduoduo.js,无报错说明代码加密成功,然后注释掉文件内的测试代码
2.修改 pinduoduo.py,并运行,会发现接口返回的不是 “账号和密码不匹配” 而是 “账号异常,无法登录”,说明还有其他的加密参数
3.点击登录重新发送请求,鼠标右击请求找到Copy>Copy as cUrl(cmd),打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码,分别复制生成的header、cookie 和之前Copy出来的代码做对比,会发现只有header里面的 anti-content 是不一样的,说明该参数也是加密参数
4.把最新的 anti-content 拷贝到 pinduoduo.py,再运行该文件,会报 “账号和密码不匹配”,说明代码已扣成功,本文主要说的是扣webpack打包后的代码,就不扣 anti-content 加密代码了,使用关键字搜索 anti-content 会找到 anti-content 生成位置,主要生成函数也是加载器中的 264,有兴趣的可以自己试下