反编译器字节码和混淆器

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

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

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

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

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

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

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

免费解决方案

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

付费解决方案

虽然免费产品可能只更改类方法名称,但付费产品通常会提供更多function

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

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

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

  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%可能是死代码。

那么我试过的球员是谁?

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

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

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

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

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

我希望这能有所帮助..

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

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

为什么Java中允许使用此function

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

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

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

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

祝你好运。

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

java类文件基于规范,所以任何人都可以读入它。 像JD-GUI这样的工具会轻易地侵入您的源代码。 它本身不是一个“function”。 虽然不可能进行100%逆向工程,但大多数代码都可以进行逆向工程。

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

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