148

这个问题很难用问题标题来概括

更新 我创建了一个 JSFiddle,它根据从这个问题中提取的字母从您的输入中构建一个混淆字符串:您可以在此处访问它,或者要点更容易?

我最近在这个配置文件中遇到了一些有趣的混淆 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 返回“我孤独你”因为这行:

([]+/-/[(!!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 引擎在告诉你让它感觉有多特别:)

4

7 回答 7

84

首先,我要感谢 Jason 和所有贡献者使用这个有趣的片段。我写这段代码只是为了好玩,以便在 2 月 14 日将它发送给我的妻子 :) 笔记本电脑上只安装了 Chrome,我无法检查它在 Firefox 和 IE 中的工作方式。此外,我并没有真正预料到toString()内置方法的表示在其他浏览器中可能会有所不同。

现在,转向真正的问题,让我们准确地看一下代码。是的,"v"这是真正的“问题”。[native code]除了可以从任何内置方法中获取的解析字符串外,我没有发现其他获取该字母的方法。由于我限制自己除了使用之外没有字符串和数字1,因此我需要利用一些名称中只有可用字符的方法。

可用字符可以从现有的关键字和字符串表示中获得,即从一开始我们就有NaNnullundefinedInfinitytruefalse"[object Object]"。其中一些可以很容易地转换为字符串,例如1/!1+[]"Infinity"

[]我分析了数组、对象{}、正则表达式/(?:)/、数字1.1、字符串的不同内置方法"1",并发现了一种漂亮的RegExp对象方法,称为test(). 它的名称可以由所有可用的字符组合而成,例如"t",and "e"fromtrue"s"from false。我创建了一个字符串"test",并使用方括号表示法解决了这个方法的正则表达式文字/-/,在这一行中正确识别:

/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]

正如已经讨论过的,这段代码在 Chrome 中被评估为:

function test() { [native code] }

在 Firefox 中为:

function test() {
    [native code]
}

在 IE 中为:

 function test() {     [native code] }  

(在后者中要特别注意function关键字前的空格)

因此,正如您清楚地看到的那样,我的代码正在从提供的字符串中获取第 24 个字符,这在 Chrome 中是"v"(按计划),但不幸的是在 Firefox 和 IE 中 -"n""["分别。

为了在所有浏览器中产生相同的输出,我使用了与其他答案中所示不同的方法。现在修改后的版本是这样的:

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]

但是,为了吸引读者,我不会为此提供解决方案。老实说,我相信你会很容易理解它是如何工作的......有些甚至可以以跨浏览器的方式让他们心爱的人大吃一惊;)

PS又一个混淆器

受到 Jason 创建通用混淆工具的想法的启发,我又写了一个。你可以在JSBin 上找到它:http: //jsbin.com/amecoq/2。它可以混淆任何包含数字[0-9]、小拉丁字母[a-z]和空格的文本。字符串长度主要受您的 RAM 限制(至少我的答案的主体已成功混淆)。Chrome、Firefox 和 IE 支持输出。

提示:该工具使用与上面介绍的不同的混淆方法。

于 2013-04-16T12:13:50.440 回答
26

为什么不native code使用问题中的位?这'v'在 Chrome 和 Firefox 中都给出了一个:

([]+/-/[(!!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)
]
于 2013-04-12T22:35:27.453 回答
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"

其他想法:

  1. 不知何故到达unescape("\x76")
  2. 以某种方式转换118而不调用String.fromCharCode()
  3. 从包含“无效”一词的异常中获取文本

更新:

我开始玩代码高尔夫,并一直在缩短它,用更多1的 s 替换零件等。

于 2013-04-12T20:07:51.610 回答
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 的额外空格,这还不足以到达“v”,而是“n”。

这就是为什么您不应该依赖 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,从而在两种情况下都从“native”获取“v”(我找不到另一个 'v ':P)。
parseInt 看起来有点不合适,但这是我现在能做的最好的。

于 2013-04-12T18:33:04.697 回答
4

对于一般用例,如果字符大小写不是一个大问题,我可能会倾向于作弊。

创建函数“c”,将数字 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"
于 2013-04-12T20:54:44.370 回答
3

这在 Chrome 中给出了 av:

Object.getOwnPropertyNames(Object)[17][3];

这在 Firefox 中是这样的:

Object.getOwnPropertyNames(Object)[9][3]

他们都将其从 中提取出来Object.prototype.preventExtensions(),因此您可能会找到一种跨浏览器的方式来引用该方法。(对于初学者来说,它是 Object.Prototype 中唯一的 17 个字符的名称。)

随意构建一个更加模糊的版本,并将所有功劳归于自己,我没时间了;)

于 2013-04-12T18:37:08.587 回答
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 位)

于 2013-04-12T18:33:18.610 回答