域名出售网站,宁波网站建设公司哪有,北京做网站好的,网站注册域名免费原文地址:https://zhuoyue360.com/jsnx/110.html 1. 期望
这是一个瑞数5代解混淆的案例#xff0c;我们本章节需要做的是把if节点的内容转换成switch-case内容.以此来熟悉AST对JS混淆的对抗.
原始代码:
function whileState() {while (1) {aV cA[wU];if (aV 4) {if (… 原文地址:https://zhuoyue360.com/jsnx/110.html 1. 期望
这是一个瑞数5代解混淆的案例我们本章节需要做的是把if节点的内容转换成switch-case内容.以此来熟悉AST对JS混淆的对抗.
原始代码:
function whileState() {while (1) {aV cA[wU];if (aV 4) {if (aV 1) {zT window, kD String, bO Array, xX document, nZ Date;} else if (aV 2) {iG zT[ab] {};} else if (aV 3) {iG zT[ab];} else {mM !iG;}} else {if (aV 5) {xT(0);} else if (aV 6) {if (!mM) wU 1;} else if (aV 7) {lG [4, 16, 64, 256, 1024, 4096, 16384, 65536];} else {return;}}}
}期望代码:
function whileState() {while (1) {switch (cA[wU]) {case 0:zT window, kD String, bO Array, xX document, nZ Date;break;case 1:iG zT[ab] {};break;case 2:iG zT[ab];break;case 3:mM !iG;break;case 4:xT(0);break;case 5:if (!mM) wU 1;break;case 6:lG [4, 16, 64, 256, 1024, 4096, 16384, 65536];break;case 7:return;break;}}
}2. 思路分析
首先,我们需要明确一点,aV 的索引是从0开始的,它是不可能为负数的.
那么也就可以有如下的转换:
if (aV 1) {zT window, kD String, bO Array, xX document, nZ Date;
}转换成
if (aV 0) {zT window, kD String, bO Array, xX document, nZ Date;
}这是蔡老板所说的夹逼原理 ,奈何文化低,我不懂.知道有这么一个回事就行.
思路如下(更加详细的看代码注释):
while循环的参数是NumericLiteral ,且内容为1.body中只有2个节点提取出aV找到WhileStatement枚举WhileStatement下的IfStatement节点.left的name应该为我们提取出的aVoperator为right类型不能为IfStatement, 因为它有嵌套.记录下了所有符合条件的body生成switch 节点 3. 代码
function collectSwitchCase(whilePath,name){// 菜老板知识星球获得.let ifNodes [];// 遍历WhilePathwhilePath.traverse({IfStatement(path){//遍历所有的ifStatement;let {test,consequent,alternate} path.node; //获取子节点let {left,operator,right} test; // 必定是BinaryExpressionif (!types.isIdentifier(left,{name:name}) || operator ! || !types.isNumericLiteral(right)) {//条件过滤return;}let value right.value;//保存整个body记得生成switchCase节点的时候加上break节点。ifNodes[right.value-1] consequent.body; if (!types.isIfStatement(alternate)){ifNodes[right.value] alternate.body; //最后一个else其实就是上一个else-if 的 test.right的值} }})return ifNodes;}const if2switchReplace {WhileStatement(path){let {test,body} path.node;// while循环的参数是NumericLiteral ,且内容为1. body中只有2个节点if(!types.isNumericLiteral(test,{value:1}) || body.body.length ! 2){return}// 判断while循环格式, 条件过滤let blockBody body.body;if (!types.isExpressionStatement(blockBody[0]) || !types.isIfStatement(blockBody[1])){return;}// left 左边的节点就是我们需要的变量名let {left,right} blockBody[0].expression; //或者左右节点 aV cA[wU];let name left.name;// 获取到了变量名称后, 就需要收集使用了aV的caselet ifNodes collectSwitchCase(path,name); //收集case//无case直接返回。if (ifNodes.length 0) return; let len ifNodes.length;for (let i0; i len; i){//每一个case最后都加breakifNodes[i].push(types.BreakStatement()); ifNodes[i] types.SwitchCase(test types.valueToNode(i),consequent ifNodes[i]); //生成SwitchCase节点}//生成SwitchCase节点let switchNode types.SwitchStatement(right,ifNodes); path.node.body.body [switchNode]; //最后的while节点只有一个Switch Node;}
}traverse(ast, if2switchReplace);