Android 代码混淆之部分类不混淆的技巧

本文介绍了如何在Android开发中处理实现Serializable接口的类和特定JavaScript接口方法的混淆问题,引入NotProguard注解作为统一标识,简化ProGuard配置,确保关键代码段在混淆时不被删除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 在编写Android程序之后,我们通常要代码进行混淆编码,这样才能保证市场上我们的应用不会被别人进行反编译,然后破解,所以此时需要在发布正式版本的时候,有一些类事不能混淆的,比如实现了 Serializable 接口的,否则反序列化时会出错,这种情况下,我们可以简单的通过在proguard.cfg(Eclipse)添加配置来解决:

-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 接口的类及其成员都不进行混淆。

再比如JS调用的Android的JavaScriptInterface代码的方法,比如个别控制层类需要反射、个别实体类需要JSON化保存在本地,这些都是要防止没有明显共同特征的类被混淆,这时候,我们怎么做呢,一个个添加到proguard.cfg里面吗?这样会导致proguard配置文件杂乱无章,同时需要团队所有的成员对其语法有所了解。

下面针对这个问题,分享一个小技巧,通过给这些类、属性、函数添加共同的标识,然后统一过滤,最后解决上面所说的问题

1. 新建表示统一标识的注解 NotProguard
​
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/>
*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
public @interface NotProguard {
}

​

NotProguard 是个编译时注解,不会对运行时性能有任何影响。可修饰类、方法、构造函数、属性。

这里,可能会对注解(Annotation)有一些模糊,想了解更多关于注解相关的知识可以点击链接: Java Annotation 总结

2. 在 Proguard 配置文件中过滤被这个注解修饰的元素
# 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. 使用NotProguard让指定的域不进行混淆:

(1) 整个类不混淆

@NotProguard 
public class User {}

(2) 单个属性不混淆

@NotProguard 
public int id;

(3) 单个方法不混淆

@NotProguard
public boolean isValid() {
…
}

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

*关于混淆*

混淆一般在 Release 模式生效,主要有三个作用:

(1) 压缩、优化、删除代码;

(2) 一定程度上提高反编译后被读懂的难度;

(3) 通过删除代码功能实现的特殊作用。

比如在  Proguard 语法及常用 proguard.cfg 代码 中介绍的利用 Progurad 使得线上版本不打印 Log.d 和 Log.v 的技巧,防止调试的敏感信息被泄露。

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

关于 Proguard 基础可参考:

Proguard 语法及常用 proguard.cfg 代码

ProGuard 的作用、使用及 Bug 分析

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值