Android Proguard / ZKM 点滴记录
简介
Java代码是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理。
ProGuard是一个混淆代码的开源项目。它的主要作用就是混淆,当然它还能对字节码进行缩减体积、优化等
官网网址:http://proguard.sourceforge.net
详解
1、原理
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25%
2、语法 详见: http://proguard.sourceforge.net
输入输出选项
-include {filename} 从给定的文件中读取配置参数
-basedirectory {directoryname} 指定基础目录为以后相对的档案名称
-injars {class_path} 指定要处理的应用程序jar,war,ear和目录
-outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。
保留选项
-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称
-keepclassmembernames {class_specification} 保护指定的类的成员的名称
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}
优化
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontobfuscate 不混淆输入的类文件
-printmapping {filename}
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,…} 保护给定的可选属性,例如Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,Annotation,EnclosingMethod-renamesourcefileattribute {string} 设置源文件中给定的字符串常量
* android 通用实例 *
-injars dist/jpush-sdk-dev.jar
-outjars dist/jpush-sdk-release.jar
-libraryjars /Users/zhangfl/local/android-sdk-macosx/platforms/android-23/android.jar-ignorewarnings # 忽略警告,避免打包时某些警告出现
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法-dontwarn android.support.v4.** #缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
-dontwarn android.os.**
-keep class android.support.v4.** { *; } # 保持哪些类不被混淆
-keep class android.os.**{*;}-keep interface android.support.v4.app.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.support.v4.widget-keepclasseswithmembernames class * { # 保持 native 方法不被混淆native <methods>;
}-keepclasseswithmembers class * { # 保持自定义控件类不被混淆public <init>(android.content.Context,android.util.AttributeSet);
}-keepclassmembers class * extends android.app.Activity { //保持类成员public void *(android.view.View);
}-keepclassmembers enum * { # 保持枚举 enum 类不被混淆public static **[] values();public static ** valueOf(java.lang.String);
}-keep class * implements android.os.Parcelable {# 保持 Parcelable 不被混淆public static final android.os.Parcelable$Creator *;
}-keepclassmembers class **.R$* {public static <fields>;
}-keepclassmembers class * {@android.webkit.JavascriptInterface <methods>;
}-keep class MyClass; # 保持自己定义的类不被混淆
3、生成的文件
mapping.txt
列出了原始的类,方法,和字段名与混淆后代码之间的映射。
dump.txt
描述apk内所有class文件的内部结构。
seeds.txt
列出了没有被混淆的类和成员。
usage.txt
列出了源代码中被删除在apk中不存在的代码。
当我们发布的release版本的程序出现bug时,可以通过以上文件(特别是mapping.txt)文件找到错误原始的位置,进行bug修改。同时,可能一开始的proguard配置有错误,也可以通过错误日志,根据这些文件,找到哪些文件不应该混淆,从而修改proguard的配置。
PS:重新release编译后,这些文件会被覆盖,所以每次发布程序,最好都保存一份配置文件。
4、不能混淆的代码
顾名思义,不能混淆代码,否则会出错。
反射的地方
系统接口
Jni接口等
android proguard 官方demo : http://proguard.sourceforge.net
5、常见错误
官网bug解决方法:
http://proguard.sourceforge.net/index.html#manual/troubleshooting.html
使用gson包解析数据时,出现missing type parameter异常
类型转换错误
-keepattributes Signature
空指针异常
混淆过滤掉相关类与方法
java.lang.reflect.UndeclaredThrowableException
内存溢出和无法写入堆栈
Error: Unable to access jarfile ..\lib\proguard.jar
路径问题
java.lang.NoSuchMethodError
没有相关方法,方法被混淆了,混淆过滤掉相关方法便可。
- …..
ZKM
Zelix KlassMaster是一个来自Zelix Pty Ltd的商业混淆器,
它的保护功能非常强大,可以进行符号混淆和控制混淆,支持字符串的复杂加密保护,堆栈混乱,支持异常重构,支持增量混淆.
zkm script
详见: http://www.zelix.com/klassmaster/docs/langZKMScript.html
demo:
//sets the classpath that will be used by Zelix KlassMaster
classpath "%java.dir%\\jre\\lib\\resources.jar""%java.dir%\\jre\\lib\\rt.jar""%java.dir%\\jre\\lib\\jsse.jar""%java.dir%\\jre\\lib\\jce.jar""%java.dir%\\jre\\lib\\charsets.jar""%sdk.dir%\\platforms\\%android-target%\\android.jar";//load all classes in a jar file
open "%project.dir%/dist/%jpush-sdk-name%-%jpush-sdk-version-name%.jar";//Don't rename anything
exclude *.^* +; //Just String encrypt
obfuscate changeLogFileIn="" changeLogFileOut="%proguard.dir%/ChangeLog.txt" aggressiveMethodRenaming=falsekeepInnerClassInfo=truekeepGenericsInfo=trueobfuscateFlow=noneencryptStringLiterals=flowObfuscatelineNumbers=deleteexceptionObfuscation=noneautoReflectionHandling=none;//saves all opened classes to the specified directory
saveAll archiveCompression=all "%project.dir%/dist/zkm";> ps: 可以通过 %var% 来引用变量, eg %project.dir%
Android Proguard / ZKM 点滴记录相关推荐
- [转载]关于Android ProGuard混淆学习记录
转自:http://www.cnitblog.com/zouzheng/archive/2011/01/12/72630.aspx 前段时间把Android的工程用Ant Build搞定后,现在需要把 ...
- 关于TVM的点滴记录
关于TVM的点滴记录
- android p获取通话记录_[android] 取得最近通话记录的方法
经过一下午的研究,终于弄明白了android中,关于通话记录取得的方法.下边是自己的一点心得. final Cursor cursor = cr.query(CallLog.Calls.CONTENT ...
- Android 手机影音 开发过程记录(六)
Android 手机影音 开发过程记录(六) 前一篇已经将音乐播放及切换的相关逻辑弄好了,今天主要理一下剩余的部分,包含: 1. 自己定义通知栏的布局及逻辑处理 2. 滚动歌词的绘制 3. 歌词解析 ...
- 软件开发心得点滴记录
软件开发心得点滴记录 一见 创建日期:2013/6/27 1. 前言 自从2002年大学毕业后一直沉浸于软件开发之路,平时喜欢思考和归纳,时常会产生一点心得和想法,回想起来是一笔宝贵的财富,只可惜陆陆 ...
- [原创] Android SDK 安装全记录
[原创] Android SDK 安装全记录 1. JDK jdk-se-7u3 http://www.oracle.com/technetwork/java/javase/downloads/ind ...
- 深度学习(四十)caffe使用点滴记录
caffe使用点滴记录-持续更新 一.caffe 创建python 层 因为caffe底层是用c++编写的,所以我们有的时候想要添加某一个最新文献出来的新算法,正常的方法是直接编写c++网络层,然而这 ...
- Android Camera数据流分析全程记录(overlay方式二)
Android Camera数据流分析全程记录(overlay方式) 上一篇文章overlay这个过程已经走了一遍,但是根本是这个流程还没有走完,由上一篇文章知道,最后调用了postFrame方法, ...
- Android Camera数据流分析全程记录(overlay方式一)
Android Camera数据流分析全程记录(overlay方式) 这里为什么要研究overlay方式呢?android camera需要driver和app层需要有大量数据需要传输,如果使用非o ...
最新文章
- Nacos 1.3.0 发布, 全新内核构建
- 谷歌新App观妙中国发布:AR传承文化艺术,小米vivo应用宝可体验
- python使用笔记:xlrd和xlwt库的使用
- hdu2196 树形DP
- [1-2] Dependence-Aware Service Function Chain Design and Mapping
- 【数据结构与算法】之深入解析Base64编码的实现原理
- c语言函数调用二次方程求根,[编程入门]自定义函数求一元二次方程 (C语言代码)...
- mysql表连接_SELECT中的多表连接
- 常用邮箱SMTP/POP3地址及端口
- IT项目经验和难点分享
- 卡巴斯基重新激活试用版的方法
- Anylogic模型搭建01:医院排队挂号模拟试验
- matlab中的封装引脚,lm5117封装引脚图及功能
- Linux有道词典依赖问题
- cacti监控及配置
- 用户画像(Persona )简介
- 如何关闭Microsoft Office正版增值计划?
- python制作词典软件_Python爬虫之二:自制简易词典
- rust python_用于Python程序员的Rust
- 【ESP 保姆级教程 】疯狂传感器篇 —— 案例:ESP8266 + 火焰传感器 + 串口输出 + 自定义微信告警(火警预防)