一、 背景介绍
AXMLEditor是尼古拉斯·赵四开源的的AndroidManifest ARSC二进制文件修改器,可直接修改APK资源文件,非常方便。源码链接是:源码下载地址,且
工具使用介绍地址文章详细介绍其用法和原理。但是,文末提到一个待改进的地方,即不支持添加引用资源类型的属性。工作过程中,我刚好需要添加应用资源类型的属性,于是在此记录我的解决过程。
“当然这里还是有些操作不支持的,比如插入一个activity标签内容,现在不支持一些特殊的属性,比如theme类型,因为我们知道这些属性可能需要引用一些资源。而资源文件我们现在还没弄。所以引用资源类型的属性添加都是失败的。”
二、 问题分析
我们需要修改二进制AndroidManifest文件,添加标签。我们下载AXMLEditor.jar文件,插入上述标签。发现,安装时报错,说找不到android:value标签。
使用AndroidSDK自带的aapt.exe工具查看具体情况,发现“android:name”、”android:label”等都有资源ID,但是新插入的“android:value”没有资源ID,这大概率就是找不到“android:value”标签的原因。
这些资源ID代表什么意思呢?android:name(0x01010003),它的PackageID为0x01,是一个系统资源命名空间,因此这类资源ID应该是固定且通用的,android:value的资源ID也是通用的,任意找一个其他APK查看它的资源ID为0x01010024。
Package
ID相当于是一个命名空间,限定资源的来源。Android系统当前定义了两个资源命令空间,其中一个系统资源命令空间,它的Package
ID等于0x01,另外一个是应用程序资源命令空间,它的Package ID等于0x7f。所有位于[0x01, 0x7f]之间的Package
ID都是合法的,而在这个范围之外的都是非法的Package ID。—罗升阳
我们继续用010Editor工具分析以下AndroidManifest.xml文件。下图是010Editor的分析截图,我们发现”value“已成功插入字符串列表,但是resMap中却没有attr_value的内容。
三、 问题解决
经过问题分析,我们发现现有的AXMLEditor工具没有添加resMap内容,修改源码内容,插入resMap内容,发现任然提示找不到“android:value”,使用appt工具查看也依然没有给他分配资源ID。经过一番资料查找,发现该属性在ResStringPool中的位置必须同它在resids中的位置一致,即我们将”value”字符插入到ResStringPool中的44位,那么”attr_value”就必须插入到resids中的第44位。如下图所示:
不仅需要插入”attr_value”资源属性,还需要修改resMap的大小。
修改完成后,APK正常安装执行。
下述代码是在AXMLEditor源码的基础上修改的添加资源属性的函数,由于android:name属性默认会存在,因此不需额外添加。
public static void modifyResMap_violet() {
byte[] tmpSize = Utils.