上一篇我们已经解释了jsfuck的基本原理,简单来说,如果我们想要用jsfuck加密一段可执行代码,那么代码最后应该是这样的类型:
Function(code)()
在上一篇中我们提到,Function()()这一段可以转换成如下代码:
[]["filter"]["constructor"]( )()
那么,我们就得到了一段完全由“ ()+[]! ”与字符串组合的代码,接下来我们只需要把字符串也加密成“ ()+[]! ”就可以了!
所需要加密的字符串,包含了所有可显示字符在此,我们依然拿“ alert(1) ”来举例:
字符串“ alert(1) ”可拆解为a、l、e、r、t、(、1、),八个字符,这些字符我们很容易在上一篇文章中找到:
1 => +!+[]
false => ![]
true => !![]
由上可得:
'a' == 'false'[1] == (false + '')[1] == (![]+[])[+!+[]]
'l' == 'false'[2] == (false + '')[2] == (![]+[])[!+[]+!+[]]
'e' == 'true'[0] == (true + '')[3] == (!![]+[])[!+[]+!+[]+!+[]]
'r' == 'true'[0] == (true + '')[1] == (!![]+[])[+!+[]]
't' == 'true'[0] == (true + '')[0] == (!![]+[])[+[]]
则:'alert' == (![]+[])[+!+[]] + (![]+[])[!+[]+!+[]] + (!![]+[])[!+[]+!+[]+!+[]] + (!![]+[])[+!+[]] + (!![]+[])[+[]]
那么我们如何得到括号字符呢?首先我们要找到包含括号的字符串--方法,方法的基本样式就是function name (){ code }这样我们只需要把它转换成字符串,按照上面的方法实现一遍就行了。jsfuck官方给出的方法是:
([][[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[!+[]+!+[]]]
拆分可得:
(undefined + []['fill'])['22'] == "undefinedfunction fill() { [native code] }"['22']
这里只是用了数组的fill方法,和方法本身没有关系,换成find没有影响,一样可以得到括号。即:
(undefined + []['find'])['22'] == "undefinedfunction find() { [native code] }"['22']
既然得到了左括号,那么右括号只需要把数字22改成23就可以得到,即:
([+[]]+![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[+[]]]
把以上加密后的代码组合(部分代码记得加上括号),我们便得到了:
(![]+[])[+!+[]] + (![]+[])[!+[]+!+[]] + (!![]+[])[!+[]+!+[]+!+[]] + (!![]+[])[+!+[]] + (!![]+[])[+[]]+([][[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[!+[]+!+[]]]+(+!+[])+([+[]]+![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[+[]]] == 'alert(1)'
到目前为止,字符串我们已经拿到了,接下来只需要按照上面的方法,拿到Function就行了,最终组合成:
[]["filter"]["constructor"]('alert(1)')() == Function('alert(1)')()
这样一个完美的jsfuck加密代码已经完成了!