关注它,不迷路。
本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
1.代码片段
((((ld0 = ((ld1 = (ld1 = Uint8Array) && undefined || ld2) || 6) && encodeUTF8(ld1)) && 0 || (ld3 = ((ld4 = (ld5 = new ld3(ld0)) && undefined || ld5) || 6) && ld4) && 0 || (ld5 = ((ld0 = (ld1 = "length") && null || ld3[ld1]) || 7) && 8) && 0 || (ld8 = ((ld7 = ((ld9 = ld0 + ld5) || 2) && 6) || 3) && ld9 >>> ld7) && undefined || (ld10 = (ld11 = ((ld12 = 4) || 7) && ld8 << ld12) && null || 16) || 3) && (ld16 = (ld33 = (ld13 = ld11 + ld10) && undefined || ld13) && null || Uint8Array) && undefined || (ld32 = ((ld14 = ((ld34 = ld33) || 8) && 2) || 9) && ld34 << ld14) && null || (((ld15 = (ld17 = new ld16(ld32)) && null || ld17) && 0 || (ld18 = ld15) && null || (ld19 = "set") || 10) && ((ld20 = Uint8Array) || 4) && ((ld21 = ld4) || 4) && ((ld22 = "buffer") || 5) && ((ld23 = ld21[ld22]) || 7) && (ld24 = new ld20(ld23)) && null || ld18[ld19](ld24) && 0 || (ld25 = Uint32Array) || 5) && (((ld27 = ld15) || 8) && (ld31 = "buffer") && undefined || (ld26 = ld27[ld31]) && undefined || (ld30 = new ld25(ld26)) || 3) && (ld15 = ld30)) && null || (ld29 = new DataView(ld15.buffer)) && undefined || (ld28 = 0) || 1) && (ld6 -= 999);
说是复杂,其实就是赋值语句与逻辑表达式的各种相互嵌套罢了。
2.先导知识
经过多次询问GPT,得知,在一个js语句中,有些代码可能会执行,也可能不会执行。而我们如果要简化上面的代码,就要找出一定会执行的语句。
一般而言,我们遇到比较常见的代码节点类型如条件表达式以及逻辑表达式,它会存在上面的情况。
对于上面的混淆代码,它不包含 条件表达式,因此只需要处理 逻辑表达式 的情况即可。
对于一个赋值语句与逻辑表达式的各种相互嵌套的混淆代码,如何找出它第一条一定会执行的语句?
答案是 使用深度优先模式来遍历该语句。
3.还原思路
我们知道,节点的访问模式有两种,enter 和 exit,一般默认为 enter,
但是,对于这种嵌套的语句,使用 exit 更好。通过这种方式,可以找到第一条一定会执行的语句:
const splitLogicalExpression =
{
LogicalExpression:
{
exit(path) {
console.log(path.toString());
return;
}
},
}
运行后的打印结果:
如图,红色框内是一定可以被执行的语句,因此将它提到整个表达式的前面来,而这个逻辑表达式的值 可以看出是 false,即有两步操作:
1.将 ld1 = Uint8Array 这行代码 提到整个代码的前面来;
2.因为代码已经执行了,可以直接用结果来继续替换,这里很明显它的结果是false,因此直接用false替换即可。
替换后的代码应该是这样的:
经过这一步后,接下来处理的逻辑表达式就应该是:
(ld1 = false || ld2) || 6
这里又可以把 ld1 = false || ld2 给提到混淆代码的前面去,而后面的 || 6,可以确定这个表达式恒为true,因此它可以直接被替换成 true。
第二步处理后的代码应该是这样的:
........
就这么一起处理下去,最终我们得到下面的代码:
看到了代码中包含大量的 false 和 true,这个时候再写个插件,去掉这些false 和true,得到最终的代码:
这样代码就被我们轻松还原了。可以说,非常的清爽!
今天的文章就分享到这里,感谢大家的阅读!
欢迎加入知识星球,学习更多AST和爬虫技巧。