使用Babel操作AST抽象语法树混淆JS代码
1.变量名混淆
2.数组访问方式混淆
3.数组混淆
4.数组乱序
const parser = require("@babel/parser");
const traverse=require("@babel/traverse").default;
const t=require("@babel/types");
const generator=require("@babel/generator").default;
const fs=require("fs");
const jscode=fs.readFileSync("./ASTTestDemo.js",{
encoding:"utf-8"
})
//console.log(jscode);
let newAst=parser.parse("");
newAst.program.body.push(t.expressionStatement(t.stringLiteral("__shift__")));
// let {code}=generator(newAst);
// console.log(code);
traverse(newAst,{
StringLiteral(path){
if(path.node.value=="__shift__"){
path.replaceWithSourceString('!function(myArr,num){var lx=function(num){while(--num){myArr.push(myArr.shift());}};lx(++num);}(arr,0x12)');
path.stop();
}
}
});
let ast=parser.parse(jscode);
var newArr=[];
traverse(ast,{
//匹配函数
FunctionDeclaration(path){
//函数内部修改
path.traverse({
Identifier(innerPath){
//作用域分为全局和局部
path.scope.rename(innerPath.node.name=path.scope.generateUid("_0x2594"));
}
})
},
//匹配数组引用方式
MemberExpression(path){
path.node.computed=true;
if(t.isIdentifier(path.node.property)){
var name=path.node.property.name;
path.node.property=t.stringLiteral(name);
}
},
StringLiteral(path){
var position=newArr.indexOf(path.node.value);
var lengths=position;
if(position==-1){
var le=newArr.push(path.node.value);
lengths=le-1;
}
console.log(path.parent.type);
path.parent.type=="ReturnStatement" && (path.parent.argument=t.memberExpression(t.identifier("arr"),t.numericLiteral(lengths),true));
path.parent.type=="AssignmentExpression" && (path.parent.property=t.memberExpression(t.identifier("arr"),t.numericLiteral(lengths),true));
path.parent.type=="MemberExpression" && (path.parent.property=t.memberExpression(t.identifier("arr"),t.numericLiteral(lengths),true));
//path.parent.type=="ObjectProperty" && (path.parent.key=t.memberExpression(t.identifier("arr"),t.numericLiteral(lengths),true));
}
})
var resultArr=newArr.map(function(v){
return t.stringLiteral(v);
});
(function(myArr,num){
var lx=function(num){
while(--num){
myArr.unshift(myArr.pop());
}
};
lx(++num);
}(resultArr,0x12));
newAst.program.body.unshift(t.variableDeclaration("var",[t.variableDeclarator(t.identifier("arr"),t.arrayExpression(resultArr))]));
let code1=generator(newAst).code;
let code2=generator(ast).code;
//console.log(code);
fs.writeFile("./demo.js",code1+code2,(err)=>{});
原先的代码:
var obj={"name":1};
function test(a,b){
return "hello";
}
function test2(a,b){
return "world";
}
obj.name="losenine";
obj[age]=20;
混淆后的代码:
var arr = ["world", "losenine", "age", "name", "hello"];
!function (myArr, num) {
var lx = function (num) {
while (--num) {
myArr.push(myArr.shift());
}
};
lx(++num);
}(arr, 0x12);var obj = {
"name": 1
};
function _0x(_0x2, _0x3) {
return arr[1];
}
function _0x4(_0x5, _0x6) {
return arr[2];
}
obj[arr[0]] = "losenine";
obj[arr[4]] = 20;