一、APKTOOL
APKTOOL 这个东西,作为一个很强的 Android 应用程序逆向工程的工具,在开发者还有技术爱好者当中可受欢迎啦。它有好多重要的功能,给深入去了解和修改 Android 应用提供了很有力的支持。
在资源解码这块,APKTOOL 能把 APK 里的图片、布局还有字符串这些资源给解析成能读得懂的格式。比如说,它能把复杂的布局文件变成容易理解的 XML 格式,方便开发者去看还有修改应用的界面结构。同时呢,对图片资源,APKTOOL 也能解码,这样开发者就能去看还有替换应用里的图标、背景图啥的。
在打包的功能上,APKTOOL 能支持把改了的资源和代码重新打包成 APK 文件。反编译还有修改完了的应用,能通过 APKTOOL 的打包功能弄出个新的 APK,好能在设备上做测试或者分发。
在 Smali 调试这方面,对于那种没法直接读的 Dalvik 字节码(smali),APKTOOL 提供了一种方便的办法能一行一行调试。通过一系列的操作,像加调试代码、设远程调试的选项这些,可以在 Android Studio 这样的开发环境里对反编译之后的 Smali 代码调试,帮着开发者深入去了解应用的内部逻辑还有运行的机制。
反正,APKTOOL 凭着它强大的功能还有灵活性,成了 Android 应用开发和逆向工程领域的重要工具。不管是做应用本地化、性能优化,还是搞安全研究还有自定义 ROM 开发,APKTOOL 都能起大作用。
二、下载与安装
(一)查看 Java 版本
在装 APKTOOL 之前,得先瞅瞅 Java 版本。因为 APKTOOL 得要 1.8 及以上的 JDK 版本才能正常运行。具体咋弄呢,按下 Win + R 这俩键,然后输入 cmd 打开命令行那个窗口。在命令行里输入 java -version 这个指令,就能看到现在系统装的 Java 版本是啥样。要是显示的版本比 1.8 低,那就得先装 Java 8 或者更高的版本。有统计说,现在大部分开发者和技术爱好者用的 Java 版本主要就是 Java 8 和 Java 11,这俩版本在性能和稳定性上表现都不错。
(二)下载相关文件
接下来,咱们得从指定的链接去下载 apktool.jar 和相关的文件。先打开这个链接 https://ibotpeaches.github.io/Apktool/install/,在这个页面里找到相关的下载地方。然后再打开另一个链接 https://bitbucket.org/iBotPeaches/apktool/downloads/,选 apktool_2.4.0.jar 下载。下载完了,把这个文件重命名,把后面的版本号去掉。这么做是为了后面用的时候和认的时候方便。
(三)使用命令行工具
把文件下载完重命名好了,把刚下载好的这俩文件复制到特定的目录里,比如说在 Windows 系统里,得复制到 C:\Windows 目录下,这个操作得要管理员权限,点继续就行。接着,再按下 Win + R 这俩键,输入 cmd 打开命令行工具,然后输入指令 apktool(注意:apktool 后面没 s)。输完回车,这时候就会出现 apktool 的使用帮助信息。到这,APKTOOL 的安装就弄好啦。
三、APK 文件反编译
(一)准备工作
(二)执行反编译指令
反编译的具体指令是:java -jar apktool.jar d D:\\test\\baiduditu_908.apk -o C:\\test 。这里头指令的意思是用 apktool.jar 对 D 盘 test 目录下的“baiduditu_908.apk”文件解码(反编译),输出的东西会放在 C 盘的 test 目录里。C 盘的 test 目录不用事先建好,工具会自己创建。这种办法能方便地指定输入和输出的路径,保证反编译过程能顺顺当当进行。
(三)反编译后的文件结构
反编译完了,Android 里的 assets 文件和 res 文件不会被编译成二进制文件,所以能很好地恢复原样。比如说,咱们瞅瞅 res 目录,能看到里头有应用的各种资源文件,像布局文件、图片、字符串啥的。这些文件反编译完了还是原来的目录结构,不过内容变成能读的文本格式了。
对于 smali 文件,Android 里的.Java 文件在 JVM 编译完变成.class 文件,然后再经过 Android 的虚拟机 Dalvik,代码就编译成.smali 文件。smali 有点像汇编那种语言,涉及寄存器的操作。要是没学过.smali 的语法这些相关的东西,那这些 smali 文件暂时没法直接用。但是,通过学 smali 语言或者借其他工具,咱们能对这些文件分析和修改,这样就能深入知道应用的内部逻辑和实现的办法。
四、APKTOOL 的使用技巧
(一)常用命令选项
APKTOOL 有好多实用的命令选项,在不同的操作里都起着重要作用。
通用命令:
--version 或者 -version :能看 apktool 现在的版本,像 apktool --version 就能很快知道现在用的 APKTOOL 是啥版本。
-v 或者 --verbose :详细输出,得当成第一个参数用,能在操作的时候知道更多细节。
-q 或者 --quiet :安静输出,就是输出的时候不显示详细信息,也得当成第一个参数用,适合要简洁输出的情况。
-advance 或者 --advanced :在命令行每一步操作之前,会打印详细信息,方便用户跟着操作进度。
反编译命令选项:
-api 或者 --api-level :生成用的 smali 文件的 api 等级(默认是 targetSdkVersion),比如 apktool d -api21 C:\\Users\\Administrator\\Desktop\\test.apk 就是指定 api 等级是 21 来反编译。
-b 或者 --no--debug-info :不让 baksmali 打印出调试信息,让输出更简洁,不需要调试信息的时候这个就很有用。
-f 或者 --force :强行删掉目标文件目录,执行反编译命令的时候,强行覆盖已经有的文件,像 apktool d -f C:\\Users\\Administrator\\Desktop\\test.apk 。 --force-manifest :强行反编译 AndroidManifest.xml 文件,从 v2.3.1 开始有这个功能。
--keep-broken-res :要是出了“Invalid Config Flags Detected. Dropping Resources…”这个错误,可以加上这个命令,跳过这个错误,不过后面得自己手动修错。
-m 或者 --match-original :把各个文件处理成最接近原生的样子,这样就不能重新打包了。
--no-assets :不处理和拷贝属于 unknown 的资源文件。
-o 或者 --output :把反编译之后的文件写到指定的文件路径里,这个经常用,比如 apktool d -f C:\\Users\\Administrator\\Desktop\\test.apk -o C:\\Users\\Administrator\\Desktop\\decode 。
--only-main-classes :反编译根目录里的 dex 文件,从 v2.4.1 开始有。
-p 或者 --frame-path :指定 framework 文件存的地方。
-r 或者 --no-res :不反编译资源,让 resources.arsc 保持原来的样子,要是只是要改代码,用这个能加快反编译和重新打包的速度。
-s 或者 --no-src :不反编译代码,就是不处理 dex 文件。要是只是改资源,用这个也能加快反编译和重新打包的速度。
-t 或者 --frame-tag :给生成的 framework 文件打上标记。
回编命令选项:
-a 或者 --aapt :从指定的路径加载 aapt,指定目录没找到 aapt 的时候,会用 apktool 自己带的 aapt 来处理,比如 apktool b -a C:\\Windows\\System32\\aapt.exe C:\\Users\\Administrator\\Desktop\\test2 。
-api 或者 --api-level (v2.4.0 加上的):要建的 smali 文件的数字 api 级别 (默认是 minSdkVersion) 。
-c 或者 --copy-original :把原始的 AndroidManifest.xml 和 META-INF 文件复制到内置的 apk 里,从 v2.5.0 准备不用这个了。
-d 或者 --debug :在 AndroidManifest 文件里加上 debuggable="true" 。
-f 或者 --force-all :回编的时候强行覆盖已经有的文件。
-nc 或者 --no-crunch :回编的时候不让处理资源文件,从 v2.4.0 开始有。
-o 或者 --output :回编的时候指定生成 apk 的生成路径,比如 apktool b C:\\Users\\Administrator\\Desktop\\test -o C:\\Users\\Administrator\\Desktop\\test_unsigned.apk 。
-p 或者 --frame-path :从指定的地方加载 framework 的路径。
--use-aapt2 :用 aapt2 来回编打包,从 v2.3.2 版本开始有。
(二)处理特定厂商 APK
像小米、htc、三星这些厂商定制 framework 文件的 APK,处理起来得有额外的步骤。比如说咱们试着编译小米桌面的 MiuiHome.apk,可能会收到错误提示。这时候,咱们可以用 apktool if/install-framework <framework.apk> ,然后再试试反编译 MiuiHome.apk 。这些厂商定制了 framework 文件,还在系统应用里用了,为了能正常反编译这些 APK,就得拷贝反编译 APK 依赖的 framework 文件。
(三)签名问题
用 apktool b testapp –o out\testapp.apk 编译好了之后,生成的 testapp.apk 没签名,还不能安装测试。一般来说,要保持原来的签名不变,可以用 -c 选项来保持,就是 apktool b testapp -c -o out\\testapp.apk 。要不然就得用别的签名工具给 apk 签名,像 signapk.jar 、auto-sign 这些。META-INF 包含 apk 的签名,用 -c/--copy-original 来保持签名,用原来的 AndroidManifest.xml 文件。但是要是改了 AndroidManifest.xml 文件,签名就没了,就得重新给它签名。
五、注意事项
(一)脚本包装调用命令
在用 APKTOOL 的时候,可以写个脚本把调用命令包起来,这样能更方便地搞批量处理或者自动化操作。比如说,可以用批处理脚本(.bat 文件)或者 shell 脚本(在 Linux 或者 macOS 上)来弄一系列的 APKTOOL 操作,像反编译、修改还有重新打包啥的。这样能把工作效率提上去,特别是要处理好多 APK 文件的时候。
(二)解码选项的谨慎使用
在用反编译命令的各种选项的时候,得小心选。不同的选项可能对反编译的结果有不一样的影响。比如说,用--no-res 选项就可以不反编译资源文件,要是只改代码,用这个能加快反编译和重新打包的速度,可这也意味着不能直接看和改资源文件。同样,--no-src 选项不反编译代码文件,适合只改资源的情况。选这些选项的时候,得按照具体的需求好好琢磨,别弄出没必要的问题。
(三)签名阶段可能出现的问题及解决方法
在签名的阶段,可能会有各种问题。要是用 APKTOOL 的 -c 选项来保持原来的签名,但是改了 AndroidManifest.xml 文件,签名就没了,就得重新给 APK 签名。这时候能用上别的签名工具,像 signapk.jar 或者 auto-sign 这些。
另外,签名的时候还可能有签名文件错了、密钥库密码错了、别名错了、Java 环境配置有问题还有文件访问权限有问题这些情况。对签名文件错了的,得保证用的签名文件是对的(一般是一个.keystore 文件)。要是密钥库密码错了,得仔细瞅瞅密码输入对不对。别名错了就得保证输入的别名是有效的,还得跟签名文件能对上。对 Java 环境配置的问题,得保证 Java 开发环境装好了也配好了,在命令行里能正常执行 java 和 keytool 这些命令。要是碰到文件访问权限的问题,可以用管理员的身份去运行相关命令,或者改改文件的访问权限。
反正,用 APKTOOL 的时候,得注意这些可能有的问题,再用对应的解决办法,保证 APK 文件反编译、修改还有重新打包的过程能顺顺当当的。