一、情景分析
通常我们在破解apk的时候,第一步肯定先反编译apk文件,然后开始修改代码和资源文件,最后回编译签名即可。但是现在有些apk做了一定策略,或者apk包如果很大都会导致回编译失败,而回编译如果失败,对于修改就没意义了。毕竟我们想回编译安装使用我们修改之后的功能。而对于回编译失败的问题,也可以花点时间结局的。但是有时候花费的时间不值得,而且也不一定能成功。所以就需要想其他的办法了。那就是无需反编译对apk进行修改。其实我们在修改apk的时候就是主要修改三个地方:代码+资源+清单文件。其他的修改很少。那么我们知道apk文件其实就是一个压缩文件。可以直接使用压缩软件打开。所以如果我们能对dex文件和arsc文件直接操作修改。然后在塞进去apk文件中,在重新签名就可以了。这样就避免了反编译和回编译了。也可以避免很多操作错误了。而关于如何操作这两类文件,后一篇文章会详细介绍。今天我们主要看如何直接修改AndroidManifest ARSC文件内容。
二、原理分析
弄过反编译的同学都知道AndroidManifest在apk中是以二进制形式存在的。也是有固定的存储格式的。这样做是为了减少apk的大小。而关于文件格式,我在之前的文章也做了详细介绍,不了解的同学可以看这篇文章:Android中的清单文件ARSC格式解析;而且再次说明。一定要看明白这篇文章,不然本文会看的很吃力。而这篇文章其实是借助了看雪大神MindMac的一张神图:
大神是根据AXMLPrinter.jar工具源码分析出来的,非常的不容易。关于AXMLPrinter.jar这个工具是专门为解析二进制文件AndroidManifest ARSC弄的。网上有很多。而且这个工具是开源的,可以下载源码看看。
下面我们就是基于这个文件的二进制文件格式,开始做如下功能的修改器:
第一、操作属性:删除,增加,修改功能
第二、操作标签:删除,增加功能
而这些功能也是最常用的,下面就来一一介绍如何修改操作:
第一、删除属性
我们看完文件格式之后,知道每个标签中的属性值都是存放在标签块(StartTagChunk)末尾的。每个属性是5个字段,每个字段是4个字节。所以一个属性占用20个字节:
所以如果我们要删除一个属性,需要这些条件:
1、属性所属的标签名称,标签唯一id也就是name值。
比如我们想删除xxx.xxx.Activity标签的一个属性,那么得知道是activity标签,然后是name值找到唯一的标签
2、属性的名称
通过标签名和唯一id找到标签对应的块内容,然后开始利用索引值找到其属性块区域,然后在遍历属性找到想要删除的属性块直接干掉这块字节。而对于标签块的格式如下:
签名都是几个固定四个字节大小的极端,有一个字段需要解析就是属性个数。因为我们删除完属性块之后,还需要做两件事:
第一、修改属性个数
第二、修改标签块大小(其实就是减小20个字节即可)
那么如何找到标签块,其实借助我们之前自己做的一个AndroidManifest文件解析工具,下载地址文章后面会给出。直接在那个代码基础上修改即可。我们需要先解析arsc文件,获取所有的标签块然后保存到池子中即可。说了这么多,操作这里就不粘贴代码了:
这里还要注意的是:如果只有一个属性的标签,在删除属性的时候直接可以删除整个标签了。删除标签后面会详细介绍。每次操作完成之后,还必须重新写好总得文件大小。
总结:
第一步:解析arsc文件,获取所有的标签块和其属性块值。
第二步:利用需要删除属性提供的标签名和id,以及属性名找到对应的属性块信息,直接删除这块字节即可。
第三步:修改属性所属的标签的属性个数和整个标签块大小。
第四步:修改整个文件的大小。
注意:如果发现只有一个属性的标签,直接删除这个标签即可。
第二、添加属性
在上面的删除属性操作基础上,我们添加一个属性就简单了。前几步还是那么简单,首先找到需要添加属性的标签块,因为每个标签块的末尾存储的就是对应的属性块信息,所以直接在该标签块的末尾添加一个20个字节的属性块即可。然后在去修改标签块的属性个数,和标签块大小即可。但是这里需要注意是,我们新添加一个属性,有可能会增加新的字符串信息,我们通过分析文件格式知道,还有一个字符串块,也就是文件中所有的字符串保存的地方。
所以在添加属性的时候,还得先去解析这个字符串信息,然后去判断当前添加的属性是否带来了新的字符串值,而不管是属性还是标签中的字符串都是用索引值保存的。所以我们需要判断当前添加的属性带来的字符串值是否已经存在了,如果存在就直接返回池子中的索引值,不存在就放到字符串末尾返回索引值即可。
因为我们有可能修改了字符串块内容。所以我们最后还需要修改字符串块信息。把最终的字符串信息变成字符串块回写到文件中。这个就需要看明白字符串块格式:
这个这里不在多解释了,直接看我开源的代码即可。
总结:
第一步:解析arsc文件获取所有的标签块和其属性块信息,以及字符串块信息
第二步:根据需要插入属性的标签名称和id值,找到对应的标签块
第三步:通过添加的属性信息构造一个属性块信息,然后直接添加在标签块的末尾即可
第四步:更新字符串块信息,以及标签块大小和属性个数信息,最后修改文件大小。
注意:记得还得修改字符串块信息
第三、修改属性
其实修改属性这里没那么复杂操作了,直接利用前面的两个操作组合完成即可,因为一次修改等于先删除在添加操作,这里为了简单,直接这么操作了。所以这里就不多介绍了。
第四、删除标签
这个其实和属性块删除操作非常类似,找到标签块直接删除即可。然后修改文件大小。比删除属性还要简单点。不过这里需要注意了,在AndroidManifest.xml中存在两种标签,一种是和application标签平级的,比如权限标签,一种是在application标签中的。而在删除一个标签必须还需要id值,也就是name属性值,所以我们还需要获取到这个标签块的属性值,才能找到对应的标签块。而且在删除一个标签块必须删除开始块和结束块。
总结:
第一步:解析arsc文件获取全部的标签块信息以及属性块信息
第二步:通过标签名和标签id找到指定的标签块信息,直接删除当前标签块即可。
第三步:修改文件大小。
注意:删除一个标签,必须要有name属性值作为唯一性。所以还得继续解析他的属性块信息。
第五、添加标签
这个和添加属性操作也很类似。因为我们了解文件个时候之后,每个标签块是连在一起的,而这些标签块是成树形结构保存的。最外层的开始标签,第二层开始标签………第二层结束标签,最外层的结束标签。所以我们添加一个标签需要添加开始块和结束块。因为我们添加一个属性不像是添加一个属性,需要的信息不是那么多。假如我们想插入如下标签块:
如果靠命令输入那是不现实的。所以这里我们在插入标签的时候,依赖的是需要一个xml文件,而这个文件中是保存了需要插入的标签内容,这样还可以支持同时插入多个标签内容。这时候我们就需要首先解析这个插入的xml文件结构。构造出对应的标签块信息。而我们知道AndroidManifest.xml中分为两种标签。一种是和application平级的标签,一种是application的内部标签。所以我们需要区分插入对待。因为如果我们想找到标签的插入口,最好的就是在标签的开始处,所以这里如果发现是application平级的标签,就插入到manifest标签块后面即可。如果是application的内部标签,就插入appliation标签块后面即可。
同样插入一个标签有可能增加字符串信息,所以还得更新修改字符串块信息,这个操作在增加标签中已经介绍了。主要还是继续看代码吧。
总结:
第一步:解析arsc文件中所有的标签块信息和属性信息,同时标记处manifest和application标签块的开始位置地址。
第二步:解析需要插入标签的xml信息,构造出对应的标签块信息,根据两种标签类型直接插入即可。
第三步:修改字符串块信息,和文件总大小。
注意:需要区分对待两种标签的插入操作。
三、工具用法
好了,上面就介绍完了操作arsc文件的工具原理,下面来看看工具的用法吧:
第一、用途
针对于特定apk反编译破解之后无法回编译操作,直接进行arsc文件的二进制文件修改,然后只需要二次签名即可。无需在进行反编译和回编译。
第二、用法
1》插入属性
java -jar AXMLEditor.jar -attr -i [标签名] [标签唯一标识] [属性名] [属性值] [输入xml] [输出xml]
案例:java -jar AXMLEditor.jar -attr -i application package debuggable true input_arsc.xml out_arsc.xml
application的标签中插入android:debuggable=”true”属性,让程序处于可调式状态
2》删除属性
java -jar AXMLEditor.jar -attr -r [标签名] [标签唯一标识] [属性名] [输入xml] [输出xml]
案例:java -jar AXMLEditor.jar -attr -r application allowBackup input_arsc.xml out_arsc.xml
application标签中删除allowBackup属性,这样此app就可以进行沙盒数据备份
3》更改属性
java -jar AXMLEditor.jar -attr -m [标签名] [标签唯一标识] [属性名] [属性值] [输入xml] [输出xml]
案例:java -jar AXMLEditor.jar -attr -m application package debuggable true input_arsc.xml out_arsc.xml
application的标签中修改android:debuggable=”true”属性,让程序处于可调式状态
4》插入标签
java -jar AXMLEditor.jar -tag -i [需要插入标签内容的xml文件] [输入xml] [输出xml]
案例:java -jar AXMLEditor.jar -tag -i [insert.xml] input_arsc.xml out_arsc.xml
因为插入标签时一个标签内容比较多,所以命令方式不方便,而是输入一个需要插入标签内容的xml文件即可。
5》删除标签
java -jar AXMLEditor.jar -tag -r [标签名] [标签唯一标识] [输入xml] [输出xml]
案例:java -jar AXMLEditor.jar -tag -r activity cn.wjdiankong.demo.MainActivity input_arsc.xml out_arsc.xml
删除android:name=”cn.wjdiankong.demo.MainActivity”的标签内容
工具源码下载地址:https://github.com/fourbrother/AXMLEditor
四、总结
当然这里还是有些操作不支持的,比如插入一个activity标签内容,现在不支持一些特殊的属性,比如theme类型,因为我们知道这些属性可能需要引用一些资源。而资源文件我们现在还没弄。所以引用资源类型的属性添加都是失败的。不过我们一般不会添加这些属性操作值。关于工具的使用案例分析期待下一篇文章。
《Android应用安全防护和逆向分析》
更多内容:点击这里
关注微信公众号,最新技术干货实时推送
添加时请注明:“编码美丽”非常感谢!
转载请注明:尼古拉斯.赵四 » Android中AndroidManifest ARSC 二进制文件修改器AXMLEditor