Proguard 保留公共类、字段和方法

Posted

技术标签:

【中文标题】Proguard 保留公共类、字段和方法【英文标题】:Proguard keep public classes, fields and methods 【发布时间】:2018-07-08 15:05:12 【问题描述】:

我使用 Kotlin,并且有很多内部类。 我想混淆和缩小除所有 public 类之外的所有内容。

Proguard 规则:

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

-optimizationpasses 5
-overloadaggressively
-repackageclasses ''
-allowaccessmodification

-keep public class * 
    public <methods>;
    public <fields>;

不幸的是,-keep public class * 表现得很防御并保留所有名称,内部类也是如此。

【问题讨论】:

【参考方案1】:

你的规则太宽泛了。

    与“-keepmembers”和“-keepclasseswithmembers”规则的组合相比,带有嵌套规则的单个“-keep”更广泛 完整的“-keep”规则意味着“永远不要更改该方法的字节码” 被保留的类和方法引用的类不能被删除、重命名或重新打包

你的规则中的这一行保留了所有你的类和接口:

-keep public class * 

我的意思是所有这些。无论他们是否有公共成员。

改用-keepclasseswithmembers

因为这几行


    public <methods>;
    public <fields>;

您的所有公共方法都将保持不变,这意味着您的公共方法引用的重新打包重命名方法无法执行!

如果您希望至少进行一些重新打包,请确保允许优化(因为重新打包是作为优化步骤的一部分执行的):

-keepmembers,allowoptimization public class * 
    public <methods>;
    public <fields>;

除了重新打包之外,这还将允许一些内联(这反过来又有助于删除提供内联方法的类)。

此外,对于 android 应用程序,您最好将其重新打包到主包(应用程序包或其中包含最多不可移动类的包)而不是空包 ('')。这是因为一些“导出”的类(活动、视图、服务、其他东西,从 xml 文件中引用)不能被 Proguard 移到它们的包之外——aapt 动态生成特殊规则来防止这种情况发生。将访问模式从公共更改为受保护/私有的优化过程部分变得更加高效,可以将更多的类放在一个包中。

我想混淆和缩小除所有公共类之外的所有内容。

坏主意。你真的应该尽可能地混淆,尤其是公共类。如果你限制混淆,重新打包也受到限制!它会重命名它们!

尽可能制定最具体的规则。

如果要防止缩水:

-keep,allowoptimization,allowobfuscation public class com.example.Example

如果您想防止重命名,但允许剥离未使用的类:

-keep,allowoptimization,allowshrinking public class com.example.*

一般来说,避免通配符规则(裸*)和-keep规则:更喜欢特定类的规则和-keepmembers/-keepclasseswithmembers


混淆应用程序和库的正确方法是完全不同的,但它们有一些共同点——你不应该关心公共方法/类;只是尽可能地混淆/缩小/重新打包,直到更多的东西会破坏它。

对于应用程序,您应该尽可能地混淆/重新打包。如果您不知道哪些包可以安全混淆,请从opting known safe packages into obfuscation 开始。

对于库——不要将 Proguard 应用于库本身(除非您试图通过隐蔽来实现安全性)。使用 aar 格式的特性——consumer proguard files——允许提供规则“段”,在最终的应用程序混淆过程中应该遵循这些规则。

【讨论】:

以上是关于Proguard 保留公共类、字段和方法的主要内容,如果未能解决你的问题,请参考以下文章

Proguard 不会保留班级成员的枚举

如何使 ProGuard 保留整个(整个)类(带有字段和方法)而不使用“-keep”

如何使用 ProGuard(或任何其他方式)隐藏库 Jar 中的公共类?

如何使用箭头函数(公共类字段)作为类方法?

如果在proguard中包含带有注释的字段,如何保持类的成员不受影响

如何告诉 proguard 保留枚举常量和字段