前言
webpack打包是前端js模块化压缩打包常用的手段,它的目的不是为了用来进行混淆,但对于想要逆向js的人而言,无疑又是一种混淆,把很多简单的函数形式变复杂了。
webpack特征
! function (t) {
function e(s) {
if (i[s]) return i[s].exports;
var n = i[s] = {
exports: {},
id: s,
loaded: !1
};
return t[s].call(n.exports, n, n.exports, e), n.loaded = !0, n.exports
}
var i = {};
}({})
webpack标记
看到类似 n(123)、n["xxx"],你差不多就知道这是调用了webpack打包的js模块代码。
webpack标记
1. 确定加密的函数。
这个其实和常规的js解密差不多,你首先得知道用哪个函数加密。如图,你找到了
类似你会找到 Object(o.a)(t) 这样与常规的函数长得不像,其实 Object(o.a)就类似于 MD5这个函数名,类推,如果是 MD5(t),你就不慌了?那么就把o.a怎么来就行了,一般就在这个Object(o.a)的上方,就会有类似var o = n("MuMZ");的定义出来,不然怎么调用呢?而看到n("MuMZ"),是不是就知道 调用了webpack打包的js模块代码。
2. 确定分发器。
分发器看上去很高端,简而言之,这是一个函数就是总开关,所有的内容都需要从它这儿调用后形成有效的功能,怎么找到这个分发器?
首先,你需要在n("MuMZ")这个地方下断,然后重新刷新页面,因为webpack这类的模块会在页面开始的时候就加载,所以需要重新刷新才能断点成功。
然后从断点中跟进去就能找到分发器的位置,同时也确定分发器函数的名称,比如function f(n){……}。
3. 确定调用的模块。
根据刚刚的操作,我们找到分发器,其实你就确定了n("MuMZ")这个函数中n()函数,那么"MuMZ"是什么呢?就是模块名,真正这个代码调用的函数的函数名,通过函数名就找到了真正的调用函数。
举个例子,比如是一个MD5加密的函数,其实 "MuMZ"对应的可能就是一个 常见形式的函数MD5()的MD5这个名字。找到MD5不就等于找到了MD5()?所以,怎么找到这个函数,你只需要在全局搜索 "MuMZ" ,如果看到 "MuMZ": function(t, e) {……} 那就是调用的模块,直接拷贝下来。[注:如果你js基础深厚,其实有些加密函数简单、易识别的,完全可以直接改写实现。]
4. 调用。
调用就是我们要运行 n("MuMZ") ,那么前面提到的var o = n("MuMZ")中o就有功能了,然后就能实现o.a,实现了o.a也就等于运行了所谓的MD5函数。
怎么调用?
【基本套路】定义一个全局变量,如 eFunc,而后在模块加载器前面应用语句 eFunc = e,再把调用模块放到对应位置上,调用eFunc()
var eFunc;//创建一个全局变量,供调用之用
!function (t) {
function e(s) {
if (i[s])
return i[s].exports;
var n = i[s] = {
exports: {},
id: s,
loaded: !1
};
return t[s].call(n.exports, n, n.exports, e),
n.loaded = !0,
n.exports
}
var i = {};
eFunc = e//全局调用
}(
{
"MuMZ": function(t, e) {……} //调用模块
}
)
var o=eFunc("MuMZ")// 类似 var o = n("MuMZ")
结语
我对webpack改写也就初步了解,我希望用我理解的、通俗易懂的形式给大家介绍,希望给大家一点启发。其实所谓的webpack改写和传统的JS改写一样,即使找到加密内容,实际调用可能还会出现这样或那样的问题,调用还是不行,还需要扎实的JS方面基础。最后鸣谢:从前重前、K哥爬虫。