zhen5435
曾经无意中看到过的一段很有意思的JavagScript代码

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__[_+~$]+$_[_]+$$](_/_)

这是一段合法的javascript代码,其效果相当于alert(1)。但是我一直没有实验出结果。

nongeek
吃完饭又来蛋疼地修改下
展开Biu

吃完饭又来蛋疼地修改下...

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($__=($_=!''+$)[_/_]+$_[+$])]);$()[__[_/_]+__[_+~$]+$_[_]+$__](_/_)

$$似乎有特殊含义所以不行

[查看全文]
nongeek
本帖最后由
展开Biu

本帖最后由 nongeek 于 2012-9-1 18:17 编辑

zhen5435 发表于 2012-9-1 17:08

第一部分:

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()

[__[_/_]+__[_+~$]+$_[_]+$$](_/_) = ["false"[1]+"false"[3+(-1)]+"true"[3]+"rt"](1) = ["a"+"l"+"e"+"rt"](1)

$$怎么变成了"rt"? <---- 我知道了...但不知道为什么就是不行

如果把这个$$直接写成"rt",再在前面修改一下我这儿就能成功了

红色为修改的地方

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])]);$()[__[_/_]+__[_+~$]+$_[_]+"rt"](_/_)

[查看全文]
zhen5435
下测试不行
展开Biu

nongeek 发表于 2012-9-1 16:53

在chrome下测试不行...不过这个代码的原理到底是啥...

TypeError: Array.prototype.sort called on null or ...

第一部分:

($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+($$=($_=!''+$)[_/_]+$_[+$])])()

第二部分:

1.[__[_/_]+__[_+~$]+$_[_]+$$](_/_)

第一部分代码可以改写为以下等价形式:

1. $ = [];

2. __ = !$+$;

3. _ = -~-~-~$;

4. $_=!''+$;

5. $$ = $_[_/_] + $_[+$];

$= [$][

6. __[_] +

7. ({}+$)[_/_] +

8. $$

9. ];

10. $();

1. $先赋值为一个空数组

2. __ = ![] + [] = false + [] = "false" 这里利用了javascript运算的强制类型转换特性。首先空数组是一个非null值,因此![]的结果是false(布尔型)。在计算false + []时,由于数组对象无法与其他值相加,在加法之前会先做一个toString的转换,空数组的toString就是"",因此事实上在计算false + ""。这时false被自动转换为字符串。最终结果是"false"+"" = "false"。

3. 在计算~[]时,~需要一个数字操作数,空数组无法直接转换为数字,则作为0处理。因此~[] = ~0 = -1。

因此: _ = -~-~-~[] = -~-~-(-1) = -~-~1 = -~-(-2) = -~2 = -(-3) = 3

4. !''是true,使用+$将其变为字符串 "true"

5. 之前一直用“值+[]”来获得“值”的字符串形式。而“+[]”则是0(正号导致[]被自动转换为数值0)。因此:$$ = "true"[3/3] + "true"[+[]] = "true"[1] + "true"[0] = "rt"

6. __[_] = "false"[3] = "s"

7. ({} + [])导致空对象{}被转换为字符串"[object Object]", 因此({}+$)[_/_] = "[object Object]"[1] = "o"

9. 这里把$覆盖为 [[]]["s"+"o"+"rt"]。注意这里[[]]本身是一个包含空数组的数组,最终结果是,$ = [[]]["sort"] = [[]].sort = Array.prototype.sort。

10. 调用$(),作为整个表达式最终的取值。$是全局范围的,是window的一个属性,相当于window.$。

第二部分:

现在$是一个函数,因此~$ = ~0 (无法直接转换为数字则作为0处理) = -1。

[__[_/_]+__[_+~$]+$_[_]+$$](_/_) = ["false"[1]+"false"[3+(-1)]+"true"[3]+"rt"](1) = ["a"+"l"+"e"+"rt"](1)

最终结果为window["alert"](1)

[查看全文]
nongeek
下测试不行
展开Biu

在chrome下测试不行...不过这个代码的原理到底是啥...

TypeError: Array.prototype.sort called on null or undefined

arguments: Array[1]

get message: function getter() { [native code] }

get stack: function getter() { [native code] }

set message: function setter() { [native code] }

set stack: function setter() { [native code] }

type: "called_on_null_or_undefined"

__proto__: Error

[查看全文]