快速修改apk的AndroidManifest.xml

前提

直接将apk解压,查看其中的AndroidManifest.xml文件,会发现无法正常显示,是因为在打包的时候,aapt将资源文件编译成二进制文件,包括AndroidManifest.xml。所以修改apk中的AndroidManifest.xml的思路就是反编译AndroidManifest.xml->修改->回编译AndroidManifest.xml->打包签名。

修改apk的AndroidManifest.xml的用处多多,例如可以修改名称、修改横竖屏、插入android:debuggable=”true”属性等等。

尝试

apktool

反编译apk后修改内容再打包,首先想到的是使用apktool

  1. apktool d test.apk
  2. 修改smali、修改xml、替换资源文件
  3. apktool b test
  4. zipalign
  5. sign

这样就可以实现修改现有apk的目的(未被加固的apk,并且修改后签名会改变)。

不过使用apktool有个缺点,就是无论是否需要改到代码逻辑,都需要将dex反编译成smali,然后回编译的时候再整个包回编译,包括将smali回编译成dex,而反编译和回编译代码逻辑这是整个过程中最耗时的。如果我们不需要改到代码逻辑,只想要在AndroidManifest.xml中修改一些属性,例如插入android:debuggable=”true”属性,使用这个方法就将耗费大量时间在无意义的事情上。MacBook Pro 15款对一个极其简单的apk执行apktool b指令都需要耗费10秒左右的时间。

apktool+aapt

apktool在执行apktool d test.apk命令反编译的时候,能在将AndroidManifest.xml文件反编译后替换其中所有资源文件索引的十六进制索引为可读的@string/xxx这样的形式;aapt是用来编译资源文件的,能编译APP中的所有资源文件。其实apktool本身在回编译的时候就是使用aapt来编译资源文件。

那就有了另一种可能性

  1. unzip test.apk
  2. apktool d test.apk
  3. 修改apktool反编译出来的xml
  4. 对修改后的xml执行aapt package
  5. 提取aapt编译出来的二进制AndroidManifest.xml,替换掉unzip中的二进制AndroidManifest.xml
  6. 对unzip并替换了AndroidManifest.xml的文件夹执行zip
  7. zipalign
  8. sign

有人可能会觉得使用apktool d命令来反编译整个apk只是为了提取AndroidManifest.xml有点浪费,能不能直接使用AXMLPrinter2来反编译AXMLPrinter2?AXMLPrinter2是能实现单独反编译AndroidManifest.xml文件,但是问题是其中所有对资源文件的引用依然保留R.java中对应的十六进制索引,而不是可读的@string/xxx这样的形式,在后续使用aapt编译资源文件的时候明显会出错。

那能不能直接使用apktool+aapt来饶过对代码逻辑的回编译从而直接反编译和回编译AXMLPrinter2呢?不能。

使用aapt生成R.java
rem 测试的工程目录下必须得有gen文件夹,否则会提示:Unable to open class file R.java:No such file or directory
%aapt% package -f -m -J %GEN% -S %RES% -I %ANDROID_JAR% -M %ANDROID_MANIFEST_XML%

使用aapt生成资源包文件
%aapt% package -f -M %ANDROID_MANIFEST_XML% -S %RES% -A %ASSETS% -I %ANDROID_JAR% -F %RESOURCE%

%GEN%:存放的R.java文件夹路径。
%RES%:res文件夹路径。
%ANDROID_JAR%:引用的android.jar路径。
%ANDROID_MANIFEST_XML%:工程AndroidManifest.xml绝对路径。
%ASSETS%:asset文件夹路径。
%RESOURCE%:生成的resouces.arsc存放路径。

aapt在编译打包资源文件的时候,必须引入res、assets资源文件夹,在编译之后AndroidManifest.xml中@string/xxx这样的形式将被替换成生成的R.java中的十六进制索引,那这时候生成的索引会跟原始apk中的索引一致吗?经过实验证明,这个索引并不一致,所以这就意味着,如果要用这个方法,必须修改原来apk文件中的dex文件,替换掉R.java中的资源索引。先不管用什么方法可以实现这个目的,首先这需要对dex的编译和反编译就违背了我们快速修改AndroidManifest.xml文件而不去动代码逻辑的初衷。

方法

既然二进制的AndroidManifest.xml文件结构是已知的,那肯定是可以将(通过AXMLPrinter2提取并修改后的)可读AndroidManifest.xml直接反编译成二进制,而不用像aapt一样让所有资源文件也参和进来,全程对资源文件的引用都保留十六进制索引。

https://github.com/hzw1199/xml2axml

该项目就是为了实现这个功能存在的。在release中直接下载jar就可以使用。该项目同时还支持像AXMLPrinter2那样反编译二进制AndroidManifest.xml。

该项目是在另一个项目的基础上改过来的,原始项目是我在github搜索相关开源项目时无意中找到的,加上了我的star竟然也才10个star,真是酒香也怕巷子深。我对原始项目的改造包括替换原来API Level 21的android.jar为API Level 28,解决了不支持高Target的attribute,导致高Target的apk使用后出现无法连接http等异常的问题,并且通过添加maven plugin打包了jar文件,方便直接下载使用。

encode
java -jar xml2axml e [AndroidManifest-readable-in.xml] [AndroidManifest-bin-out.xml]

decode
java -jar xml2axml d [AndroidManifest-bin-in.xml] [AndroidManifest-readable-out.xml]

于是整个流程就变成这样

  1. unzip test.apk
  2. xml2axml d AndroidManifest.xml AndroidManifest-dec.xml
  3. 修改xml2axml反编译出来的xml:AndroidManifest-dec.xml
  4. xml2axml e AndroidManifest-dec.xml AndroidManifest.xml
  5. 对unzip并修改了AndroidManifest.xml的文件夹执行zip
  6. zipalign
  7. sign

结论

本文的方法全程不对dex进行任何反编译和回编译,对AndroidManifest.xml的反编译和回编译也是计算量极小,唯一计算量稍大的地方就是unzip和zip,但是跟使用apktool的方法中需要反编译和回编译dex比起来,效率有了非常大的提升。而由于AndroidManifest.xml中的所有对资源文件的引用全程维持R.java中的十六进制索引,所以无需使用aapt重新编译资源文件,从而无需担心R.java中对资源的索引改变导致需要修改dex。

参考文献

https://blog.csdn.net/qq_35159110/article/details/82751928

https://blog.csdn.net/qq_35159110/article/details/82223723

https://www.jb51.net/article/101656.htm

https://blog.csdn.net/byhook/article/details/83060836

https://www.jianshu.com/p/839969887e2c

https://code.google.com/archive/p/android4me/downloads

https://stackoverflow.com/questions/16777049/encode-decode-androidmanifest-xml-inside-apk

https://stackoverflow.com/questions/29669937/android-converting-standard-xml-to-android-binary-xml-format-axml

https://ibotpeaches.github.io/Apktool/

https://github.com/fourbrother/AXMLEditor

https://www.cnblogs.com/bydzhangxiaowei/p/8172766.html

https://github.com/l741589/xml2axml

Share

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注