Javascript自我防御是如何工作的以及如何在美化时进入无限循环?

GxD*_*xDD 6 javascript obfuscation

有一个网站“obfuscator.io”,它混淆了 Javascript 代码。它的功能之一是“自卫”。它将简单的console.log()一行变成了这样:

var _0x2a3a06=function(){var _0x409993=!![];return function(_0xe0f537,_0x527a96){var _0x430fdb=_0x409993?function(){if(_0x527a96){var _0x154d06=_0x527a96['apply'](_0xe0f537,arguments);_0x527a96=null;return _0x154d06;}}:function(){};_0x409993=![];return _0x430fdb;};}();var _0x165132=_0x2a3a06(this,function(){var _0x46b23c=function(){var _0x4c0e23=_0x46b23c['constructor']('return\x20/\x22\x20+\x20this\x20+\x20\x22/')()['constructor']('^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}');return!_0x4c0e23['test'](_0x165132);};return _0x46b23c();});_0x165132();console['log']();
Run Code Online (Sandbox Code Playgroud)

该代码确实可以在 Webkit 控制台中运行,但是当您使用“beautifier.io”或“de4js”等应用程序对其进行美化并再次在同一控制台中运行它时,代码会进入无限循环,从本质上破坏了代码。这是如何运作的?它与美化器的工作方式有关,还是与 Javascript 解释代码的方式有关?

Ber*_*rgi 10

像您一样通过美化器运行代码,然后应用一些基本的变量重命名和取消转义会产生以下代码:

var makeRun = function() {
    var firstMakeRun = true;
    return function(global, callback) {
        var run = firstMakeRun ? function() {
            if (callback) {
                var result = callback['apply'](global, arguments);
                callback = null;
                return result;
            }
        } : function() {};
        firstMakeRun = false;
        return run;
    };
}();
var run = makeRun(this, function() {
    var fluff = function() {
        var regex = fluff['constructor']('return /" + this + "/')()['constructor']('^([^ ]+( +[^ ]+)+)+[^ ]}');
        return !regex['test'](run);
    };
    return fluff();
});
run();
console['log']()
Run Code Online (Sandbox Code Playgroud)

/^([^ ]+( +[^ ]+)+)+[^ ]}/重要的部分是它针对函数本身测试正则表达式run,执行隐式run.toString().

现在无限循环在哪里?没有,但是应用于包含大量空格的字符串的正则表达式确实会出现灾难性的回溯。尝试运行使用制表符而不是空格缩进的代码,它会正常工作 - 只要您的函数run不包含彼此之间的多个空格,并且结束符前面没有空格,正则表达式就会匹配}。