let visitor = {
BinaryExpression(path){
let left = path.node.left;
let right = path.node.right;
if(t.isNumericLiteral(left) && t.isNumericLiteral(right)){
let {confident, value} = path.evaluate();
confident && path.replaceWith(t.valueToNode(value));
}
}
}
还原eval加密
遍历CallExpression节点,判断callee.name是否为eval
若eval的参数就是一个字符串,直接使用types组件的identifier让参数变成代码
若eval的参数是个表达式,提取其arguments[0]并通过eval计算出来
最后替换整个CallExpression节点
let visitor = {
CallExpression(path){
if(path.node.callee.name != 'eval') return;
let arguments = path.node.arguments;
let code = generator(arguments[0]).code;
if(t.isStringLiteral(arguments[0])){
path.replaceWith(t.identifier(code));
} else {
path.replaceWith(t.identifier(eval(code)));
}
}
}
上面的解密函数是js内置的atob,若解密函数自定义的,得扣进代码中
还原unicode和hex字符串加密
JS中字符串可以是unicode或hex形式,标识符可以用unicode表示
Unicode字符串加密
function unicodeEnc(str){
var value = '';
for(var i = 0;i < str.length;i++){
value += "\\u" + ("0000" + parseInt(str.charCodeAt(i)).toString(16)).substr(-4);
}
return value;
}
let idVisitor = {
Identifier(path){
path.replaceWith(t.identifier(unicodeEnc(path.node.name)));
path.skip();
}
}
let strVisitor = {
StringLiteral(path){
path.replaceWith(t.stringLiteral(unicodeEnc(path.node.value)));
path.skip();
}
}
traverse(ast, idVisitor);
traverse(ast, strVisitor);
let code = generator(ast).code;
code = code.replace(/\\\\u/g,'\\u');