用零宽度字符混淆 JavaScript - 利弊?

逆向工程 混淆 javascript
2021-06-18 02:32:08

这来自对 StackOverflow 上关于 JavaScript 变量的一个问题的评论:为什么 ◎☺ 和 ☺ 不是有效的 JavaScript 变量名?

JavaScript 接受零宽度字符作为有效的变量名,例如所有这三个变量都有不同的名称,但在视觉上是相同的:

var ab, /* ab */
    a‍b, /* a‍b */
    a‌b; /* a‌b */

这是上述三个正在使用的变量JSFiddle示例。

作为 JavaScript(和其他支持语言)的混淆技术,这样做的利弊是什么?

4个回答

好吧,在您自己的程序中,这可能没问题。但在公司环境中,如果没有非常好的文档和/或团队连续性,它是一个维护噩梦。在我的经验中,这两种情况似乎都不那么普遍。

我认为一个更普遍的问题可能是,“混淆技术真的那么有用吗?” 我可以理解为了页面加载目的而缩小。但是隐藏来源似乎没有意义。你要么认为你有一些以前从未做过的聪明算法。如果是这样,也许 JS 不是它的语言,因为真的没有办法完全隐藏它。或者你试图变得狡猾并通过默默无闻来尝试一些安全,通常是一个坏主意。

在以下问题中提出了一个很大的缺点:

  • 当遇到这样的代码时,哪些 JavaScript 解释器会崩溃?
  • 这是可以接受的吗?

一个简单的普通混淆器应该在不破坏一些 JavaScript 解释器的情况下产生可接受的钝化代码。

如果真的想在变量名中使用零宽度字符,它将被包含在代码混淆过程中(生成的 js 文件应该只在浏览器版本检查之后加载。)。这样,开发人员就不必处理原始源代码中的零宽度字符。

使用零宽度字符对变量名称进行反混淆与重命名变量一样简单。作为反混淆过程的一部分,您无论如何都会这样做,因为您推断变量背后的意图并为它们提供有意义的名称。因此,这种技术最多可能会提示读者进行初始重命名。额外的反混淆成本可以忽略不计。这是不值得的,有没有优势abc,...

也打破了一些美化者(但不是全部)。例如,通过 JS Beautifier 运行您的代码:

   var ab = "Hello, world!",
       a‍ b = "Completely different string!",
       a‌ b = "Yet another completely different string!";

document.getElementById('result1').innerHTML = ab;
document.getElementById('result2').innerHTML = a‍ b;
document.getElementById('result3').innerHTML = a‌ b;

(注意“a”和“b”之间的空格。)

你可以争辩说这是一个利弊。根据您编写代码的确切程度,看到随机空间被注入可能会更加令人困惑。另一方面,它也提醒读者某些事情肯定发生了。