变成AST之后,还得带一段执行AST的代码,也就是AST的解释器。
当然,这里是简单的仅解析异或运算的解释器:(AST解释器的雏形)
function ast(node) {
if(node.type == "File"){
return ast_excute(node.program);
}
if(node.type == "Program"){
return ast_excute(node.body[0]);
}
if(node.type == "ExpressionStatement"){
return ast_excute(node.expression);
}
if(node.type == "BinaryExpression"){
var left_value = node.left.value;
var right_value = node.right.value;
var operator = node.operator;
if(operator == "^"){
return left_value ^ right_value;
}
}
}
此操作,等于将异或运算代码编译为AST,再带了一个AST解释器运行它。
第六种写法eval的使用。
直接的写法:
var a = eval(1);
console.log(a);
Eval的变形写法:
var a = window[(14).toString(32) (31).toString(32) (10).toString(32) (21).toString(32)](1); console.log(a);
对方法四的代码做升级,也可加入eval:
var a = function (s, h) {
return eval(String.fromCharCode(115, 32, 94, 32, 104));
}(678405, 678404);
console.log(a);
即:把return s ^ h用eval进行了包裹,并用formCharCode做了加密。
第七种写法:构造函数的使用。
与eval有些类似,但eval做为高风险函数,容易被检测或禁用,因此使用构造函数实现代码运行,与eval效果类似。
原始形态:
var a = [].constructor.constructor("return 1")();
console.log(a);