使用 ProGuard 混淆私有字段

Posted

技术标签:

【中文标题】使用 ProGuard 混淆私有字段【英文标题】:Obfuscate private fields using ProGuard 【发布时间】:2015-08-12 02:51:30 【问题描述】:

我在带有 Gradle 1.2.3 的 androidStudio 1.2.1.1 中使用 ProGuard。

我的 Gradle 的发布版本配置如下:

minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
shrinkResources true

我希望对类的私有字段进行混淆处理。

这是我的 proguard 配置文件(经过多次尝试):

-allowaccessmodification
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
-verbose
[...]

但在使用 AndroidGuard 中的androdd 反编译后,我得到了:

private com.google.android.gms.common.api.GoogleApiClient googleApiClient;

我知道这种混淆的使用是有限的,但我希望 googleApiClient 被 ProGuard 重命名。该怎么做?

这里是refcard。

有什么办法可以和-keepclassmembernames相反吗?

【问题讨论】:

googleApiClient 是唯一未混淆的字段还是所有字段都相同? 我希望所有私有字段都使用这个。 【参考方案1】:

从中获得: How to tell ProGuard to keep private fields without specifying each field

根据ProGuard documenation,通配符匹配任何 字段。

最重要的是,您可以使用否定符 (!)。 (http://proguard.sourceforge.net/#manual/usage.html)

属性名称可以包含 ?、* 和 ** 通配符,它​​们可以是 前面有!否定句。

我在这个领域不是很有经验,所以这是一个猜测,但更容易写在新的评论中。像这样的东西应该可以完成这项工作(未测试):

-keepclassmembers class *  //should find all classes 
    !private <fields>;    
    <methods>;
    <init>; //and keep every field, method, constructor apart from private fields

也许你可以这样使用,但首先不确定它如何与否定符一起使用:

-keepclassmembers class *  //should find all classes 
    !private <fields>;    
    *; //should exclude everything except private fields, which should be obfuscated.

【讨论】:

我使用了-keepclassmembers class my.package !private &lt;fields&gt;; protected &lt;field&gt;; public &lt;fields&gt;; &lt;methods&gt;; 并得到了我想要的:名称为abc 等的字段。我知道这与否定者有关,感谢您将我带到正确使用。我会根据我的个人用途进行改进,但这就是我一直在寻找的答案。 这是我的最终 ProGuard 文件,可以运行 bug Android bug #78377:gist.github.com/shkschneider/a1c81780cd1f35a7037d 感谢您的回复和奖励!我很高兴您根据我的提示进行了锻炼,也感谢您提交到 github,这对我来说也是一次很好的体验。

以上是关于使用 ProGuard 混淆私有字段的主要内容,如果未能解决你的问题,请参考以下文章

DexGuard/Proguard 混淆注释值

如何在 Eclipse 中混淆我的代码? (安卓)

使用混淆ProGuard压缩代码和资源/减少方法数量

Proguard 混淆导致 java.lang.IllegalArgumentException:类声明多个名为“a”的 JSON 字段

为 Proguard 指定类名以避免混淆

Android 代码混淆规则