完整教程:【apktool】Android apk安装包反编译、apk 签名
文章目录

一、apk 文件结构
首先是 apk,即安卓程序的安装包。Apk 是一种类似于 Symbian Sis 或 Sisx 的文件格式。通过将 APK 文件直接传到 Android 模拟器或 Android 手机中执行即可安装。
而 apk 文件实际上就是一个 MIME 为 ZIP 的压缩包,只不过后缀名进行了更改。
我们可以直接把 .apk 后缀的文件修改成 .zip 后缀的压缩包格式,然后解压后就可以看到内部的文件结构,就像下面这样:
文件夹结构说明:
- assets 文件夹: 保存一些额外的资源文件,如游戏的声音文件,字体文件、图片等等,在代码中可以用
AssetManager获取assets文件夹的资源。 - lib 文件夹: 存放用
C/C++编写的,用NDK编译生成的so文件,供java端调用。 - META-INF 文件夹: 存放
apk签名信息,用来保证apk包的完整性和系统的安全。在 IDE 编译生成一个apk包时,会对里面所有的文件做一个校验计算,并把计算结果存放在 META-INF 文件夹内,apk在安装的时候,系统会按照同样的算法对apk包里面的文件做校验,如果结果与 META-INF 里面的值不一样,系统就不会安装这个 apk,这就保证了apk包里的文件不能被随意修改和替换。比如拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系统的安全。 - res文件夹: 存放资源文件,包括
icon,xml布局文件 - AndroidManifest.xml文件: 应用程序的清单文件,每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等信息。
- classes.dex文件: 传统 Class 文件是由一个
Java源码文件生成的.Class文件,而 Android 是把所有Class文件进行合并优化,然后生成一个最终的class.dex文件。它包含 APK 的可执行代码,是分析 Android 软件时最常见的目标。由于dex文件很难看懂,可通过apktool反编译得到.smali文件,smali文件是对Dalvik虚拟机字节码的一种解释(也可以说是翻译),并非一种官方标准语言。通过对smali文件的解读可以获取源码的信息。当然 你也可以通过dex2jar工具将classes.dex文件转化为jar包,然后再通过jadx或者jd-gui可以查看jar包里面的代码。一般软件开发者会对classes.dex进行加固,防止别人轻易反编译 - resources.arsc文件: 二进制资源文件,如:字符串常量就会存放在
strings.xml中。 - smali:
smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为 Android 字节码的反汇编语言。利用apktool或者Android Killer,反编classes.dex文件,就可以得到以smali为后缀的文件,这些smali文件就是Dalvik的寄存器语言。
简单的说,smali就是Dalvik VM内部执行的核心代码,andorid逆向分析的关键点。
二、下载 apktool
可在下面两种下载中选择一种方式下载:
(我这里使用的是 apktool_2.9.1.jar 版本)
三、使用 apktool 反编译 apk
将 apk 安装包和下载的 apktool 放在同一目录。
前置条件:安装
java8环境
假如我的安装包叫 base.apk ,我想把它反编译到 test 文件夹下,反编译命令如下:
java -jar apktool_2.9.1.jar d base.apk -o test
该命令将会自动新建一个 test 文件夹, 反编译后的所有文件都将被放到里面。
说明:与
jadx不同,apktool反编译apk后,你在反编译后的AndroidManifest.xml里是找不到versionCode内部版本号 和versionName版本名称 的,因为apktool把它放到了apktool.yml文件里,如果你要修改versionCode、versionName,可以在apktool.yml文件里修改。
四、编译为apk
假如你修改了 test 文件夹里的代码 或者 修改了versionCode 、versionName 等其他内容,可用下面的命令将 test 文件夹编译为 apk 。
java -jar apktool_2.9.1.jar b test -o test.apk
该命令将 test 文件夹编译为 test.apk 。
到这里你已经得到了一个修改后的 apk,但是这个编译后的 apk 还无法安装到手机上,因为修改了文件,在安装时手机会对安装包里的签名进行比对签名,如果签名对不上说明apk被篡改了,就不会进行安装。
所以,如果现在要对修改后的 apk 重新进行签名,才能安装。
五、apk 签名
- V1签名(JAR签名)基于JAR文件格式兼容性好,但安全性相对较低
- V2签名(APK签名方案)
Android 7.0引入对整个APK进行签名,安全性更高,验证速度更快 - V3签名(APK签名方案v3)
Android 9.0引入,支持密钥轮转,无需应用数据丢失- - V4签名(APK签名方案v4)
Android 11引入,基于fs-verity,提供更快的安装验证
1.生成密钥库
使用如下命令生成 keystore 格式的密钥库:
keytool -genkey -alias new.keystore -keyalg RSA -validity 20000 -keystore new.keystore
输入两次密钥口令,一直回车,最后输入 y
2.使用 v1 签名
使用如下命令进行签名:
jarsigner -verbose -keystore new.keystore -signedjar D:\fanbiany\sign1.apk D:\fanbiany\test.apk new.keystore
说明:该命令使用上面生成的
new.keystore密钥库对D:\fanbiany\test.apk进行签名,最后生成D:\fanbiany\sign1.apk
3.使用 v2 签名
先找到你的 apksigner.jar 所在路径,我的是在 C:\Users\kingdee\AppData\Local\Android\Sdk\build-tools\33.0.2\lib\apksigner.jar
执行如下命令进行 v2 签名:
java -jar C:\Users\kingdee\AppData\Local\Android\Sdk\build-tools\33.0.2\lib\apksigner.jar sign --ks new.keystore --out sign2.apk sign1.apk
说明:使用
apksigner.jar然后用new.keystore密钥库对sign1.apk进行签名,最后生成sign2.apk
六、Dex 加解密原理
一般 apk 都会进行加固,即对 Dex 加密,Dex 就是格式的文件里是 apk 的代码,加密后反编译是看不到项目主要代码的,从而保证了 apk 的安全性。
浙公网安备 33010602011771号