代码
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const generator = require("@babel/generator").default;
let origin_code = `
function _0x506bbd(v){
const a= !![]
console.log(a);
return v.length
}
console.log(_0x506bbd(‘\x69\x6e\x64\u0435\x78\x4f\x66‘));
`
let ast = parser.parse(origin_code);
pre_ast = ast.program.body.slice(0, 1)
const gen = generator(ast, {
// 禁止自动格式化(针对反调试)
compact: true
})
eval(gen.code)
function toSource(_ast) {
let {code} = generator(_ast, {
// 是否格式化
compact: false,
jsescOption: {
// 自动转义
minimal: true,
}
});
return code.replace(/!!\[\]/g, ‘true‘).replace(/!\[\]/g, ‘false‘)
}
function getvalue(path) {
const node = path.node
if (t.isStringLiteral(node)) {
if (node && node.exact) {
delete path.node.exact
}
} else if (t.isCallExpression(node)) {
const {callee} = path.node;
if (t.isMemberExpression(callee) &&
callee.object.name === "console" &&
callee.property.name === "log") {
node.arguments.map(item => {
if (t.isCallExpression(item)) {
let _value = item.arguments
let _key = item.callee.name
const func = eval(_key)
let new_value = func(..._value.map(v => v.value))
let value_type = Object.prototype.toString.call(new_value)
let new_node;
if (value_type === "[object Number]") {
new_node = t.NumericLiteral(new_value)
} else if (value_type === "[object String]") {
new_node = t.stringLiteral(new_value)
}
path.node.arguments[0] = new_node
}
})
}
}
}
function traverse_ast(ast, opts) {
traverse(ast, opts);
return ast
}
let step1_ast = traverse_ast(ast, {StringLiteral: getvalue})
let step2_ast = traverse_ast(step1_ast, {CallExpression: getvalue})
let new_code = toSource(step2_ast)
console.log("before: =============")
console.log(origin_code)
console.log("after: =============")
console.log(new_code)
目标结果:
true
7
true
before: =============
function _0x506bbd(v){
const a= !![]
console.log(a);
return v.length
}
console.log(_0x506bbd(‘indеxOf‘));
after: =============
function _0x506bbd(v) {
const a = true;
console.log(a);
return v.length;
}