- 对本书的赞誉
- 前言
- 基础篇
- 第 1 章 Android 中锁屏密码加密算法分析
- 第 2 章 Android 中 NDK 开发
- 第 3 章 Android 中开发与逆向常用命令总结
- 第 4 章 so 文件格式解析
- 第 5 章 AndroidManifest.xml 文件格式解析
- 第 6 章 resource.arsc 文件格式解析
- 第 7 章 dex 文件格式解析
- 防护篇
- 第 8 章 Android 应用安全防护的基本策略
- 第 9 章 Android 中常用权限分析
- 第 10 章 Android 中的 run-as 命令
- 第 11 章 Android 中的 allowBackup 属性
- 第 12 章 Android 中的签名机制
- 第 13 章 Android 应用加固原理
- 第 14 章 Android 中的 so 加固原理
- 工具篇
- 第 15 章 Android 逆向分析基础
- 第 16 章 反编译神器 apktool 和 Jadx
- 第 17 章 Hook 神器 Xposed
- 第 18 章 脱壳神器 ZjDroid
- 第 19 章 Native 层 Hook 神器 Cydia Substrate
- 操作篇
- 第 20 章 静态方式逆向应用
- 第 21 章 动态调试 smali 源码
- 第 22 章 IDA 工具调试 so 源码
- 第 23 章 逆向加固应用
- 第 24 章 逆向应用经典案例分析
- 第 25 章 Android 中常见漏洞分析
- 第 26 章 文件加密病毒 Wannacry 样本分析
6.3 解析代码
因为篇幅的原因,这里就不把所有的代码都粘贴出来了,后面会列出代码下载地址,首先读取 resource.arsc 文件到一个字节数组,然后开始解析。
6.3.1 解析头部信息
头部信息代码如下:
解析结果如下:
6.3.2 解析资源字符串内容
解析资源字符串代码如下:
这里有一个核心的方法 parseStringPoolChunk:
这里在得到一个字符串的时候,需要得到字符串的开始位置和字符串的大小即可,这点和解析 AndroidManifest.xml 文件中的字符串原理是一样的。就是一个字符串的头两个字节中的最后一个字节是字符串的长度。这里在解析完字符串之后,需要用一个列表将其存储起来,后面要用到,需要通过索引来取字符串内容。
解析结果如下:
6.3.3 解析包信息
解析包信息代码如下:
这里看到有一个特殊的地方,就是最后两行,这是后面需要重点解析的两个内容,一个是资源值字符串的偏移值,另一个是资源类型字符串的偏移值。
解析结果如下:
6.3.4 解析资源类型的字符串内容
解析资源类型的字符串代码如下:
这里也是用 parseStringPoolChunk 方法进行解析的,同样也需要用一个字符串列表存储内容。
解析结果如下:
6.3.5 解析资源值字符串内容
解析资源值字符串内容代码如下:
这里也是使用 parseStringPoolChunk 方法来解析,解析完之后需要用一个字符串列表保存,后面需要使用索引值来访问。
解析结果如下:
6.3.6 解析正文内容
这里说到的正文内容就是 ResValue 值,是开始构建 public.xml 中的条目信息,和类型的分离不同的 XML 文件,所以这部分内容的解析工作有点复杂,如下所示:
这里有一个循环解析,有两个方法,一个是 isEnd 方法,另一个是 isTypeSpec 方法。
如果仔细看前面的图 6-3,就可以看到后面的 ResType 和 ResTypeSpec 两个内容是交替出现的,直到文件结束。
所以 isEnd 方法就是判断是否到达文件结束位置:
还有一个方法就是判断是 ResType 还是 ResTypeSpec,这可以通过 Chunk 中头部信息来区分的:
下面分别来解析 ResTypeSpec 和 ResType 这两个内容。
1.解析 ResTypeSpec
主要得到 Res 的每个类型名:
解析结果如下:
2.解析 ResType
主要得到每个 res 类型的所有条目内容:
看到这里,发现解析很复杂,和在讲解数据结构的时候一样,需要解析很多内容:ResValue、ResTableMap、ResTableMapEntry、ResTableEntry、ResConfig。关于每个数据结构如何解析这里就不多说了,就是读取字节即可。这里有一个核心的代码:
判断 flag 的值来进行不同的解析操作。需要注意这点。
解析结果如下:
看到解析结果还是挺欣慰的,因为最难的地方解析成功了,这就是想要的结果。这里需要解释的是,有了这些值构建 public.xml 内容和各个类型的 XML 内容就很简单了。
注意,这里 ResId 的构造方法是:
可以看到一个 int 类型的 resId,它的最高两个字节表示 packId,系统资源 id 是 0x01,普通应用资源 id 是 0x7F。它的中间的两个字节表示 resTypeId,类型 id,这个值从 0 开始,比如例子中第一个类型是 attr,那么它的 resTypeId 就是 00。它的最低四个字节表示这个资源的顺序 id,从 1 开始,逐渐累加 1。
提示:项目下载地址: https://github.com/fourbrother/parse_androidarsc
上面就解析完了所有的 resource.arsc 文件,解析 resource.arsc 文件格式的目的有两个:
·在使用 apktool 工具进行反编译的时候,经常出现一些莫名的异常信息,最多的就是 NotFound ResId 0x0000XXX 这些内容。那么这时候就需要修复,当然可以得到 apktool 的源码来解决这个问题,还可以使用自己写的这套解析代码。
·解析 resource.arsc 文件之后,对 resource.arsc 文件格式如果有了解,可以对资源文件名进行混淆,从而减小 apk 包大小。因为 META-INF 文件夹下的三个文件体积很大,原因就是它们内部保存了每个资源名称,在项目中有时候为了不造成冲突,就把资源名起的很长,那么这样就会导致 apk 的包很大。同样 resource.arsc 文件也会很大,因为资源名都是需要保存的,但是 Android 中的混淆是不会对资源文件进行混淆的,所以这时候就可以通过这个思路来减小包 apk 的大小了。
在前面一章中已经介绍了关于 aapt 命令的用法了,这里依然可以利用 aapt 命令解析 arsc 文件,用 aapt 命令很简单:
将输入的结果定向到 demo.txt 中,如图 6-7 所示。
图 6-7 用 aapt 命令输出结果
看到内容就是上面解析的 AndroidManifest.xml 内容,所以这也是一个解析方法。为何 aapt 命令最后说呢?因为了解 AndroidManifest.xml 格式能更好地掌握解析方法。以后记得有一个 aapt 命令就好了,它的用途很多,可以单独编译成一个 resource.arsc 文件来,后面会用到这个命令。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论