javascript - 什么是 JavaScript 的内置字符串?

标签 javascript obfuscation

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

更新 我创建了一个 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 返回“我孤独你”因为这行:

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

[1^11<<1]从中 trim 一个特定的字符:

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

最佳答案

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

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

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

我分析了数组[]、对象{}、正则表达式/(?:)/的不同内置方法,数字1.1,字符串"1",并发现了一个漂亮的RegExp对象方法,叫做test() .它的名称可以由所有可用字符组合而成,例如"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] }  

(在后者中特别注意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]

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

附言Yet Another Obfuscator

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

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

关于javascript - 什么是 JavaScript 的内置字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15978204/

相关文章:

javascript - Angular : Getting changed value into array

java - 混淆不适用于proguard

javascript - 如何保护 HTML5+PhoneGap 移动应用程序中的数据?

java - 如何将java程序交付给客户?

javascript - 使用不同的元素计数对值进行分组

javascript - 未捕获( promise )TypeError : Cannot read property 'data' of undefined React/Redux/Axios

javascript - 固定 html,body 时滚动到元素顶部

javascript - 抑制 javascript lint 错误

javascript - JS - 对象内的保留字

gwt - 对某些模型类禁用 gwt 混淆