原文地址:https://zhuoyue360.com/jsnx/109.html
AST入门与实战(一):基于babel库的js反混淆模板的实践 : https://www.zhuoyue360.com/jsnx/106.html
还记的上一篇AST的文章,我们把函数调用简单的给替换了一下,但是其最终的效果并不完美.
哪里不完美呢? 有如下几点:
开头的匿名函数
,_0x4f09
,_0x49be
函数已经没用,我们应该删除它 (我认为手动删除就好了)- 在代码中,存在不少的无效代码,例如
var _0x49beab = _0x49be();
我也也应该删除它.
(function (_0x42555b, _0x288c31) {
var _0x2e2c7a = _0x4f09,
_0x264ee4 = _0x42555b();
while (!![]) {
try {
var _0x54167b = parseInt(_0x2e2c7a(262)) / 1 * (-parseInt(_0x2e2c7a(266)) / 2) + -parseInt(_0x2e2c7a(265)) / 3 * (parseInt(_0x2e2c7a(267)) / 4) + -parseInt(_0x2e2c7a(270)) / 5 * (parseInt(_0x2e2c7a(273)) / 6) + -parseInt(_0x2e2c7a(272)) / 7 + parseInt(_0x2e2c7a(268)) / 8 + parseInt(_0x2e2c7a(269)) / 9 * (parseInt(_0x2e2c7a(271)) / 10) + parseInt(_0x2e2c7a(264)) / 11;
if (_0x54167b === _0x288c31) break;else _0x264ee4['push'](_0x264ee4['shift']());
} catch (_0x1b893f) {
_0x264ee4['push'](_0x264ee4['shift']());
}
}
})(_0x49be, 769884);
function hi() {
console['log']('Hello,zhuoyue360.com');
}
function _0x4f09(_0xd05c9f, _0x352733) {
var _0x49beab = _0x49be();
return _0x4f09 = function (_0x4f0967, _0x3191e8) {
_0x4f0967 = _0x4f0967 - 261;
var _0x4f9c38 = _0x49beab[_0x4f0967];
return _0x4f9c38;
}, _0x4f09(_0xd05c9f, _0x352733);
}
function _0x49be() {
var _0x13bd5d = ['12032256MLzLfN', '1251zScKBQ', '25cNqVzl', '270jbEuTF', '5872188ZkfPRj', '1062282TyhTBn', 'Hello,zhuoyue360.com', '1kakbhL', 'log', '11816574EYEQFr', '66741ytXvQy', '42550jdDgVb', '12QEFacN'];
_0x49be = function () {
return _0x13bd5d;
};
return _0x49be();
}
function h3i() {
var _0x2b1dcb = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
var _0xa95bed = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
var _0xb505a4 = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
hi();
所以,我们理想状态下的代码应该是:
function hi() {
console['log']('Hello,zhuoyue360.com');
}
function h3i() {
var _0x2b1dcb = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
var _0xa95bed = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
var _0xb505a4 = _0x4f09;
console["log"]("Hello,zhuoyue360.com");
}
hi();
我们可以通过枚举VariableDeclarator
来实现.
思路如下:
- 枚举
VariableDeclarator
- 通过
scope.getBinding
来获取调用的次数 - 如果次数为0,删除它的父节点(也就是那一整行代码)
VariableDeclaration
实现代码如下:
const deleteUnUseVar = {
VariableDeclarator(path){
let {node,scope} = path;
// 我们拿到变量名称, 寻找其binding的次数. 如果binding的长度为0的话,证明没用过,删除即可.
const {id,init} = node;
console.log(id.name)
const bindings = scope.getBinding(id.name);
if (!bindings || bindings.constantViolations.length > 0){
// 这个变量被用了.
return;
}
// 这个变量没任何引用.
path.parentPath.remove();
}
}
traverse(ast, deleteUnUseVar);
最终的展示效果如下:
解密函数我手动删除了, 感觉好像没多大必要写自动的. 毕竟只是学习~
function hi() {
console['log']('Hello,zhuoyue360.com');
}
function h3i() {
console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
console["log"]("Hello,zhuoyue360.com");
}
hi();