【问题标题】:Do you obfuscate your commercial Java code? [closed]您是否混淆了您的商业 Java 代码? [关闭]
【发布时间】:2010-09-05 22:34:17
【问题描述】:

我想知道是否有人在他自己的商业产品上使用商业/免费的 java 混淆器。我只知道一个项目实际上在发布的 ant 构建步骤中有一个混淆步骤。

你会混淆吗?如果是这样,你为什么要混淆?

这真的是保护代码的一种方式,还是只是让开发人员/经理感觉更好?

编辑:好的,我要准确地说出我的观点:您是否为了保护您的 IP(您的算法,您在产品中投入的工作)而进行混淆处理?出于安全原因,我不会混淆,这感觉不对。所以我只是在谈论保护您的应用程序代码免受竞争对手的侵害。

@staffan 说得好:

远离链接代码流的原因是其中一些更改使 JVM 无法有效地优化代码。实际上,它实际上会降低应用程序的性能。

【问题讨论】:

标签: java obfuscation


【解决方案1】:

我想这真的归结为 你的 Java 代码是做什么用的、它是如何分布的以及你的客户是谁。我们不会混淆任何东西,因为我们从来没有找到一个特别好的东西,而且它往往比它的价值更麻烦。如果有人可以访问我们的 JAR 文件并且知道能够嗅探其中的内容,那么他​​们可以做的事情远比窃取我们的源代码更令人担忧。

【讨论】:

    【解决方案2】:

    我使用 proguard 进行 JavaME 开发。它不仅非常擅长使 jar 文件更小(对于移动设备而言必不可少),而且它还可以作为一种更好的方式来编写特定于设备的代码,而无需使用对 IDE 不友好的预处理工具,例如天线。

    例如

    public void doSomething()
    {
        /* Generated config class containing static finals: */
        if (Configuration.ISMOTOROLA)
        {
            System.out.println("This is a motorola phone");
        }
        else
        {
            System.out.println("This is not a motorola phone");
        }
    }
    

    这将被编译、混淆,并且类文件最终就像您编写的一样:

    public void doSomething()
    {
        System.out.println("This is a motorola phone");
    }
    

    因此,您可以使用代码变体来解决 JVM/库实现中的制造商错误,而无需增加最终的可执行类文件。

    我相信一些商业混淆器在某些情况下也可以将类文件合并在一起。这很有用,因为您拥有的类越多,您在 zip (jar) 文件中的大小开销就越大。

    【讨论】:

    • 实际上,对于条件代码,Java 规范要求编译器删除这样的死代码,前提是条件是通过静态错误表达式分配的。这是 Proguard 所能做的。
    【解决方案3】:

    如果您进行混淆处理,请远离那些通过更改代码流和/或添加异常块等来修改代码的混淆器,以使其难以反汇编。要使代码不可读,通常只需更改所有方法、字段和类的名称即可。

    远离更改代码流的原因是,其中一些更改使 JVM 无法有效地优化代码。实际上,它实际上会降低应用程序的性能。

    【讨论】:

    • 对我来说听起来像是过早的优化。
    【解决方案4】:

    今年我花了一些时间尝试各种 Java 混淆器,我发现其中一个比其他混淆器领先很多:JBCO。不幸的是,它设置起来有点麻烦,并且没有 GUI,但就它产生的混淆程度而言,它是无与伦比的。你试着给它一个简单的循环,如果你的反编译器在加载它时没有崩溃,你会看到这样的:

        if(i < ll1) goto _L6; else goto _L5
    _L5:
        char ac[] = run(stop(lI1l));
        l7 = (long)ac.length << 32 & 0xffffffff00000000L ^ l7 & 0xffffffffL;
        if((int)((l7 & 0xffffffff00000000L) >> 32) != $5$)
        {
            l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
        } else
        {
            for(l3 = (long)III & 0xffffffffL ^ l3 & 0xffffffff00000000L; (int)(l3 & 0xffffffffL) < ll1; l3 = (long)(S$$ + (int)(l3 & 0xffffffffL)) ^ l3 & 0xffffffff00000000L)
            {
                for(int j = III; j < ll1; j++)
                {
                    l2 = (long)actionevent[j][(int)(l3 & 0xffffffffL)] & 65535L ^ l2 & 0xffffffffffff0000L;
                    l6 = (long)(j << -351) & 0xffffffffL ^ l6 & 0xffffffff00000000L;
                    l1 = (long)((int)(l6 & 0xffffffffL) + j) & 0xffffffffL ^ l1 & 0xffffffff00000000L;
                    l = (long)((int)(l1 & 0xffffffffL) + (int)(l3 & 0xffffffffL)) << 16 & 0xffffffff0000L ^ l & 0xffff00000000ffffL;
                    l = (long)ac[(int)((l & 0xffffffff0000L) >> 16)] & 65535L ^ l & 0xffffffffffff0000L;
                    if((char)(int)(l2 & 65535L) != (char)(int)(l & 65535L))
                    {
                        l = (long)III << 50 & 0x4000000000000L ^ l & 0xfffbffffffffffffL;
                    }
                }
    
            }
    
        }
    

    你不知道 Java 有 goto 吗?好吧,JVM 支持它们 =)

    【讨论】:

    • 在机器代码级别(因此在字节码中,它只是机器独立的机器代码)所有计算机都使用 goto。循环只是 goto/condition 结构。顺便说一句,continue 和 break 只不过是使用标签的受限 goto(有时标签是推断的,而不是显式的)。
    • JBCO 的缺点是它的研究质量代码。我什至无法让它在简单的测试用例上运行,而且文档几乎不存在。
    • 我想再补充一点……如果这真的是“简单循环”的结果,那么它会付出高昂的效率代价,以换取逆向工程代码难以辨认和晦涩难懂.
    【解决方案5】:

    我使用ProGuard 并强烈推荐它。虽然混淆确实可以保护您的代码免受临时攻击者的攻击,但它的主要好处是最大程度地减少了删除未使用的类和方法并将所有标识符缩短为 1 或 2 个字符的影响。

    【讨论】:

    • 我想知道你有没有混淆过广泛使用反射的代码?你有问题吗?
    • @user384706:是的,我确实将 ProGuard 与广泛使用反射的代码一起使用。除了简单使用Class.forName()之外,您必须对其进行配置以保留反映的项目。
    【解决方案6】:

    我认为在大多数情况下混淆是没有意义的:即使有完整的源代码,通常也很难弄清楚到底是什么意图(假设没有 cmets,也没有对局部变量有意义的名称——这就是从字节码重新生成源时的情况)。混淆只是装饰蛋糕。

    我认为开发人员,尤其是他们的经理往往会过分夸大有人看到源代码的风险。虽然好的反编译器可以生成漂亮的源代码,但使用它并非易事,并且相关的成本(更不用说法律风险)高到足以使这种方法很少有用。我只反编译以调试闭源供应商产品的问题(数据库抽象层中的死锁,呃)。 我认为字节码实际上被混淆了,但我们仍然发现了根本问题——这是一个实际的设计问题。

    【讨论】:

      【解决方案7】:

      我认为旧的(经典)混淆方式正在逐渐失去其相关性。因为在大多数情况下,经典混淆器会破坏堆栈跟踪(它不利于支持您的客户)

      现在的重点不是保护某些算法,而是保护敏感数据:API 登录名/密码/密钥,负责许可的代码(盗版仍然存在,尤其是西欧,俄罗斯,亚洲,恕我直言),广告帐户ID 等。

      有趣的事实:我们在字符串中拥有所有这些敏感数据。实际上,字符串约占我们应用程序逻辑的 50-80%。 在我看来,混淆的未来是“字符串加密工具”。

      但现在“字符串加密”功能仅在商业混淆器中可用,例如:AllatoriZelix KlassMasterSmokescreenStringer Java Obfuscation ToolkitDashO

      注意 我是 Licel LLC 的首席执行官。 Stringer Java 混淆器的开发者。

      【讨论】:

      • 确实如此。现在的开源项目太多了,没人关心别人的商业源代码。重点是保护一些(小)特定信息,例如 PRIVATE KEYS 和 PASSWORDS。
      猜你喜欢
      • 1970-01-01
      • 2010-10-20
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多