这篇是理论实战噻,刚学来的热乎着,速度与大家分享一下,简单的webpack的解决方法,用简单的理论,结合实战来理解不嵌套的webpack如何逆向。
01
通过某翼云认识webpack
网址:
aHR0cHM6Ly9tLmN0eXVuLmNuL3dhcC9tYWluL2F1dGgvbG9naW4=
某翼云是一个不嵌套的webpack属于简单的webpack,所以咱一起来学习一下这个webpack是如何执行的。
01
找到加密点的位置。
我们可以看到,在password参数的加密中是通过嵌套了了多个Object(u[“?”])来提供encodeURI输出结果的,但Object()是一个简单混淆,可以直接去掉不管,u[‘c’](xx,xx)这样我们就可以知道,这是一个方法。
02
发现webpack的特性一
理解:a函数就是一个加载器,当加载a方法的某个参数时,该方法就被初始化了。
o = (a("6762"),
a("2fdb"),
a("b54a"),
a("456d"),
a("ceaa"),
a("b2fb"))
, n = a.n(o)
, i = (a("96cf"),
a("3b8d"))
, c = (a("ac6a"),
a("cadf"),
a("a481"),
a("7f7f"),
a("aba2d"))
诸如此类的调用同一个方法通过传入不同参数来返回不同结果的就是webpack的特性一。
03
发现webpack多文件打包特性
文件头上有两个特征:
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["login"]
特征一:
window["webpackJsonp"]
window中的webpackJsonp就是最终打包出来的多个子文件的信息。
特征二:
.push(xx)
向window.webpackJsonp数组中追加初始化完成的的方法数据用于缓存。
04
加载器详解
加载器只出现在主文件里,不会出现在子文件里。
我们可以通过下断去看主文件位置。
进入方法查看加载器如何运行的。
这个就是这个主文件所在的位置,也就是webpack的加载器,也是主文件最关键的东西。
function u(n) {
// 如果缓存存在
if (a[n])
return a[n].exports; // 就执行导出函数
// 如果缓存不存在就初始化
var t = a[n] = {
i: n,
l: !1, // 用于二次判断 缓存是否被加载
exports: {} // 初始化一个对象,在init后加入到这个对象中
};
// Function.prototype.call() === 所有函数
// 参数解释:t.exports === this
// u === 加载器 function u(n){}的u
return e[n].call(t.exports, t, t.exports, u),
t.l = !0, //
t.exports //返回创建的新对象
}
05
init在webpack中的作用
– 网页文件加载
– 接口的调用
– 检测环境
– 页面更改、渲染
init初始化方法在webpack中永远在加载器最后一行。
在抠代码时一定要将其删掉,即自己调用加载器执行一次检测性代码。
i.push([0, "chunk-vendors"]),
t() // 比如这个
06
逻辑概述
这里讲一下webpack的不嵌套多文件打包的抠代码的解决逻辑。
代码执行逻辑是先通过一系列相同的方法通过不同的参数来调用不同的函数。如:l(“add”) == add:function(){}
调用不同的函数就需要通过主文件中的加载器去进行加载。加载器默认有缓存,当执行过的数据就会被存入缓存中,提供方法的调用。
子文件的方法在被加载完成后可以看成被默认加在主文件传入的对象或数组中,作为一个整体方法。
主文件中核心点就是加载器执行导出函数,还有一个init初始化作为一个环境检测等的初始化,就会在代码最后一行对加载器内容进行一个初始化。
02
浅抠代码一
01
将文件补成一个JS
由于都是自执行函数所以可以都直接全部抠下来。
先扣有加载器的主函数。
将断点打到password参数加密的自执行的最头部,这样我们就知道,环境中的所有子文件。
按顺序将环境中的的子文件全部抠下来,往后追加即可。
我们直接在node环境中构造一下。
首先,抠下主文件。
发现运行报错。
补一个window
将加载器方法置为全局方法:
将方法最后两行的初始化代码去掉改成全局的的设置。
我们在e传入的对象中加入一段我们自己的代码测试一下是否可以执行。
发现是可以获取到的,原代码中是通过7f6d这个参数获取的方法。
我们去测试一下是否已经存在了。
报错,Function.prototype.call()方法不存在,怎么可能呢?就是说明这个方法还没被定义过来。
那就把子文件全抠下来吧。
第一个子文件,全抠,运行测试一下环境。
报错了,那就去改改。
这个直接改到能运行不就好了,后面这串判断直接改true
接着测试运行。
发现还是报错,去改一下。
直接删&&后面的判断改true走前面方法。
接着测试运行。
报错啊。
判断里这个对象里没有,方法没执行很正常。
直接删掉&& xx.toLowerCase()就好了,接着测试。
这个里面不存在indexOf()方法只是个判断,我们就不需要他这个来判断是啥环境的,直接删只要是Q.indexOf()就删,别删多了,注意括号。
删完长这样,接着测试。
删就完事了。
长这样,接着测试。
事件监听,我们这里脚本没啥要监听的,直接删掉这段。
一般检测跨域问题的,就是网页来源,去网站上抠来替换。
再测试一下就可以运行了。
ok,那剩下两个都不用抠了,已经有了,我们测试一下里面是否已经满足我们密码password加密的需求了。
直接照搬出原结果。
03
浅抠代码二
我们知道webpack是通过将方法存入缓存中,来调取执行的,那我们把所有的方法都加到主文件的e对象里面不就也可以直接调取,来试一下。
这里用的上文已经配好的环境代码,直接进行一下修改。
我们看到这个是子文件的代码。
我们取出所有的方法。
这个直接删掉。
将扣下来的方法直接粘到主函数的e里。
我们测试运行一下。
结果一致。
04
利用特性自动补代码
我们知道,一个自定义的函数方法+””就可以是一个字符串。
我们在原代码中加一个加载器拼接一下。
这不就是我们调用这个方法所需要的方法集嘛,那我们将我们要的方法打印出来不就好了。
用e[n]将我们要的方法打印出来了,我们要一个直接可以复制黏贴来的结果,那咋弄嘞。
拼接不就好了。
可以看到我们这里按我们需要的结果拼接字符串,我们看看我们要拼接的效果是怎么样子的。
我们打印输出看看。
发现这个对象已经全部拼接好了,发现打印结果是我们要的。
我们再给他按字符串获取,放到文件中格式化一下替换掉”\n”,粘贴进去。
最终结果是简化后的方案2
05
完整代码
完整代码于交流群中打包,如有需要学习之处可以前往下载,有其他不足之处可以予以指正。
喜欢就点个关注一起进步吧
此文章仅做学习之用,请勿做违法违纪之事。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/218412.html