你能解释一下这个NoAlphanumeric JS代码是如何工作的吗?

时间:2012-01-03 16:22:29

标签: javascript

我在网上找到了一个javascript代码(名为NoAlphanumeric JS):

_=[]|[];$=_++;__=(_<<_);___=(_<<_)+_;____=__+__;_____=__+___;$$=({}+"")[_____]+({}+"")[_]+({}[$]+"")[_]+(($!=$)+"")[___]+(($==$)+"")[$]+(($==$)+"")[_]+(($==$)+"")[__]+({}+"")[_____]+(($==$)+"")[$]+({}+"")[_]+(($==$)+"")[_];$$$=(($!=$)+"")[_]+(($!=$)+"")[__]+(($==$)+"")[___]+(($==$)+"")[_]+(($==$)+"")[$];$_$=({}+"")[_____]+({}+"")[_]+({}+"")[_]+(($!=$)+"")[__]+({}+"")[__+_____]+({}+"")[_____]+({}+"")[_]+({}[$]+"")[__]+(($==$)+"")[___]; ($)[$$][$$]($$$+"('"+$_$+"')")() 

此代码将打开“提醒”并打印“酷代码”......

有人可以解释这段代码的工作原理吗?

4 个答案:

答案 0 :(得分:4)

到此为止!

添加换行符

......和一些评论

// Variable declarations
_=[]|[];
$=_++;
__=(_<<_);
___=(_<<_)+_;
____=__+__;
_____=__+___;

// Variable declarations that "do stuff"
$$=({}+"")[_____]+({}+"")[_]+({}[$]+"")[_]+(($!=$)+"")[___]+(($==$)+"")[$]+(($==$)+"")[_]+(($==$)+"")[__]+({}+"")[_____]+(($==$)+"")[$]+({}+"")[_]+(($==$)+"")[_];
$$$=(($!=$)+"")[_]+(($!=$)+"")[__]+(($==$)+"")[___]+(($==$)+"")[_]+(($==$)+"")[$];
$_$=({}+"")[_____]+({}+"")[_]+({}+"")[_]+(($!=$)+"")[__]+({}+"")[__+_____]+({}+"")[_____]+({}+"")[_]+({}[$]+"")[__]+(($==$)+"")[___];

// Final function call
($)[$$][$$]($$$+"('"+$_$+"')")()

扩展声明1

// Variable declarations
// _=[]|[];  ->  replace `_` with 0
$=0;          //  (actually, 1)
__=(1<<1);    // 2
___=(1<<1)+1; // 3
____=2+2;     // 4
_____=2+3;    // 5

// Variable declarations that "do stuff"
$$=({}+"")[_____]+({}+"")[1]+({}[0]+"")[1]+((0!=0)+"")[___]+((0==0)+"")[0]+((0==0)+"")[1]+((0==0)+"")[__]+({}+"")[_____]+((0==0)+"")[0]+({}+"")[1]+((0==0)+"")[1];
$$$=((0!=0)+"")[1]+((0!=0)+"")[__]+((0==0)+"")[___]+((0==0)+"")[1]+((0==0)+"")[0];
$_$=({}+"")[_____]+({}+"")[1]+({}+"")[1]+((0!=0)+"")[__]+({}+"")[__+_____]+({}+"")[_____]+({}+"")[1]+({}[0]+"")[__]+((0==0)+"")[___];

// Final function call
(0)[$$][$$]($$$+"('"+$_$+"')")() 

扩展声明2

更多扩展变量,让我们评估那些0==00!=0

// Variable declarations that "do stuff"
$$=({}+"")[5]+({}+"")[1]+({}[0]+"")[1]+((false)+"")[3]+((true)+"")[0]+((true)+"")[1]+((true)+"")[2]+({}+"")[5]+((true)+"")[0]+({}+"")[1]+((true)+"")[1];
$$$=((false)+"")[1]+((false)+"")[2]+((true)+"")[3]+((true)+"")[1]+((true)+"")[0];
$_$=({}+"")[5]+({}+"")[1]+({}+"")[1]+((false)+"")[2]+({}+"")[2+5]+({}+"")[5]+({}+"")[1]+({}[0]+"")[2]+((true)+"")[3];

// Final function call
(0)[$$][$$]($$$+"('"+$_$+"')")() 

字符串构建

(true)+""等于"true"(false)+""等于"false"。此外,{}+""变为"[object Object]"{}[0]+""变为"undefined"

// Variable declarations that "do stuff"
$$=("[object Object]")[5]+("[object Object]")[1]+("undefined")[1]+("false")[3]+("true")[0]+("true")[1]+("true")[2]+("[object Object]")[5]+("true")[0]+("[object Object]")[1]+("true")[1];
$$$=("false")[1]+("false")[2]+("true")[3]+("true")[1]+("true")[0];
$_$=("[object Object]")[5]+("[object Object]")[1]+("[object Object]")[1]+("false")[2]+("[object Object]")[2+5]+("[object Object]")[5]+("[object Object]")[1]+("undefined")[2]+("true")[3];

// Final function call
(0)[$$][$$]($$$+"('"+$_$+"')")() 

并且,将([0][1]等)索引到这些字符串中:

$$="c"+"o"+"n"+"s"+"t"+"r"+"u"+"c"+"t"+"o"+"r";
$$$="a"+"l"+"e"+"r"+"t";
$_$="c"+"o"+"o"+"l"+" "+"c"+"o"+"d"+"e";

// Final function call
(0)[$$][$$]($$$+"('"+$_$+"')")() 

并结合:

$$="constructor";
$$$="alert";
$_$="cool code";

// Final function call
(0)[$$][$$]($$$+"('"+$_$+"')")() 

执行

现在它变得有点棘手了。

(0)[$$][$$]($$$+"('"+$_$+"')")() 

(0)["constructor"]["constructor"](0).constructor.constructor相同,并生成Function构造函数(Number的构造函数的构造函数):

(Function)($$$+"('"+$_$+"')")()

扩展变量:

(Function)("alert"+"('"+"cool code"+"')")()

和签约:

(Function)("alert('cool code')")()

将该字符串转换为Function对象会产生一个'eval代码的函数,因此,我们最终得到:

(function() { alert('cool code') {})()

()执行函数。

Bootnote

我接受Paypal。

答案 1 :(得分:2)

据我所知,代码利用Javascript错误和输出类型来编写各种字符。例如,输出“NaN”将产生字符“N”和“a”,您可以像在Javascript中的任何字符串一样选择它们 - 相当于v [0]选择“N”和v [1]选择“a”。

这至多是一个基本的解释,但鉴于对这个问题的一些评论,我的猜测是在Stack上的其他地方有一个更全面的答案。

答案 2 :(得分:2)

开始在控制台中自行分解......

_=[]|[];  // ===  _=0
$=_++;    // ===  $=0, _=1
__=(_<<_) // === __=2

...等。只需在分号上拆开它并开始测试:)询问您想要的任何特定问题,例如“为什么[]|[] === 0?”

之后,我假设这会利用JS错误消息,vars,例如使用“undefined”,“NaN”,“true”,“false”你可以使用这些字母做任何事情......

答案 3 :(得分:2)

我不打算为你翻译,因为asw @LightnessRacesinOrbit表示这是一项重大工作。我建议首先通过分裂分号将它分成多行然后开始将变量重命名为更容易区分的东西。

这就是所谓的混淆代码,其设计尽可能难以理解。使用______等不同的变量会让人很难记住每个变量。将其拆分并重命名,如果有必要,只需在每个语句之间添加一个警报,以查看最近的操作已完成(或者更好地在调试器中运行它等),然后让您了解它是如何工作的。

修改

实际上它没有我想象的那么糟糕......

一旦从[] | []得到0,它最初用一些简单的数学东西设置以下常量。我假设它更复杂地添加到混淆...

_ = 1
$ = 0
__ = 2
___ = 3
____ = 4
_____ = 5

然后使用以下内容获取字符串/字符数组以获取一些字符:

({}+"") - [object Object]
({}[$]+"") undefined
(($!=$)+"") false
(($==$)+"") true

然后最后的事情就是将这些字符串连接起来:

$$ - constructor
$$$ - alert
$_$ - cool code

然后最后一行使用了一些我不完全清楚的魔法,然后调用alert函数......我认为它可能会重写一个对象或类似的构造函数。这是我唯一有点朦胧的......

最终修改:

我已经解决了这个问题。

($)['constructor']['constructor']似乎是Function(),如果你用字符串参数调用它,它似乎创建了一个基于该字符串的匿名方法。然后最后一个括号称匿名成员,如果你跟进到这里,你就会知道打电话给警报。