欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > AST反混淆

AST反混淆

2025/7/5 13:19:32 来源:https://blog.csdn.net/qq_41741971/article/details/143699427  浏览:    关键词:AST反混淆

合并表达式方式一

这种方式不会计算替换含有变量的表达式

function evaluateAST(node) {switch (node.type) {case 'Identifier':return falsecase 'Literal': // 处理字面量节点return node.value;case 'NumericLiteral': // 处理字面量节点return node.value;case 'StringLiteral': // 处理字面量节点return node.value;case 'UnaryExpression':return parseInt(node.operator+node.argument.value)case 'BinaryExpression': // 处理二元运算符节点const left = evaluateAST(node.left);const right = evaluateAST(node.right);if(!left || !right) {return '--continue--'}switch (node.operator) {case '+':return left + right;case '-':return left - right;case '*':return left * right;case '/':return left / right;case '%':return left % right;case '<':return left < right;case '>':return left > right;default:throw new Error(`Unsupported operator: ${node.operator}`);}default:throw new Error(`Unsupported node type: ${node.type}`);}
}function calc_be(path){var paren_node = path.nodelet result = evaluateAST(paren_node)console.log(result)if (result !== '--continue--'){let type_// 创建一个新的字面量节点替换掉原来的节点if(typeof result === 'string'){type_ = 'StringLiteral'}else if(typeof result === 'number'){type_ = 'NumericLiteral'}else if(typeof result === 'boolean'){type_ = 'BooleanLiteral'}const newNode = {type: type_,value: result,raw: result.toString()}// 替换当前节点path.replaceWith(newNode)}
}

合并表达式方式二

这种方式会尝试计算替换所有能计算出结果的表达式;

  1. path.evaluate() 是计算表达式的值,会返回两个值,当第一个值为true的时候,第二个值就是计算的结果

  2. path.replaceInline() 用一个或多个节点替换另一个节点,在进行节点的替换时,必须先构造节点才可以替换;path.replaceWith()用一个节点替换另一个节点;path.replaceWithMultiple()用多个节点替换另一个节点;

  3. types.valueToNode() 为创建构造节点,将字面量常量值转换为node节点

var merge_expression = {"BinaryExpression|CallExpression|ConditionalExpression"(path){  const {confident, value} = path.evaluate();confident && path.replaceInline(types.valueToNode(value))}
}

解Unicode、Hex、合并表达式、平坦流

ast解混淆主代码
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 types = require("@babel/types");// 删除节点中的extra属性(二进制、Unicode等编码 -> utf-8)
function rm_unicode_hex(path) {// console.log(path)let node = path.node;if (node.extra === undefined)return;delete node.extra;
}
// 计算二元计算
function calc_be(path){const {confident, value} = path.evaluate();console.log(confident, value)confident && path.replaceInline(types.valueToNode(value))
}// 控制流平坦化
function replace_WhileStatement(path) {cur_node = path.node;if(cur_node.body.body[0].type === "SwitchStatement"){var swithStm = cur_node.body.body[0];// 找到path节点的前兄弟节点,即 _0x1eb1f3所在的节点,然后获取 _0x1eb1f3数组var arrNodePath = path.getAllPrevSiblings()[0]var arrValue = arrNodePath.node.declarations[0].init.callee.object.value.split('|');// SwitchCase节点遍历并临时存储到一个数组var caseList = swithStm.cases;var temp_arr_switch_case = [];arrValue.map(targetIdx => {var targetBody = caseList[targetIdx].consequent;// 如果最后一个节点是,则删除ContinueStatement块(continue语句)if (types.isContinueStatement(targetBody[targetBody.length - 1])){targetBody.pop();}temp_arr_switch_case = temp_arr_switch_case.concat(targetBody)});// 多个节点替换一个节点的话使用replaceWithMultiple方法path.replaceWithMultiple(temp_arr_switch_case);}
}// 需要解码的文件位置
let encode_file = "./decode_js/test.js"
// 解码后的文件位置
let decode_file = "./encode_js/test.js"
// 读取需要解码的js文件, 注意文件编码为utf-8格式
let jscode = fs.readFileSync(encode_file, {encoding: "utf-8"});
// 将js代码修转成AST语法树
let ast = parser.parse(jscode);
// AST结构修改逻辑
const visitor = {StringLiteral: {enter: [rm_unicode_hex]},NumericLiteral: {enter: [rm_unicode_hex]},"BinaryExpression|CallExpression|ConditionalExpression": {enter: [calc_be]},WhileStatement: {enter: [replace_WhileStatement]}
}
// 遍历语法树节点,调用修改函数
traverse(ast, visitor);// 将ast转成js代码,{jsescOption: {"minimal": true}} unicode -> 中文
let {code} = generator(ast, opts = {jsescOption: {"minimal": true}});
// 将js代码保存到文件
fs.writeFile(decode_file, code, (err) => {});
需要解混淆的JS代码

function i(y) {var O = '3|0|4|2|5|1|6'['split']('|'), K = -0x2705 + -0x4 * 0x233 + -0x2fd1 * -0x1;while (!![]) {switch (O[K++]) {case '0':J['GJoEW'](y, ArrayBuffer) && (y = new Uint8Array(y));continue;case '1':while (J['cRGWF'](o, d0)) {d1 = y[o++],z += String['fromCharCode'](d1);}continue;case '2':d0 = y['length'];continue;case '3':var z, o, d0, d1;continue;case '4':z = '';continue;case '5':o = 0x151c + 0xb * 0x1eb + -0x2a35 * 0x1;continue;case '6':return z;}break;}
}
解混淆后的代码
function i(y) {var O = "3|0|4|2|5|1|6"["split"]("|"),K = 0;var z, o, d0, d1;J["GJoEW"](y, ArrayBuffer) && (y = new Uint8Array(y));z = "";d0 = y["length"];o = 0;while (J["cRGWF"](o, d0)) {d1 = y[o++], z += String["fromCharCode"](d1);}return z;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词