例子
// 还原前 eval(atob("c3RyID0gc3RyWyJyZXBsYWNlIl0oL2RkfERELywgdGhpc1siZ2V0RGF0ZSJdKCkgPiA5ID8gdGhpc1siZ2V0RGF0ZSJdKClbInRvU3RyaW5nIl0oKSA6ICcwJyArIHRoaXNbImdldERhdGUiXSgpKTs=")); eval(String.fromCharCode(115, 116, 114, 32, 61, 32, 115, 116, 114, 91, 34, 114, 101, 112, 108, 97, 99, 101, 34, 93, 40, 47, 121, 121, 121, 121, 124, 89, 89, 89, 89, 47, 44, 32, 116, 104, 105, 115, 91, 34, 103, 101, 116, 70, 117, 108, 108, 89, 101, 97, 114, 34, 93, 40, 41, 41, 59)); // 还原后 str = str["replace"](/dd|DD/, this["getDate"]() > 9 ? this["getDate"]()["toString"]() : '0' + this["getDate"]());; str = str["replace"](/yyyy|YYYY/, this["getFullYear"]());;
还原
这两种可以
同时处理
,因为都是eval 执行
,所以遍历 调用表达式
,判断 eval
,是 就取出 eval 的参数
,判断节点类型
,如果是StringLiteral
说明就是一串代码字符串
,直接替换
,如果是其他类型
,直接使用node
的eval 执行
,然后替换节点
。
是否通用:是
特别说明:如果遇到 解密字符串
的是自写的函数
,需要先
找到 解密函数
// node atob var s = new Buffer.from("待解码的字符", "base64").toString("binary") // node btoa var s = new Buffer.from("待编码的字符", "binary").toString("base64")
// 还原代码 function atob(code) { return new Buffer.from(code, "base64").toString("binary") } // eval 还原 traverse(ast, { CallExpression(path) { // 判断 特征 if (path.node.callee.name !== 'eval') return; let arguments = path.node.arguments // eval 的参数 let code = generator(arguments[0]).code if (type.isStringLiteral(arguments)) { path.replaceWith(type.identifier(code)) } else { path.replaceWith(type.identifier(eval(code))) // node 的 eval } } })
版权声明:《 【AST 还原】二、还原代码加密(base64) 及 ASCII码混淆 》为明妃原创文章,转载请注明出处!
最后编辑:2022-4-21 10:04:16