这个问题很难在问题标题中总结
更新 我创建了一个JSFiddle,它根据从这个问题中提取的字母从输入中构建一个混淆的字符串:你可以访问它here,还是gist会更容易?
我最近在this profile中遇到了一些有趣的混淆JavaScript,看起来像这样:
javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]
很抱歉破坏了这个惊喜,但是当评估它时会返回:
"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10
分解时的工作方式是生成一系列消息并从中拉出字母(使用“I”作为示例):
[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"
生成的其他字符串包括:
({}+[]) -> "[object Object]" (where the space comes from)
([]+!!-[]) -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[]) -> "undefined"
我有兴趣找到“n”和“[”的替代品,并想出了这个:
String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))
我觉得使用1和0的精神,但违反了原始代码的一个更优雅的方面,即完全与字符串无关。是否有其他人知道如何生成与原始混淆代码保持一致的“v”?
以下是一些额外的信息,这些信息是在许多才华横溢的JavaScript程序员深入研究之后发现的
Firefox返回“I lone you”因为这一行:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+
[1^11<<1]
修剪一个特定字符:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
对此进行评估:
"function test() {
[native code]
}"
看起来我们可能有“V”!!!
Chrome会返回“我爱你”,因为相同的代码会返回:
"function test() { [native code] }"
在问题因“真正的编程问题”而被关闭之前,我认为我会添加一个基于@Supr's,@Cory's和@alpha123's构建的摘要解决方案:
alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])
鉴于代码的复杂性及其产生的消息,它几乎就像JavaScript引擎告诉你有多特别感觉:)
答案 0 :(得分:83)
首先,我要感谢杰森和所有贡献者玩这个有趣的片段。我已经写了那段代码只是为了好玩以便在2月14日将它发送给我的妻子:)在笔记本电脑上只安装了Chrome我无法检查它在Firefox和IE中是如何工作的。此外,我并没有真正期望内置方法的toString()
表示在其他浏览器中看起来可能有所不同。
现在,转向真正的问题,让我们来看看代码。是的,"v"
是真正的“问题”。除了解析[native code]
字符串之外,我找不到其他方法来获取此字母,这可以从任何内置方法中获取。由于除了使用1
之外没有字符串和数字限制自己,我需要利用一些在名称中只有可用字符的方法。
可以从现有关键字和字符串表示中获取可用字符,即从一开始我们NaN
,null
,undefined
,Infinity
,true
,false
和"[object Object]"
。其中一些可以很容易地转换为字符串,例如1/!1+[]
提供"Infinity"
。
我分析了数组[]
,对象{}
,正则表达式/(?:)/
,数字1.1
,字符串"1"
和已发现的不同内置方法一个名为test()
的RegExp
对象的漂亮方法。它的名称可以从所有可用的字符组合,例如来自"t"
的{{1}}和"e"
以及来自true
的{{1}}。我创建了一个字符串"s"
,并使用正方形文字false
的方括号表示法来解决此方法,在此行中正确标识:
"test"
如前所述,这段代码在Chrome中评估为:
/-/
在Firefox中:
/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]
并在IE中:
function test() { [native code] }
(后者支付特殊注意function test() {
[native code]
}
关键字之前的空格
因此,正如您清楚地看到的那样,我的代码从呈现的字符串中获得了第24个字符,在Chrome中 function test() { [native code] }
(按计划),但不幸的是在Firefox和IE中function
和"v"
分别。
为了在所有浏览器中生成相同的输出,我使用了不同的方法,而不是其他答案中所示。现在修改后的版本看起来像这样:
"n"
然而,为了激发读者的兴趣,我不会为此提供解决方案。老实说,我相信你会很容易理解它是如何运作的......有些人甚至可以用跨浏览器的方式惊喜他们心爱的人;)
受到Jason创建通用混淆工具的想法的启发,我又写了一篇。您可以在 JSBin:http://jsbin.com/amecoq/2 找到它。它可以混淆包含数字"["
,小拉丁字母javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+/\[[^1]+\]/[([]+![])[1<<1<<
1]+(/|/[(1+{})[1+11>>>1]+[[]+{}][+!1][1]+([]+1/[])[1<<1>>1]
+([1<1]+[])[1+11>>>1+1]+[[!!1]+1][+[]][1-1]+([]+!!/!/)[1|1]
+(/1/[1]+[])[!1%1]+(-{}+{})[-1+1e1-1]+(1+[!!1])[1]+([]+1+{}
)[1<<1]+[!!/!!/+[]][+[]][1&1]]+/=/)[1e1+(1<<1|1)+(([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[1^1]==+!1)]+(!![]+{})[1|1<<1]+[1+{}+1][!1+!1][(11>>1)+1
]](([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+
(!!1+[])[1^1]]))[1&.1][11>>>1]+([,][~1]+[])[1-~1]+[[]+{}][!
1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[]
,[]+{}][1<<1>>>1][1||1]+(/[<+>]/[1&1|1]+[1.1])[1/11.1&1.11]
和空格的任何文本。字符串长度主要受限于你的RAM(至少我的答案的主体被成功地混淆了)。 Chrome,Firefox和IE支持输出。
提示:该工具使用与上述不同的混淆方法。
答案 1 :(得分:26)
为什么问题的native code
位没有被使用?这个在Chrome和Firefox中都提供'v'
:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]>([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]?([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]
编辑以支持IE并在没有三元运算符的情况下执行此操作:
这个适用于Chrome,IE和FF。构建一个数组并使用==
来确定浏览器。
[([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]
可读:
[
//ie
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],
//ch
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],
//ff
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]
]
[
//ch?
((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+
//ff?
((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)
]
答案 2 :(得分:8)
这是我能得到的尽可能接近,不幸的是,它通过拨打unescape()
违反了原始混淆的惯例:
unescape((/%/+[])[1]+(/1/[1]+[])[1%1]+(+!1)+(+!1)+(1e1+(11*(1-~1)<<1)))
拆解:
(/%/+[])[1] => "%"
(/1/[1]+[])[1%1] => "u"
(+!1) => "0"
(+!1) => "0"
(1e1+(11*(1-~1)<<1)) => "76"
===========================
unescape("%u0076") => "v"
其他想法:
unescape("\x76")
118
而不调用String.fromCharCode()
<强>更新强>
我开始玩代码高尔夫并且一直在缩短代码,用更多1
等替换部件。
答案 3 :(得分:4)
这是生成n / v的部分:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]
在Firefox中,([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
评估为
"function test() {
[native code]
}"
在Chrome中,它是
"function test() { [native code] }"
1^11<<1
等于23.因此,由于Firefox的额外空白,这还不足以进入&#39; v&#39;而是&#39; N'#39;
这就是为什么你不应该依赖Function#toString行为。 ;)
编辑: 最后,我找到了一个合理混淆的跨浏览器版本:
[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]+([,][~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]
这会将n / v部分替换为:
([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]
利用parseInt中的差异(显然Firefox会解析以0开头的数字作为八进制,而Chrome不会在Firefox的情况下添加4),从而获得&#39; v&#39;来自&#39; native&#39;在这两种情况下(我都找不到另一个&#39; v&#39;:P) parseInt看起来有点不合适,但这是我现在能做的最好的事情。
答案 4 :(得分:4)
对于一般用例,如果字符大小不是一个大问题,我可能会倾向于作弊。
创建功能&#34; c&#34;它将数字0 .. 25变成一个字符。
c=function(v){for(var i in window){for(var ci in i){if(parseInt(i[ci],(10+11+11)+(1<<1)+(1<<1))==(v+10)){return i[ci]}}}};
出于性能原因,如果需要,请预先缓存字母。
l=[];for(var i=0; i<(11+11)+(1<<1)+(1<<1);i++){l[i]=c(i);}
在Chrome控制台中,生成的数组如下所示:
> l;
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "K", "l", "m", "n", "o", "p", "q", "r", "S", "t", "u", "v", "w", "x", "y", "Z"]
所以......你的 v 可能是l[10+10+1]
。
或者,像这样的一般解决方案:
p=(function(){10%11}+[])[1+11+(1<<1)]; // "%"
u=(function(){club=1}+[])[1+11+(1<<1)]; // "u"
vc=p+u+(0+[])+(0+[])+((111>>1)+11+10+[]); // "%u0076"
unescape(vc);
或者,对于此特定的问题,可能只是:
(function(){v=1}+[])[10+(1<<1)]; // "v"
答案 5 :(得分:3)
这在Chrome中提供了一个v:
Object.getOwnPropertyNames(Object)[17][3];
这是在Firefox中做到的:
Object.getOwnPropertyNames(Object)[9][3]
他们都将其从Object.prototype.preventExtensions()
中删除,因此您可能会找到一种跨浏览器方式来引用该方法。 (对于初学者来说,它是Object.Prototype中唯一的17个字符的名称。)
随意建立一个更加混淆的版本并为自己拿走所有功劳,我没时间;)
答案 6 :(得分:2)
在chrome中,表达式([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])
的计算结果为"function test() { [native code] }"
,[1^11<<1]
的计算结果为23(按位运算符会导致变量被截断为32位)