Proguard 部分类不混淆的技巧

简介:

一、场景

两年前在 Proguard 语法及常用 proguard.cfg 代码 中介绍过一些 Proguard 的基础知识,其中提到一些类不能混淆,比如实现了 Serializable 接口的,否则反序列化时会出错。这种情况我们可以简单的通过在 proguard-rules.pro 配置文件中添加配置,对于较早 Android 项目默认配置文件可能为 proguard.cfg,如下:

Java

1

2

3

4

5

6

7

8

9

10

-keepnames class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {

static final long serialVersionUID;

private static final java.io.ObjectStreamField[] serialPersistentFields;

!static !transient <fields>;

private void writeObject(java.io.ObjectOutputStream);

private void readObject(java.io.ObjectInputStream);

java.lang.Object writeReplace();

java.lang.Object readResolve();

}

表示所有实现了 Serializable 接口的类及其成员都不进行混淆。

但有时我们可能需要防止一些没有明显共同特征的类被混淆,比如个别控制层类需要反射、个别实体类需要 JSON 化存本地,这时我们怎么做呢,一个个添加到 proguard-rules.pro(或 proguard.cfg) 中吗?
这样会导致 proguard 配置文件变得杂乱无章,同时需要团队所有成员对其语法有所了解。

这里分享个小技巧,通过给这些类、属性、函数添加共同标识,然后统一过滤。

二、解决方法

1. 新建表示统一标识的注解 NotProguard

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package cn.trinea.android.common.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* NotProguard, Means not proguard something, like class, method, field<br/>

*

* @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2015-08-07

*/

@Retention(RetentionPolicy.CLASS)

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})

public @interface NotProguard {

}

NotProguard 是个编译时注解,不会对运行时性能有任何影响。可修饰类、方法、构造函数、属性。
关于注解更多的知识可见:Java Annotation 介绍及几个常用开源项目注解原理简析

2. 在 Proguard 配置文件中过滤被这个注解修饰的元素

Java

1

2

3

4

5

6

7

8

# keep annotated by NotProguard

-keep @cn.trinea.android.common.annotation.NotProguard class * {*;}

-keep class * {

@cn.trinea.android.common.annotation.NotProguard <fields>;

}

-keepclassmembers class * {

@cn.trinea.android.common.annotation.NotProguard <methods>;

}

表示不混淆被 NotProguard 修饰的类、属性和方法。

3. 使用

(1) 整个类不混淆

Java

1

2

@NotProguard

public class User {}

(2) 单个属性不混淆

Java

1

2

@NotProguard

public int id;

(3) 单个方法不混淆

Java

1

2

3

4

@NotProguard

public boolean isValid() {

}

这样我们便解决了每个类都需要在 proguard 配置文件中配置的问题。

三、关于混淆

混淆一般在 Release 模式生效,主要有三个作用:
(1) 压缩、优化、删除代码;
(2) 一定程度上提高反编译后被读懂的难度;
(3) 通过删除代码功能实现的特殊作用。
比如在 Proguard 语法及常用 proguard.cfg 代码 中介绍的利用 Progurad 使得线上版本不打印 Log.d 和 Log.v 的技巧,防止调试的敏感信息被泄露。

一些应用的代码可能从来都没混淆过,虽说这些代码实际价值可能不大,本身可能也是开源代码凑起来的,再者该破解的还是能破解,但本着做事要专业的态度,还是混淆吧。

关于 Proguard 基础可参考:
Proguard 语法及常用 proguard.cfg 代码
ProGuard 的作用、使用及 Bug 分析

四、杂谈

感谢不少朋友的关心,九月份博客会恢复正常更新。虽然很忙,还是抽空完善了 codeKK。
透露下下周 codeKK 会发布一个大功能模块,对,跟源码解析职位内推并列的顶级模块,相信会对大家有用,希望大家到时多支持。

目录
相关文章
|
6月前
|
算法 Java Android开发
Android安全性: 什么是ProGuard,它的作用是什么?
Android安全性: 什么是ProGuard,它的作用是什么?
205 1
|
6月前
混淆产生的问题
混淆产生的问题
53 10
ProGuard:保留包名,混淆类
ProGuard:保留包名,混淆类
230 0
ProGuard:类混淆,类的指定函数保留
ProGuard:类混淆,类的指定函数保留
103 0
ProGuard混淆时保留注释(@类内容)
ProGuard混淆时保留注释(@类内容)
171 0
|
安全 Android开发 数据安全/隐私保护
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
293 0
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
|
安全 Android开发 数据安全/隐私保护
【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(二)
【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(二)
167 0
【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(二)
|
安全 Java Android开发
【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(一)
【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(一)
238 0
 【Android 安全】DEX 加密 ( ProGuard 混淆 | -keepclassmembers 混淆效果 | -keepclasseswithmembernames 混淆效果 )(一)
|
安全 Java Android开发
【Android 安全】DEX 加密 ( Proguard keep 用法 | Proguard 默认混淆结果 | 保留类及成员混淆结果 | 保留注解以及被注解修饰的类/成员/方法 )
【Android 安全】DEX 加密 ( Proguard keep 用法 | Proguard 默认混淆结果 | 保留类及成员混淆结果 | 保留注解以及被注解修饰的类/成员/方法 )
398 0
【Android 安全】DEX 加密 ( Proguard keep 用法 | Proguard 默认混淆结果 | 保留类及成员混淆结果 | 保留注解以及被注解修饰的类/成员/方法 )