本文介绍一些反编译的知识
反编译和回编译
工具
APKTool
用来反编译和回编译apk文件,下载下来是一个jar包,修改原始文件名为apktool
确保Java安装了,环境变量正确的配置了,在Windows下面做,创建一个apktool.bat
@echo off
if "%PATH_BASE%" == "" set PATH_BASE=%PATH%
set PATH=%CD%;%PATH_BASE%;
java -jar -Duser.language=en "%~dp0\apktool.jar" %1 %2 %3 %4 %5 %6 %7 %8 %9
反编译
apktool.bat d Demo.apk
回编译
apktool.bat b Demo -o New_Demo.apk
坑:error: Public symbol …… declared here is not defined
我遇到的是drawable里面的png的问题,反编译的时候就有警告提示,跟9Patch格式有关,有一大堆的错误,其实将最上面出错的png用画图工具打开再保存为png就可以了
也可以用ShakaApkTool来解决(增强工具)
查看源码
使用dex2jar
和jd-gui
查看源代码
将apk重命名为.zip
,解压class.dex文件拷贝到dex2jar目录下,执行命令获得jar文件
d2j-dex2jar classes.dex
用jd-gui打开jar文件就可以看到源码结构了
签名
重新获得的APK必须签名才能安装到手机上使用
签名文件
可以获得线程的签名文件比如~/.android/debug.keystore
,这个debug的签名文件的密码是android,别名是androiddebugkey
也可以生成自己的key
keytool -genkey -alias mykey -keyalg RSA -validity 40000 -keystore demo.keystore
这个keytool也是JDK里面的工具
签名
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore [keystore] -storepass [password] [apk] [alias]
对齐
据说可以运行的更快
zipalign 4 New_Demo.apk New_Demo_aligned.apk
假如只是替换一下资源文件什么的,就不用反编译过来再回编译过去,直接解压替换就好了,不过要注意签名
直接签名会出错,大概是文件大小不匹配什么的,因为原签名还在,所以首先要删掉原APK的签名,删除META-INF
这个文件夹,然后签名
还有可能会出现无法打开APK的错误,解决方法之一是不要解压成文件夹再压缩回去,直接用压缩工具打开修改
混淆
在AndroidStudio中
release {
minifyEnabled true 改成true就可以
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
表示打正式版才会混淆,生成一个keystore,然后打正式包
混淆的一些结论
1.普通类肯定是会被混淆的,不管是类名、方法名还是变量都不会放过,没有被调用的方法被认为是多余的代码,在打包的时候就给移除掉了,不仅仅是代码,没有被调用的资源同样也会被移除掉,因此minifyEnabled除了混淆代码之外,还可以起到压缩APK包的作用。
2.Fragment生命周期方法会不会被混淆和我们使用Fragment的方式有关,support-v4包下的,就连Fragment的源码都被一起混淆了,因此生命周期方法当然也不例外了。但如果使用的是android.app.Fragment,这就是调用手机系统中预编译好的代码了,很明显我们的混淆无法影响到系统内置的代码,因此这种情况下onCreateView()方法名就不会被混淆,但其它的方法以及变量仍然会被混淆。
3.凡是需要在AndroidManifest.xml中去注册的所有类的类名以及从父类重写的方法名都自动不会被混淆。因此,除了Activity之外,这份规则同样也适用于Service、BroadcastReceiver和ContentProvider。
4.只要一个类中有存在native方法,它的类名就不会被混淆,native方法的方法名也不会被混淆,因为C++代码要通过包名+类名+方法名来进行交互。 但是类中的别的代码还是会被混淆的。
5.第三方的Jar包都是会被混淆的。
/tools/proguard中可以找到这些规则