关注它,不迷路。
本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
1.样本DEMO**:**
javascript
var aaa = function (A) { return function (B) { return function (A) { return Q[function (A) { return function (A) { return function (B) { return function (A) { return +function (A) { return !function (A) { return null; }(); }(); }() << A(); }; }(function (A) { return !function (A) { return null; }(); })(); }()]; }()[A()]; };}
2.代码分析**:**
最显眼的莫过于 return null 了,因为它是一个字面量,并且代码也比较单一,比如这段代码里:
javascript
return !function (A) { return null;}();
这里的形式参数A,其实是没有用的。可以直接还原成 return !null
其实也就是
javascript
!function (A) {return null;}();
===>
javascript
!null;
这样的拆解,大家更容易理解。
根据特征写还原插件,优化后的代码如下:
javascript
var aaa = function (A) { return function (B) { return Q[function (A) { return function (A) { return function (B) { return function (A) { return +function (A) { return !null; }(); }() << A(); }; }(function (A) { return !null; })(); }()][A()]; };};
这里,又看到了 !null ,又可以进行处理,即:
!null ===> true;
这个使用 常量折叠插件 就可以了。优化后的代码如下:
javascript
var aaa = function (A) { return function (B) { return Q[function (A) { return function (A) { return function (B) { return function (A) { return +function (A) { return true; }(); }() << A(); }; }(function (A) { return true; })(); }()][A()]; };};
这里的 return true 这第一步是类似的,因此又回到了第一步的处理。加个循环处理就好,优化后的代码:
javascript
var aaa = function (A) { return function (B) { return Q[function (A) { return function (A) { return function (B) { return 1 << A(); }; }(function (A) { return true; })(); }()][A()]; };};
处理后,发现,仍然有地方没有被处理,如
javascript
(function (A) { return true;})()
拿去在线网站上进行解析,发现它被解析成了FunctionExpression,并不是我们以为的CallExpression,而且,它仅仅只是作为实参,因此没有被之前的插件处理。
这时,我们从其他地方入手,发现了这个:
javascript
function (A) { return function (A) { return function (B) { return 1 << A(); }; }(function (A) { return true; })();}()
它其实可以直接出值,虽然是个callexpression,但是直接eval的话会报错,你可以给它赋给另外一个变量,如:
javascript
var aaa = function (A) { return function (A) { return function (B) { return 1 << A(); }; }(function (A) { return true; })();}()
这个时候就可以进行处理了,还原后的效果如下:
javascript
var aaa = function (A) { return function (B) { return Q[2][A()]; };};
这就是还原后的最终形态了,当然,它只一个例子,并不包含所有情况,如:
javascript
function (A) { return function (B) { return function (A) { return function (B) { return false + A(); }; }(function (A) { return window; })()[A()]; }; }
因为window不是字面量,并且在node下面是未定义的,因此是没办法直接得出值的。
这个时候,我们可以根据形参的引用用实参来替换形参,它的还原效果:
javascript
function (A) { return function (B) { return function () { return function (B) { return false + window; }; }()()[A()]; }; }
还能继续简化:
javascript
function (A) { return function (B) { return (false + window)[A()]; };};
继续简化:
javascript
function (A) { return function (B) { return ('false[object Window]')[A()]; };};
这应该就是它简化后的最终形态了。
今天的分享就到这里,感谢阅读。
欢迎加入知识星球,学习更多AST和爬虫技巧。
