这里是应用程序安全工程师。编译Java代码时,我们使用KlassMaster对其进行模糊处理,并删除行号(请参阅KlassMaster文档),原因是手摇晃晃的解释“使逆向工程更加困难”。 -检查是否实际上增加了反向工程难度,足以保证尝试调试无用的堆栈跟踪所浪费的开发时间。

评论

请注意。它说它打算用于beta版本。该功能听起来不适合生产。就我个人而言,我会等到它通过测试之后再进行。获得用户认可;并修正了任何被拒登的内容。评论怎么说?

@TamusJRoyce这句话似乎特定于增加字节码的大小,不是吗?此外,我们使用的是REMOVE功能,而不是SCRAMBLE功能。

#1 楼

剥离行号对逆向工程代码的难度影响最小。如果它引起您的问题,我建议您将其禁用。

Col-E的答案是红色的鲱鱼,因为反向工程师很容易将合成行号插入字节码以消除堆栈跟踪(假设它们首先不只是重命名方法)。这些显然与原始的源代码行号不匹配,但是,如果您想要的只是消除堆栈跟踪歧义的一种方法,那很容易实现。 Javac不执行GCC所做的那种优化,这就是为什么可以如此清晰地反编译未混淆的Java。我知道Javac在编译时所做的唯一值得注意的优化是内联和简化常量表达式。

评论


谢谢!您可以扩展第一段吗?分享您的一些专业知识,以了解为什么KlassMaster会费心删除行号,以及为什么它并没有真正减慢您的速度?

– Mike Ounsworth
18年9月7日在1:45

@Mike可能是出于“不会伤害”的思维方式。它们很容易剥离,因此您也可以这样做。至于影响为什么可以忽略不计,简而言之,就是只有在代码已经被混淆的情况下,行号才非常有用,即使这样,反编译代码也变得更加漂亮。对于混淆的代码,它们可能会给您一些提示,以了解原始代码的外观,但是通常不值得花精力去看它们,而且ZKM往往使事情变得太多,以至于无论如何也是如此。

–锑
18-09-7 at 1:47

值得一提的是,我写的反编译器Krakatau完全忽略了行号表,即使它们存在也是如此。

–锑
18年9月7日在1:48

接受您的评论多于实际答案:P

– Mike Ounsworth
'18 Sep 7'在1:58

同意考虑反向工程时,静态编译和运行时优化存在很大差异。运行时优化是发生类似gcc的优化的地方。但这没有意义/不重要。

– TamusJRoyce
18-09-23在12:31



#2 楼

KlassMaster文档实际上总结了原因相当不错的原因。

由于类com.mycompany.c通常会被混淆为包含名称为ab的许多重载方法,因此可以诊断问题并重现该问题。错误对于您的开发人员来说将是非常耗时的,而对于您的客户来说则将是非常沮丧的。我将重点关注以下四行:

at com.mycompany.c.a(c.java)
at com.mycompany.c.a(c.java)
at com.mycompany.c.b(c.java)
at com.mycompany.c.a(c.java)


显然,在这些stacktrace元素中,类始终是相同的c,但是该方法呢?第1、2和4行的方法名称为a,但问题是由于名称重载(多个具有相同名称但返回/参数类型不同的方法),您不能确定它们是否都指向同一方法。

这是行号出现的地方。由于您是具有源代码访问权限的开发人员,因此您可以轻松跳转到stacktrace提供的行号。攻击者没有源代码,但是攻击者可以轻松地查看类的字节码,以创建一个表,该表将不同的行号与其方法关联(更具体地讲,在方法字节码中出现问题的位置)。这将允许他们绕过名称重载的目的,因为他们可以在任何给定的stacktrace元素中查找与行关联的方法。

如果要删除行号,则攻击者无法采用任何给定的stacktrace元素并立即知道其链接到的方法。在这种情况下,攻击者的最佳选择是从堆栈跟踪中的已知位置开始,然后手动遵循字节码,以确定堆栈跟踪中显示的是哪种重载方法。如果反编译是您最优先考虑的问题,而不是上述情况,那么您应该保留调试信息。 Java反编译器甚至可以在混淆的程序集上生成相当准确的代码,而不管是否包含调试信息。