Android中如何阻止ProGuard计算数学表达式并保留未使用指令
保留ProGuard处理中的原始数学表达式与未使用代码
ProGuard的默认优化逻辑确实会做常量折叠和死代码移除——这就是为什么你的表达式Integer.MIN_VALUE+Integer.MAX_VALUE+1被直接计算成了0,未使用的变量也被简化重命名了。如果想保留原始代码形式来实现混淆需求,你可以试试下面几种方法:
阻止常量折叠:ProGuard只会对编译期可确定的常量表达式进行计算,所以我们可以把表达式包装成一个简单的方法,让ProGuard无法在优化阶段直接算出结果:
private static int getJunkValue() { return Integer.MIN_VALUE + Integer.MAX_VALUE + 1; } // 使用这个方法代替直接写表达式 Integer JunkCode6666 = new Integer(getJunkValue());除非你开启了极端激进的内联优化,否则ProGuard不会去解析这个方法内部的计算逻辑,只会保留方法调用和原始表达式。
保留未使用的变量:如果
JunkCode6666是未被实际使用的变量,ProGuard默认会把它当作死代码移除。要保留它,有两种方式:- 使用
@Keep注解(需要依赖AndroidX或Support库的注解包):import androidx.annotation.Keep; // ... @Keep Integer JunkCode6666 = new Integer(getJunkValue()); - 在ProGuard配置文件(
proguard-rules.pro)中添加针对性的保留规则:
记得把-keepclassmembers class com.yourpackage.YourTargetClass { java.lang.Integer JunkCode6666; }com.yourpackage.YourTargetClass替换成这个变量所在的实际类的完整路径。
- 使用
全局调整优化规则(不推荐):如果你想全局禁用常量折叠,可以在
proguard-rules.pro中添加:-optimizations !code/simplification/constant但注意这会影响所有代码的优化,可能导致APK体积增大、性能略有下降,所以优先推荐前面的局部解决方案。
另外提一句:这类“垃圾代码”式的混淆其实对抗反编译的效果比较有限,经验丰富的逆向工程师很容易识别出无意义的代码,但如果你的需求就是保留原始表达式形式,上面的方法完全可以满足。
内容的提问来源于stack exchange,提问作者Khaled Rimawi
相关产品推荐
相关产品推荐

