今天在开源中国看到一篇神作《I LOVE YOU js代码》是17号的文章了,也许你已经看过了。
文章非常有意思,由 5 个 "爱心" 组成的一段js代码,能正常执行,执行后弹出 "I love you." 字符串。
$= ~[]; $={___: ++$,$$$$: (![]+"")[$], __$:++$,$_$_:(![]+"") [$],_$_:++$,$_$$: ({} + "")[$], $$_$ : ($[$]+"") [$],_$$: ++$,$$$_:(!""+"")[$],$__: ++$,$_$:++$,$$__:({}+"") [$],$$_: ++$,$$$:++$, $___:++$,$__$:++$ };$.$_ = ($.$_= $ + "") [ $.$_$]+ ($._$= $.$_[$.__$ ])+($.$$=( $.$+"")[$.__$])+((!$)+"") [$._$$]+($.__=$.$_[$.$$_ ])+($.$=(!""+"")[$.__$ ]) + ($._= (!""+"") [ $._$_]) +$.$_ [ $.$_$ ]+ $.__+ $._$+ $.$; $.$$=$.$+(!""+"") [$._$$]+$.__+$._+$.$+ $.$$;$.$=($.___)[$.$_] [$.$_];$.$($.$($.$$+ """+$.$_$_+(![]+ "")[$._$_]+ $.$$$_+ "\"+ $.__$+ $.$$_+ $._$_+$.__+"(\"\"+ $.__$+$.__$+$.__$+"\"+ $.$__+$.___+(![]+"")[$._$_]+ $._$+"\"+$.__$+$.$$_+$.$$_+ $.$$$_+"\"+$.$__+ $.___+ "\"+$.__$+$.$$$+$.__$+ $._$+$._+".\"\"+ $.$__ +$.___+ ")"+ """) ( ))( )
高手觉得没什么技术含量,无非就是类似 jsfuck 之类的。
当然,这个没jsfuck那么复杂,其实作者只是拼接字符串然后得到 Function 然后执行了下。
只是这个排版可能花了不少时间吧。
来,我们来简单的分析下这个js。我水平不够,不是直接看代码分析的,是在控制台下动态调试跟踪了几遍。
(function() { debugger; var $ = ~ []; // -1 $ = { ___: ++$, // 0 $$$$: (![] + "")[$], // "false"[0] => f __$: ++$, // 1 $_$_: (![] + "")[$], // "false"[1] => a _$_: ++$, // 2 $_$$: ({} + "")[$], // "[object Object]"[2] => b $$_$: ($[$] + "")[$], _$$: ++$, // 3 $$$_: (!"" + "")[$], // "true"[3] => e $__: ++$, // 4 $_$: ++$, // 5 $$__: ({} + "")[$], // "[object Object]"[5] => c $$_: ++$, // 6 $$$: ++$, // 7 $___: ++$, // 8 $__$: ++$ // 9 }; $.$_ = ($.$_ = $ + "")[$.$_$] + ($._$ = $.$_[$.__$]) + ($.$$ = ($.$ + "")[$.__$]) + ((!$) + "")[$._$$] + ($.__ = $.$_[$.$$_]) + ($.$ = (!"" + "")[$.__$]) + ($._ = (!"" + "")[$._$_]) + $.$_[$.$_$] + $.__ + $._$ + $.$; // 这里这么长就是为了组成 "constructor" 字符串 $.$$ = $.$ + (!"" + "")[$._$$] + $.__ + $._ + $.$ + $.$$; // "return" $.$ = ($.___)[$.$_][$.$_]; // (0).constructor.constructor => Function // $.$ = Function // return"ale162t("11140lo166e40171ou."40)" $.$( $.$( $.$$ + """ + $.$_$_ + (![] +"")[$._$_] + $.$$$_ + "\" + $.__$ + $.$$_ + $._$_ + $.__ + "(\"\" + $.__$ + $.__$ + $.__$ + "\" + $.$__ + $.___ + (![] + "")[$._$_] + $._$ + "\" + $.__$ + $.$$_ + $.$$_ + $.$$$_ + "\" + $.$__ + $.___ + "\" + $.__$ + $.$$$ + $.__$ + $._$ + $._ + ".\"\" + $.$__ + $.___ + ")" + """ // 这里这么长一段就是为了得到 return"ale\162t(\"\111\40lo\166e\40\171ou.\"\40)" 字符串 )() )(); // 这部分代码相当于 // Function(Function('return"ale\162t(\"\111\40lo\166e\40\171ou.\"\40)"')())(); })();
这是我改造后的代码,这样在F12下动态调试非常容易阅读。
前面得到一些基本字符串,然后拼接出 constructor 和 return 字符,
接着利用 constructor 得到 Function 函数。
有了 Function 剩下的非常简单了,拼接字符串然后用 Function 执行下即可。
好了,今天水了,,因为有事情。。