首页 > 编程知识 正文

ast偏低什么意思(ast反混淆进阶--花指令处理)

时间:2023-05-03 07:45:58 阅读:123573 作者:4534

目的:文字花命令和函数花命令处理前: var _0x b 28 de8={ ' ABCD ' : function (_0x 2293 f, _0x5a165e ) return_0x22293f==_0x55a1693f ) _0x5a165e ) )的(dbca ) :功能(_0x FBA c1e,_0x 23444 、' AAA':function(_0x57e640 ) { return _0x57e640;' bbb': 'eee'} '; varaa=_0x b 28 de8[ ' ABCD ' ] (123,456; varbb=_0xb28de8['dbca'](BCD,11,22 ); varcc=_0xb28de8['AAA'](dcb; 处理后: var aa=123==456; varbb=BCD (11,22 ); var cc=dcb (; demo.js var _0x b 28 de8={ ' ABCD ' : function (_0x 22293 f,_0x5a165e ) { return _0x22293f==_0x5a165e;(dbca ) :function(_0xFBAC1e、_0x23462f、_0x556555 ) return_0xFBAC1e ) _0x23462f、_0x 55656555555555555555306;' AAA':function(_0x57e640 ) { return _0x57e640;' bbb': 'eee'} '; varaa=_0x b 28 de8[ ' ABCD ' ] (123,456; varbb=_0xb28de8['dbca'](BCD,11,22 ); varcc=_0xb28de8['AAA'](dcb; functionDD((var_0xb28de8=) /本地变量同名验证' bbb': 'eee45475' } ); var dd=_0xb28de8['bbb']; }var ddf=_0xb28de8['bbb']; //局部变量与全局变量同名,验证function dd (()//全局变量在函数主体中是否可用var dd=_0xb28de8['bbb']; }functionkk(a ) )//传值验证var ss=_0xb28de8[a]; } dec _ main.jscons TFS=require (' fs ); //文件读写const parse=require (' @ babel/parser ' ); //astconsttraverse=require (' @ babel/traverse ' ).default; //遍历节点constt=require('@Babel/types ); //类型const generator=require (@ babel/generator ) ).default; //ast被解析为代码//js文件constjscode=fs.readfilesync ()./demo.js )和{ encoding: 'utf-8' }。 letast=parse.parse(jscode; //js是替换astfunctioncalltostr(path )//对象的var node=path.node; //获取路径节点if (! 如果不是xxdxy(node.init ) )//对象表达式,则退出返回; varobjpropertieslist=node.init.properties; //取得对象内所有属性if (objpropertieslist.length==0) )//如果对象内的属性列表为0,则结束返回; var objName=node.id.name; //对象名称let scope=path.scope; 获取//路径的范围let绑定=scope.get绑定(objname ); //if (! 绑定|||绑定. constant violations.length0) {//检查此变量的值是否已更改---完整性检查返回; } let paths=binding.reference paths; //绑定引用的路径let paths_sums=0; //路径计数objpropertieslist.foreach (prop={ varkey=prop.key.value; //属性名称if (平整画板(prop.value ) ) /属性值为函数表达式) varretstmt=prop.value.body.body (0); 定位到返回语句路径.scope.traverse(path.scope.block, { CallExpression: function (_path) {//调用表达式匹配 let _path_binding = _path.scope.getBinding(objName);//当前作用域获取绑定 if(_path_binding!=binding)return;//两者绑定对比 if (!清秀的白昼(_path.node.callee))//成员表达式判定 return; var _node = _path.node.callee;//回调函数节点 if (!ssdzx(_node.object) || _node.object.name !== objName)//非标识符检测||节点对象名全等验证 return; if (!(ssdnm(_node.property) || ssdzx(_node.property)))//节点属性非可迭代字符验证||节点属性标识符验证 return; if (!(_node.property.value == key || _node.property.name == key))//节点属性值与名称等于指定值验证 return; if (!ssdnm(_node.property) || _node.property.value != key)//节点属性可迭代字符验证与节点属性值与指定值等于验证 return; var args = _path.node.arguments;//获取节点的参数 // 二元运算 if (cqddy(retStmt.argument) && args.length === 2)//二进制表达式判定且参数为两个 { _path.replaceWith(t.binaryExpression(retStmt.argument.operator, args[0], args[1]));//二进制表达式替换当前节点 } // 逻辑运算 else if (辛勤的糖豆(retStmt.argument) && args.length == 2)//与二元运算一样 { _path.replaceWith(t.logicalExpression(retStmt.argument.operator, args[0], args[1])); } // 函数调用 else if (老实的巨人(retStmt.argument) && ssdzx(retStmt.argument.callee))//回调函数表达式判定及回调参数部分判定 { _path.replaceWith(t.callExpression(args[0], args.slice(1))) } paths_sums+=1;//删除计数标志 } }) } else if (ssdnm(prop.value)) {//属性值为可迭代字符类型 var retStmt = prop.value.value;//属性值的值即A:B中的B部分 path.scope.traverse(path.scope.block, { MemberExpression: function (_path) {//成员表达式 let _path_binding = _path.scope.getBinding(objName);//当前作用域获取绑定 if(_path_binding!=binding)return;//两者绑定对比 var _node = _path.node; if (!ssdzx(_node.object) || _node.object.name !== objName)//节点对象标识符验证|节点对象名验证 return; if (!(ssdnm(_node.property) || ssdzx(_node.property)))//节点属性可迭代字符验证|标识符验证 return; if (!(_node.property.value == key || _node.property.name == key))//节点属性值与名称等于指定值验证 return; if (!ssdnm(_node.property) || _node.property.value != key)//节点属性可迭代字符判定|节点属性值等于指定值验证 return; _path.replaceWith(t.stringLiteral(retStmt))//节点替换 paths_sums+=1;//删除计数标志 } }) } }); if (paths_sums == paths.length) {//若绑定的每个路径都已处理 ,则移除当前路径 path.remove();//删除路径 }}traverse(ast, {VariableDeclarator: {exit: [callToStr]},}); // 对象替换let {code} = generator(ast,opts = {jsescOption:{"minimal":true}})//文件保存fs.writeFile('./demoNew.js', code, (err) => {}); demoNew.jsvar _0xb28de8 = { "abcd": function (_0x22293f, _0x5a165e) { return _0x22293f == _0x5a165e; }, "dbca": function (_0xfbac1e, _0x23462f, _0x556555) { return _0xfbac1e(_0x23462f, _0x556555); }, "aaa": function (_0x57e640) { return _0x57e640(); }, "bbb": "eee"};//由于后面kk函数体传参数使用该字典对象,参数未知,保留该字典对象var aa = 123 == 456;var bb = bcd(11, 22);var cc = dcb();function dd() { var dd = "eee45475";}var ddf = "eee"; //局部变量与全局变量同名验证function dd() { //全局变量在函数体是否可用验证 var dd = "eee";}function kk(a) { //传值验证 var ss = _0xb28de8[a];} 优化及说明:一.对于所有的删除操作都采取影响最小的操作1.对于局部变量与全局变量同名情况var _0xb28de8 = {...};function dd() { var _0xb28de8 = {//局部变量同名验证 "bbb": "eee45475" }; var dd = _0xb28de8["bbb"];}同名作用域不同,局部变量优先,花指令处理后,可删除局部_0xb28de8,同时也是安全删除情况2.不安全删除情况function kk(a) {//传值验证 var ss = _0xb28de8[a];}此处,使用全局变量_0xb28de8,但是传入的值未知,确保整体安全,禁止删除_0xb28de8二.对全局变量及局部变量的使用场景进行优化特别说明及感谢:此处核心源码来自于作者:粗犷的大米参考ob解混淆源码https://github.com/DingZaiHub/ob-decrypt

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。