Android 安装包优化资源混淆 ( resources.arsc 资源映射表文件格式 | 头文件 数据格式 | 全局字符串池 数据格式 | 包数据 数据格式 | 包头 数据格式 )

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 安装包优化资源混淆 ( resources.arsc 资源映射表文件格式 | 头文件 数据格式 | 全局字符串池 数据格式 | 包数据 数据格式 | 包头 数据格式 )相关的知识,希望对你有一定的参考价值。





一、resources.arsc 资源映射表文件格式



上一篇博客 【Android 安装包优化】资源混淆 ( resources.arsc 资源映射表混淆 | resources.arsc 资源映射表二进制格式分析 | 混淆全局字符串池和资源名称字符串池 ) 对 resources.arsc 资源映射表 的二进制文件格式进行了分析 , 得出如下结论 :

资源混淆时 , 需要修改混淆 resources.arsc 资源映射表 的 全局字符串池 和 包数据下的 资源名称字符串池 ;


全局字符串池中是 资源 的文件路径 , “res/drawable/ic_launcher.png” , 包数据中的 资源名称字符串池 , 存储的文件的名称 “ic_launcher” ;

资源类型字符串池 , 不用进行混淆 , 在根据资源 ID 查找资源时 , 不会用到该数据块中的数据 ;


在这里插入图片描述

使用二进制文件查看器查看 resources.arsc 资源映射表 文件 :

在这里插入图片描述


部分数据列举 : 576 576 576 字节 ;

02 00 0C 00 B8 BC 05 00 01 00 00 00 01 00 1C 00 98 9E 00 00 0E 03 00 00 00 00 00 00 00 01 00 00 54 0C 00 00 00 00 00 00 00 00 00 00 0B 00 00 00 17 00 00 00 1B 00 00 00 27 00 00 00 15 01 00 00 66 01 00 00 B3 01 00 00 CD 01 00 00 DA 01 00 00 E9 01 00 00 EF 01 00 00 37 02 00 00 7D 02 00 00 BB 02 00 00 FE 02 00 00 4A 03 00 00 96 03 00 00 C6 03 00 00 F7 03 00 00 25 04 00 00 54 04 00 00 6F 04 00 00 8B 04 00 00 B7 04 00 00 D6 04 00 00 F4 04 00 00 23 05 00 00 46 05 00 00 66 05 00 00 8A 05 00 00 AB 05 00 00 CC 05 00 00 EC 05 00 00 2E 06 00 00 70 06 00 00 AB 06 00 00 EF 06 00 00 34 07 00 00 71 07 00 00 AA 07 00 00 E4 07 00 00 23 08 00 00 5B 08 00 00 94 08 00 00 D2 08 00 00 FE 08 00 00 2B 09 00 00 4D 09 00 00 70 09 00 00 9A 09 00 00 C5 09 00 00 F2 09 00 00 22 0A 00 00 53 0A 00 00 8C 0A 00 00 BB 0A 00 00 EA 0A 00 00 2A 0B 00 00 6A 0B 00 00 AA 0B 00 00 EA 0B 00 00 16 0C 00 00 4D 0C 00 00 7A 0C 00 00 A7 0C 00 00 ED 0C 00 00 31 0D 00 00 67 0D 00 00 9D 0D 00 00 D6 0D 00 00 03 0E 00 00 30 0E 00 00 6F 0E 00 00 AC 0E 00 00 E7 0E 00 00 1E 0F 00 00 5B 0F 00 00 98 0F 00 00 D5 0F 00 00 07 10 00 00 38 10 00 00 63 10 00 00 88 10 00 00 AE 10 00 00 D6 10 00 00 FB 10 00 00 25 11 00 00 66 11 00 00 A8 11 00 00 E1 11 00 00 0F 12 00 00 41 12 00 00 74 12 00 00 B0 12 00 00 ED 12 00 00 1C 13 00 00 4C 13 00 00 70 13 00 00 A1 13 00 00 D3 13 00 00 FA 13 00 00 1B 14 00 00 3D 14 00 00 61 14 00 00 82 14 00 00 A8 14 00 00 DB 14 00 00 03 15 00 00 20 15 00 00 41 15 00 00 67 15 00 00 97 15 00 00 D1 15 00 00 08 16 00 00 35 16 00 00 6C 16 00 00 A0 16 00 00 CD 16 00 00 04 17 00 00 38 17 00 00 63 17 00 00 9B 17 00 00 CE 17 00 00 F9 17 00 00 33 18 00 00 68 18 00 00 94 18 00 00 CA 18 00 00 FC 18 00 00 31 19 00 00 5F 19 00 00 93 19 00 00 C5 19 00 00




二、头文件 数据格式



头文件数据 : 数据格式是 小端格式 , 低位存储在低字节中 , 高位存储在高字节中 , 如头文件长度 0C 00 , 低字节 第 0 0 0 字节存储 0C , 高字节 第 1 1 1 字节存储 00 数据 ; ( 小端格式可读性差 )

02 00 0C 00 B8 BC 05 00 01 00 00 00

在这里插入图片描述


1. RES_TABLE_TYPE : 2 2 2 字节 , 表示文件类型 , 在 frameworks/base/include/androidfw/ResourceTypes.h 源码文件中定义 ;

enum {
    RES_NULL_TYPE               = 0x0000,
    RES_STRING_POOL_TYPE        = 0x0001,
    RES_TABLE_TYPE              = 0x0002,
    RES_XML_TYPE                = 0x0003,

    // Chunk types in RES_XML_TYPE
    RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
    RES_XML_START_NAMESPACE_TYPE= 0x0100,
    RES_XML_END_NAMESPACE_TYPE  = 0x0101,
    RES_XML_START_ELEMENT_TYPE  = 0x0102,
    RES_XML_END_ELEMENT_TYPE    = 0x0103,
    RES_XML_CDATA_TYPE          = 0x0104,
    RES_XML_LAST_CHUNK_TYPE     = 0x017f,
    // This contains a uint32_t array mapping strings in the string
    // pool back to resource identifiers.  It is optional.
    RES_XML_RESOURCE_MAP_TYPE   = 0x0180,

    // Chunk types in RES_TABLE_TYPE
    RES_TABLE_PACKAGE_TYPE      = 0x0200,
    RES_TABLE_TYPE_TYPE         = 0x0201,
    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,
    RES_TABLE_LIBRARY_TYPE      = 0x0203
};

2 . 头大小 : " 文件头 " 的大小 , 12 12 12 字节 , 文件头范围如下 :

在这里插入图片描述


3 . 文件大小 : 整个 resources.arsc 资源映射表 文件的大小 , 单位 字节 ;


4 . package 数 : 一般情况下 , 一个应用只有一个 package 包 ; 正常情况下 , 该值是 1 1 1 ;





三、全局字符串池 数据格式



字符串池混淆注意事项 : 修改 " 全局字符串池 " , " 资源名称字符串池 " 其最终的字符串数据块字节数 必须是 4 4 4 的整数倍 , 如果最后不足 4 4 4 字节 , 需要补 0 0 0 ;


蓝色部分是 全局字符串池 头文件部分 :

在这里插入图片描述


1 . RES_STRING_POOL_TYPE : 字符串池类型 , 2 2 2 字节 ;


2 . 头大小 : 2 2 2 字节 ;


3 . 块大小 : 4 4 4 字节 , 如下数据块大小 ;

在这里插入图片描述

4 . 字符串数 : 4 4 4 字节 , 字符串个数 ; 包括所有的 图片, 布局 等类型的资源对应的文件路径 , 定义的 strings 字符串资源 , value 值 资源 等 ;


5 . style 数 : 4 4 4 字节 , 字符串的样式 , 全局字符串池中的字符串样式一般为空 ;


6 . 标记 : 4 4 4 字节 , 用于标记字符串存储在 resources.arsc 资源映射表 文件中的编码方式 , UTF-8 或 UTF-16 两种编码方式 ;


7 . 字符串起始位置 : 4 4 4 字节 , 标记 全局字符串池 中的字符串开始位置 , 0 0 0 索引位置是 RES_STRING_POOL_TYPE 第一个字节位置 ;


8 . style 起始位置 : 4 4 4 字节 , 标记 全局字符串池 中的字符串风格数据的开始位置 , 0 0 0 索引位置是 RES_STRING_POOL_TYPE 第一个字节位置 ;


9 . 字符串偏移数组 : int 类型数组 , 每个 index 索引的 int 数组的元素值是 对应 index 索引的 字符串 对应的 首元素位置下标 ;





四、包数据 数据格式





1、包头 数据格式


包数据中的包头数据格式 :

在这里插入图片描述

1 . RES_TABLE_PACKAGE_TYPE : 资源包类型格式 , 2 2 2 字节 ;


2 . 头大小 : 2 2 2 字节 ;


3 . 块大小 : 4 4 4 字节 ;


4 . 包 ID : 4 4 4 字节 , 包名对应的 ID 常量标识 ;


5 . 包名 : 256 256 256 字节 , 解析出来就是对应的再清单文件中配置的包名 , “kim.hsl.svg” ;


6 . 资源类型字符串池偏移 : 4 4 4 字节 , 从 RES_TABLE_PACKAGE_TYPE 的首字节作为 0 0 0 位置开始计数 , 到 " 资源类型字符串池 " 的首字节的字节索引值 , 如 : 整个包头占 2000 字节 , 那么包头索引值是 0 0 0 ~ 1999 1999 1999 , " 资源类型字符串池 " 的首字节偏移就是 2000 2000 2000 ;


7 . lastPublicType : 4 4 4 字节 , 默认为 0 0 0 , 无意义 ;


8 . 资源关键字字符串池偏移 : 4 4 4 字节 , 就是 " 资源名称字符串池 " 的偏移 , 从 RES_TABLE_PACKAGE_TYPE 的首字节作为 0 0 0 位置开始计数 , 中间隔着 包头数据 和 资源类型字符串池 两个数据块 ;


9 . lastPublicType : 4 4 4 字节 , 默认为 0 0 0 , 无意义 ;


10 . typeIdOffset : 4 4 4 字节 ;



2、资源类型字符串池 数据格式


资源类型字符串池 与 " 全局字符串池 " 格式相同 , 参考上面的 " 三、全局字符串池 数据格式 " 章节 ;

在这里插入图片描述



3、资源名称字符串池 数据格式


资源名称字符串池 与 " 全局字符串池 " 格式相同 , 参考上面的 " 三、全局字符串池 数据格式 " 章节 ;

在这里插入图片描述





五、参考资料



参考官方文档 :

参考之前的博客资源 :


博客资源 :

以上是关于Android 安装包优化资源混淆 ( resources.arsc 资源映射表文件格式 | 头文件 数据格式 | 全局字符串池 数据格式 | 包数据 数据格式 | 包头 数据格式 )的主要内容,如果未能解决你的问题,请参考以下文章

Android 安装包优化资源混淆 ( resources.arsc 资源映射表文件格式 | 头文件 数据格式 | 全局字符串池 数据格式 | 包数据 数据格式 | 包头 数据格式 )

Android 安装包优化资源混淆 ( AAPT2 资源编译工具 | resources.arsc 资源映射表 工作机制 )

Android包体积优化上篇- 资源混淆优化

Android 安装包优化开启资源压缩

Android 安装包优化开启 ProGuard 混淆 ( 压缩 Shrink | 优化 Optimize | 混淆 Obfuscate | 预检 | 混淆文件编写 | 混淆前后对比 )

Android 安装包优化开启资源压缩 ( 资源压缩配置 | 启用严格模式的资源引用检查 | 自定义保留/移除资源配置 | 资源压缩效果 )