十、Proguad使用与配置
mac下使用反编译命令:
使用命令:chmod +x jadx-gui 将jadx-gui变成可执行文件。
(在terminal中输入 chmod +x 然后将jadx-gui直接拖入terminal中 enter键 即可)
然后你会发现apktool文件图标变成了了可执行文件;
一、反编译
常用工具
- 1、apktool
https://ibotpeaches.github.io/Apktool/
平常开发中,主要资源文件的获取(AndroidManifest/res等)
解包: java -jar apktool_xx.jar d *.apk -o outPutFileName
重打包: java -jar apktool_xx.jar b outPutFileName -o *.apk
例如:
解包: java -jar apktool_2.3.1.jar d bjjj.apk -o bjjj
重新打包:java -jar apktool_2.3.1.jar b bjjj -o bjjj.apk
备注:1.apktool_xx.jar是自己获取不同版本的.jar;
- 2、dex2jar
https://sourceforge.net/projects/dex2jar/files/
将apk中dex反编译成jar(classes.dex转化成jar文件)
d2j-dex2jar.bat *.apk -o out.jar - 3、enjarify
https://github.com/google/enjarify
将apk反编译成java源码(classes.dex转化成jar文件)
需要安装python3(https://www.python.org/downloads/)
enjarify *.apk -o out.jar - 4、jd-gui
http://jd.benow.ca/
查看反编译后的jar包中的class - 5、jadx :这个是上面四个工具的集合,但是跳转不完善
https://sourceforge.net/projects/jadx/
直接查看资源与代码(不支持跳转)
二、Proguard
对java代码进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preverify);
1.压缩(Shrink):在压缩处理这一步中,用于检测和删除没有用到的类,字段,方法和属性;
2.优化(Optimize):在优化处理这一步中,对字节码进行优化,并且移除无用的指令;
3.混淆(Obfuscate):在混淆处理这一步中,使用a、b、c等无意义的名称,对类、字段和方法进行重命名;
4.预检(Preverify):在预检这一步中,主要是在java平台上对处理后的代码进行预检检查;
三、几种keep的区别
#=====================keep===================================
# 外界没有使用此类中的方法,类名没有被混淆,所有的方法都被移除,属性不会移除,属性名被混淆;
# 使用了要混淆的类Bug中的方法,类名没有混淆,但是使用的方法名混淆了,没有被使用的方法被移除了,属性不会移除,属性名被混淆;
#-keep class com.zcbl.airport_assist.obfuscatedemo.Bug
#类中的方法名和属性名都没有被混淆,不管是否被外界使用所有的方法和属性都被保留
#-keep class com.zcbl.airport_assist.obfuscatedemo.Bug{
# *;
#}
#=====================keepclasseswithmembers===================================
# 外界没有使用此类中的任何方法,类名不被混淆,但是里面的方法都被移除,属性不会移除,属性名被混淆;
# 外界使用此类中的方法,类名没有混淆,但是使用的方法保留且方法名被混淆,没有被使用的方法被移除了,属性不会移除,属性名被混淆;
#-keepclasseswithmembers class com.zcbl.airport_assist.obfuscatedemo.Bug
# 外界不管是否使用类中的属性和方法,都全部被保留,且名称都没有被混淆;
#-keepclasseswithmembers class com.zcbl.airport_assist.obfuscatedemo.Bug{
# *;
#}
# 不管外界是否使用此类中的方法,类名和testOne方法名都没有被混淆,属性名被混淆,其他的方法都会被移除;
#-keepclasseswithmembers class com.zcbl.airport_assist.obfuscatedemo.Bug{
# void testOne();
#}
#=======================keepclasseswithmembernames=================================
# 外界没有使用此类中的任何属性和方法,此类直接会被移除;
# 外界使用此类中方法,方法名和类名被保留,其他属性和方法都被移除;
#-keepclasseswithmembernames class com.zcbl.airport_assist.obfuscatedemo.Bug{
# void testOne();
#}
#============================keepclassmembers============================
#如果没有使用要混淆的类,下面的指令会将此类移除
#使用了要混淆的类Bug中的方法,下面的指令使类名被混淆,使用的方法名混淆了,没有使用的方法和属性都被移除了
#-keepclassmembers class com.zcbl.airport_assist.obfuscatedemo.Bug
#如果没有使用要混淆的类,下面的指令会将此类移除;
#如果外界使用了此类的方法,类名被混淆,使用的方法名没有混淆,没有使用的方法和属性被移除
#-keepclassmembers class com.zcbl.airport_assist.obfuscatedemo.Bug{
# void testOne();
#}
#只会保持com.zcbl.airport_assist.obfuscatedemo目录下的文件不被混淆,这个目录下的子目录名及里面的文件都会被混淆
#-keep class com.zcbl.airport_assist.obfuscatedemo.*{
# *;
#}
# 保持住com.zcbl包下的文件和子目录及子目录中的文件
-keep class com.zcbl.**{
*;
}
#忽略com.zcbl包及子包中的警告,如果不忽略,有警告的话,编译出错
-dontwarn com.zcbl.**
- 总结------待完成?????????
四、错误日志的还原
当开启混淆后,如果程序运行时打印错误日志,我们无法定位到是哪个类哪一行出现的错误,这时就要借助打包时产生的文件夹:
映射文件夹.png
结构说明:
dump.txt
说明 APK 中所有类文件的内部结构。
这个文件内容非常多,可读性也并不高;
mapping.txt
提供原始与混淆过的类、方法和字段名称之间的转换;
seeds.txt
列出未进行混淆的类和成员;我们保护的zip没有被混淆
usage.txt
列出从 APK 移除的代码。可以在这个文件中查看是不是有我们不想被移除的类
image.png
重要的当然就是我们的mapping文件了。通过这个文件我们就能定位到:
我们现在比较简单,所以一下子就能定位到错误函数,如果函数层级较深,光靠自己比对来查找难度就比较大了。所以sdk中提供了一个工具在tools/proguard/bin中。
我们把logcat里面保存的错误堆栈复制到一个文件中:
[图片上传中...(image.png-8713f2-1539869578759-0)]
image.png
然后执行retrace 脚本(在 Windows 上为 retrace.bat;在 Mac/Linux 上为 retrace.sh)
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
image.png
所以我们每次在发布版本之后都需要保留这个mapping文件。所以一般异常上报平台都会提供mapping上传然后帮助我们分析;
第一个问题解决的,第二个问题是行数显示的是Unknow Source
image.png
如果希望出现具体行数,我们需要在配置文件中加入
抛出异常时保留代码行号,在异常分析中可以方便定位
image.png-keepattributes SourceFile,LineNumberTable
另外还可以配合
-renamesourcefileattribute AAA
使用字符串"AAA"来替代真正的类,避免泄漏更多的信息
image.png
虽然我们的代码经过了混淆,但是实际上,对于有耐心有条件的人来说,还是能够从混淆过后的代码中看到蛛丝马迹。
Jdx-gui工具可能对做到这一点的帮助不大,因为它不支持函数的跳转。现在我换一种工具来进行反编译。
dex2jar: java
<u>https://sourceforge.net/projects/dex2jar/</u>
enjarify: python3
<u>https://github.com/google/enjarify</u>
两种工具都可以,使用dex2jar
image.png
反编译后生成了一个jar
image.png
然后使用jd-gui打开: image.png
直接跳到了
image.png
所以只要花功夫,混淆完全能够被完整的解读出来。当然并不是说混淆就没用。混淆之后解读难度更大了。
proguard移除无用代码还能缩小apk大小。