反编译器字节码和混淆器

时间:2012-10-27 08:48:17

标签: java

我们可以从java字节码完全反向设计源代码吗?为什么Java中允许使用此功能?java反编译器对反混淆器的成功程度如何?

4 个答案:

答案 0 :(得分:8)

我知道这个问题已经过时但我一直在寻找一个可靠的答案,直到我找不到任何东西。 所以在这篇文章中,我总结了一些模糊J2EE JAR的努力。 看来,到2014年(写作时间),那里的选择并不多。 如果您稍后阅读此评论,那么事情可能已经改变或修复。 当我想到为什么时,我开始意识到整个混淆工作给人一种虚假的安全感。不要误解我的意思。它确实增加了一定程度的安全性,但没有我希望的那么多。 我将尝试预览我发现的解释自己。我的推荐是个人的,其他人可能不同意。

所以首先:Java中的混淆是在保持其原始功能的同时采用字节码并使其可读性较低(当然使用反编译器)的过程。我们能做什么,Java作为一个交换器,必须保持其字节码暴露。如果类文件落入坏人手中,则运行混淆器作为安全措施。混淆的结果是反向映射文件和带有混淆类的JAR。反向映射文件用于执行堆栈跟踪读取(a.k.a re-trace)或将字节码恢复为其原始形状。模糊类的运行时性能命中率不应超过10%(但这实际上取决于您在代码中执行的操作)。

但是有一个很大的“但是”。混淆将扰乱你的代码,但它不会使它成为防黑客。请记住,你只会花时间,坚定的黑客会找到一种方法将你的字节码反向工程为纯算法。

恕我直言:隐藏敏感代码的最好方法就是把它淹没在一堆无意义的代码中。

一些黑客会尝试修改你的字节码(通过代码注入)来帮助他们实现目标。一些混淆器提供额外级别的JAR强化,使其更难修改。

去混淆器和反编译器:我最喜欢的Java反编译器是JD-GUI。然而,当谈到去混淆器时,我发现市场很空洞。大多数工具都会要求您提供一个提示(用于加密源JAR的混淆工具),但它们都没有真正提供结果(其中一些甚至在尝试解密JAR时崩溃)。它们是低维护的开源项目。我甚至找不到付费应用程序来进行体面的去混淆。如果你有所了解,请告诉我。

免费解决方案

有开源的免费混淆器,它们通常简单地重命名类/方法名称,使其成为一个字母方法(即从printUsage(String params)到(String p))。 正如这里暗示的那样,它们甚至可以删除调试信息以使其更加困难。 (调试信息保存在每个Java方法字节码的末尾,包含:行号,变量名等)。 这是一个很好的努力,但是一个带有调试器的Java开发人员可以很容易地推断出每个参数的用途,同时进行一些实时运行。 一个很好的开源混淆器是ProGuard,但还有几个工具。 然而,如果你真的是安全狂热的话,你可能会想要更强大的东西。更强烈要求更多的功能(和更多的钱),这导致我们下一个项目:

付费解决方案

虽然免费产品只能更改班级方法名称,但付费产品通常会提供更多功能

  1. 代码/流混淆:这将改变方法代码并注入空循环/死代码/混淆切换表等。他们中的一些人甚至可能加扰异常表内容。混淆强度通常决定输出大小。 注意:关于代码混淆:我故意避免了我的评论中的细节。我看到和分析的一些字节码暴露了他们的混淆方法,我希望保护他们的IP。我对谁使用更好的算法有一个看法。如果您想知道,请与我联系。

  2. 类/方法重命名:这很明显,我们在免费混淆中讨论过它。某些产品将重命名类名,然后递归搜索该类的反射用法并修复它们。付费产品甚至可以为同一目的重命名Spring / Wink配置文件(在反射中重命名)。 字符串加密:对于代码中的每个字符串“like this”,它会将其加密到某个级别并将密钥保存在某处(在类常量表/静态块/新方法或任何其他方法中)。

    < / LI>
  3. 调试信息:剥离部分或加扰。其中很多将删除行号信息。 class

  4. 强化:各种方法,比如在类/方法的开头注入一些签名方案,确保局外人不能轻易修改JAR并运行它。对Android或applet来说不那么重要,因为大多数都是数字签名的无论如何。一些将硬化与水印结合起来跟踪盗版。但我们都知道软件的反盗版方法注定要被黑客入侵。几十年来,游戏行业一直受到影响,直到网络订阅到来。

  5. 由于这里的大多数产品都使用Java,因此其中一些产品提供Android集成。这意味着它不仅会混淆Java(dalvik)代码,还会操纵Android的清单文件和资源。一些提供反调试:删除Android应用程序中的调试标志。

  6. 很好的GUI应用程序,用于配置各种选项,并可能对给定的日志文件进行重新恍惚。 UI通常用于生成配置文件。使用这样的文件,您可以稍后重新进行模糊处理,甚至可以从命令行重新进行模糊处理。

  7. 增量构建支持 - 这对于经常发布产品更新/修复的大型组非常有用。您可以告诉混淆器保留旧的“混淆”结果,并随机混淆“新”代码流。通过这种方式,您可以确保对方法签名的影响最小。如果没有这个标志,JAR上的每个混淆周期都会产生不同的输出,因为大多数优秀的工具在算法中使用某种程度的随机性。

  8. CLI和分布式构建。当你独自工作时,运行混淆器不是一个大问题。您需要将混淆器配置为相关选项并运行它。但是,在企业中,当将混淆器集成到构建脚本时,事情会有所不同。还有另一个复杂程度:构建引擎任务(如ant / maven)和许可证管理。我测试的所有混淆器都有命令行API的好消息。在分布式构建环境中,存在用于支持并发构建需求的构建机器的集群/池。群集是动态和虚拟的,机器正在上升或下降,具体取决于各种条件。一些混淆产品基于cpuID许可证文件或主机名。这可能会给构建团队带来很大的挑战。有些人更喜欢本地浮动许可服务器。有些可能需要公共许可证服务器(但那时:并非所有构建服务器场都可以访问公共Internet)。有些提供多站点许可证(在我看来是最好的)。

  9. 一些提供代码优化 - 代数等效和丢弃死代码。它很好,但我相信今天的JDK在优化字节码方面做得很好。确实,死代码可以让你下载更大,但是今天的带宽不足以解决问题。我也想相信在软件今天20:80拇指规则仍然适用。在任何申请中,无论如何,20%可能是死代码。

  10. 那么我试过的球员是谁?

    • Zelix.com的KlassMaster--业内历史最悠久的之一。然而,他们每年发布3-4次固体产品。这已经持续了几十年(自1997年以来)。 Zelix提供良好的电子邮件支持并及时回复我的所有电子邮件。他们有一个很好的GUI客户端来混淆JAR或创建配置文件以供将来混淆。它简单而光滑。没什么特别的。他们为所有标志提供了简单易读的在线文档。它们支持引擎应该混淆的“排除”和“包含”正则表达式。我最喜欢他们的过程的是它还为异常表添加了“噪音”。它使方法异常处理更加混乱。它们的流动混淆器强​​度非常好,可以配置在3种可能的水平(轻,中,侵略)之间。我喜欢的另一个功能是它们为调试信息剥离(在线行号或在线局部变量或两者)提供的微调。 Klass Master不提供任何 专用的Android标志或反篡改方法。他们的许可模式非常简单:一个文本文件放在KlassMaster主JAR附近。他们还支持增量混淆。

    • 来自secureTeam.net的JFuscator:虽然secureTeam也有.Net工具,但我专注于他们的Java工具功能。他们的(基于Swing的)GUI工具看起来不错,但在尝试最简单的混淆任务时会崩溃。错误总是一样的:读取&#39; /opt/sun-jdk1.7.0_55/jre \ lib \ rt.jar&#39;时出错。原因:&#39;&#39; /opt/sun-jdk1.7.0_55/jre \ lib \ rt.jar&#39;:没有这样的文件或目录&#39; 。当然,我在/opt/sun-jdk1.7.0_55/jre中安装了我的Java。你可以想象他们根本不希望linux反斜杠结构。我通过电子邮件联系了secureTeam.net支持,其中存在轻微的“路径”问题。他们问我是不是一个linux用户,在我回复之后,他们从未回复过我的电子邮件。我也试过他们的网站在线聊天:没有回应。所以我停止了测试。没有进一步的结果,我无法检查混淆的字节码质量。从他们的网站看来,他们似乎有防篡改方法,字符串操作,方法重命名和其他一些功能。

    • GuartIt4J(作者:Arxan.com):Arxan在移动环境中是相当稳固的玩家,因此他们提供Android混淆器,这当然适用于Java。他们拥有最灵活的引擎之一。他们提供代码混淆,字符串加密等相似您可以定义代码混淆的复杂性。它只是一个整数。越高 - 你的方法越长。当然,你必须小心不要超过每个类的JVM 64KB限制......正如我之前所说,隐藏敏感代码的最佳策略之一不是加密它,而是将其注入大量垃圾中。这正是GuardIt所做的。它也可以以与方法异常表相同的方式进行爆炸。我设法在其异常表中创建了一个包含100个异常的方法(前混淆器为5)。他们错过了什么:他们的重新追踪计划不是所提供的主要JAR的一部分。然而,他们非常友好地向我发送了一个示例Java程序,该程序在给定反向映射文件和日志的情况下执行重新跟踪。它们不支持增量混淆,也不支持调试信息的灵活性。调试信息剥离是全部或全部。观察输出JAR,你将注入大量的条件和跳跃。不用考虑,爆炸的班级规模有其性能。在某些方法中,我在应用长混淆时测量了几乎50%的性能(在这些方法中没有I / O)。所以推断代码需要付出代价。(从400个操作码 - 我在混淆后达到了2200个操作码)。 JD-GUI,我的解编译器无法打开这样的类并崩溃(IndexOutOfBoundException)。它们还提供完整的类加密。这意味着该类是使用一些对称密钥加密的,这需要一个特殊的(或自定义编写的)类加载器来在内存中打开它。这是一种反篡改机制以及隐藏代码。请记住,如果没有类加载器帮助,JVM就无法运行该类。它是一个很好的功能,但秘密密钥和引导加载程序JAR可能就在那里。如果他得到加密的JAR,黑客最终会得到他的手并解密课程。然而,这是普通黑客需要通过的另一个障碍。我在这里不喜欢的是许可证文件策略:受限于CPUid或需要安装浮动许可证服务器。

    • SecureIt(由Allatori.com提供):SecureIt提供所有通用代码混淆,字符串加密,重命名等。除了标准的混淆方法之外,它们还提供某种水印,这是一种防篡改/盗版方法。他们支持Android和JavaME(现在谁使用ME ?!)。它们支持增量混淆。关于配置SecureIt的一点需要注意:它是所有命令行。这次没有GUI工具。就个人而言,我不介意命令行工具,只要它们带有良好的文档。幸运的是,他们有一个非常好的文档和丰富的API,如果你愿意,可以调整许多标志。您可以使用它们的工具(也是命令行)重新跟踪。他们不能混淆异常表。我没有检查他们的许可机制。

    • DashO(由Preemptive.com提供):DashO obfuscator可能会被记住,因为它可以作为您可以获得的最佳UI工具(创建您的配置)。与SecureIt一样,他们使用异常表混淆,但它们具有所有其他所需功能(以及CLI,Spring框架和gradle / ant集成,甚至是eclipse插件)。好吧,他们确实记录了一个try-catch混淆器(与异常表混淆器相同),但它只是对引擎的推荐。当我尝试它时,它对异常表没有影响。正如我所说,GUI工具非常棒,并且嵌入了重新跟踪。他们还提供某种应用程序签名和水印作为防篡改/盗版机制。 DashO提供卓越的Android集成,并在其产品中结合了分析上传的大门。您实际上可以跟踪您的申请。注入崩溃日志上传程序并向JAR报告代码。然而,这不是混淆的范围 - 这是一个完全不同的代码注入产品。他们有很好的支持。在线和通过电话。他们的许可计划基于每月订阅或一次性购买付款。有点不同于其他人。他们使用浮动许可证服务器来支持大型环境。

    我希望这有点帮助......

答案 1 :(得分:7)

  

我们可以完全从java字节码反向设计源代码吗?

不完全,因为源代码的某些方面(如空格,局部变量名和注释)不会保留在字节码中。否则,是的 - 虽然您无法获得完全相同的源代码,但您几乎总能获得至少可以编译回相同字节码的内容。

  

为什么Java中允许使用此功能

它不是“允许”,因为它“没有被阻止”。它并没有被阻止,因为这样做是不可能的 - 代码必须可以运行才能有用;如果代码是可运行的,那么它是可分析的;如果它是可分析的,那么通过充分的分析,它可以转换回源。

  

java反编译器对混淆器有多成功?

不是很好。我见过的大多数混淆器(尤其是ProGuard)主要用于删除有意义的函数和类名;通常不会尝试模糊逻辑本身。

答案 2 :(得分:5)

可以这些天从二进制文件中获取源代码。尽管通过Java的字节码获得的源代码更具可读性,但是混淆将使其稍微不可读。它不仅仅是Java可以反向设计代码。如今,即使是C / C ++(使用适用于IDA Pro的Hexrays插件)也可以反编译为源代码。 Obfuscaters会让人难以阅读,但并非不可能。没有什么能够从智能且有能力的逆向工程师中拯救您的程序。 :)

祝你好运。

答案 3 :(得分:1)

  

我们可以从java字节码完全反向设计源代码   ?

java类文件基于一个规范,所以任何人都可以读入它。像JD-GUI这样的工具很容易就会破坏您的源代码。它本身不是一个“功能”。虽然不可能进行100%逆向工程,但大部分代码都可以进行逆向工程。

  

java反编译器对混淆器有多成功?

取决于。混淆器的要点是删除任何有意义的名称,并试图在代码中引入混淆而不影响性能。大多数开发人员都非常擅长混淆代码:) Pro-guard很擅长混淆。