什么是 JavaScript 的内置字符串?附言:又一个混淆器

2022-08-30 03:06:31

这个问题很难在问题标题中总结

更新我创建了一个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 返回 “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@Cory@alpha123的基础上,看:

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


答案 1

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

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

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

我分析了数组、对象、正则表达式、数字、字符串的不同内置方法,并发现了一种名为test()的漂亮的对象方法。它的名字可以从所有可用的字符组合而成,例如 和 from 和 from 。我已经创建了一个字符串,并使用正则表达式文本的方括号表示法解决了此方法,在此行中正确标识:[]{}/(?:)/1.1"1"RegExp"t""e"true"s"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] }  

(在后者特别注意空格前功能关键词)

所以,正如你清楚地看到的那样,我的代码是从呈现的字符串中获取第24个字符,这在Chrome中是(按计划),但不幸的是,在Firefox和IE中 - 以及分别。"v""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]

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

附言:又一个混淆器

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

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


答案 2

为什么没有使用问题中的位?这个在Chrome和Firefox中都给出了一个:native code'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)
]