resource.asrc文件结构分析

以下所有关于res的结构均可以在安卓源码 ResourceTypes.h中找到,请参考ResourceTypes.h各个结构注释

asrc文件头

典型的resource.asrc文件由一个大块定义为ResTable_header的结构开始:
<span style="font-weight: normal;">struct ResTable_header
{
    struct ResChunk_header header;


    // The number of ResTable_package structures.
    uint32_t packageCount;
};</span>




查看上面的结构,除了packageCount还包含另一个结构,ResChunk_header
<span style="font-weight: normal;">struct ResChunk_header
{
    // Type identifier for this chunk.  The meaning of this value depends
    // on the containing chunk.
    uint16_t type;


    // Size of the chunk header (in bytes).  Adding this value to
    // the address of the chunk allows you to find its associated data
    // (if any).
    uint16_t headerSize;


    // Total size of this chunk (in bytes).  This is the chunkSize plus
    // the size of any data associated with the chunk.  Adding this value
    // to the chunk allows you to completely skip its contents (including
    // any child chunks).  If this value is the same as chunkSize, there is
    // no data associated with the chunk.
    uint32_t size;
};
</span>



根据上面的信息,我们使用真实的数据来解释


[00000010]   02 00 0C 00 BC C6 07 00   01 00 00 00 01 00 1C 00 
[00000020]   F0 16 04 00 95 18 00 00   00 00 00 00 00 01 00 00 
[00000030]   70 62 00 00 00 00 00 00   00 00 00 00 2F 00 00 00


type: 前两个字节(uint16_t)偏移量(0-1)是类型表示,在上面的例子中,0x0002是RES_TABLE_TYPE。
headerSize: 下面的两个字节(uint16_6)偏移量(2-3),000c是头的大小
size: uint32_t偏移量(4-7),0x0007c6bc,是整个文件asrc文件的大小,现在这个文件的大小是509628,下面是我的asrc文件信息。
509628 Apr  7 15:58 resources.arsc
上面的三个字段是ResChunk_header的信息。
在ResChunk_header后面是packageCount。
pacageCount: uint32_t偏移量(8-0xb),0x00000001。





asrc文件的数据部分,在 ResTable_header结构后,包含另外两个结构,定义为ResStringPool_header其次是ResTable_package。
<span style="font-weight: normal;">struct ResStringPool_header
{
    struct ResChunk_header header;


    // Number of strings in this pool (number of uint32_t indices that follow
    // in the data).
    uint32_t stringCount;


    // Number of style span arrays in the pool (number of uint32_t indices
    // follow the string indices).
    uint32_t styleCount;


    // Flags.
    enum {
        // If set, the string index is sorted by the string values (based
        // on strcmp16()).
        SORTED_FLAG = 1<<0,


        // String pool is encoded in UTF-8
        UTF8_FLAG = 1<<8
    };
    uint32_t flags;


    // Index from header of the string data.
    uint32_t stringsStart;


    // Index from header of the style data.
    uint32_t stylesStart;
};
struct ResTable_package
{
    struct ResChunk_header header;


    // If this is a base package, its ID.  Package IDs start
    // at 1 (corresponding to the value of the package bits in a
    // resource identifier).  0 means this is not a base package.
    uint32_t id;


    // Actual name of this package, \0-terminated.
    uint16_t name[128];


    // Offset to a ResStringPool_header defining the resource
    // type symbol table.  If zero, this package is inheriting from
    // another base package (overriding specific values in it).
    uint32_t typeStrings;


    // Last index into typeStrings that is for public use by others.
    uint32_t lastPublicType;


    // Offset to a ResStringPool_header defining the resource
    // key symbol table.  If zero, this package is inheriting from
    // another base package (overriding specific values in it).
    uint32_t keyStrings;


    // Last index into keyStrings that is for public use by others.
    uint32_t lastPublicKey;


    uint32_t typeIdOffset;
};</span>




可以看出每个块都包含ResChunk_header结构。
下面解释ResStringPool_header结构。


[00000010]   02 00 0C 00 BC C6 07 00   01 00 00 00 01 00 1C 00   ........ ........
[00000020]   F0 16 04 00 95 18 00 00   00 00 00 00 00 01 00 00   ........ ........
[00000030]   70 62 00 00 00 00 00 00   00 00 00 00 2F 00 00 00   pb...... ........
[00000040]   61 00 00 00 7E 00 00 00   A1 00 00 00 C6 00 00 00





StringPool结构是从偏移0xc开始。
0xc-0xd是块的类型,0x0001,RES_STRING_POOL_TYPE
0xe-0xf是头的大小,0x001c
0x10-0x13是块的大小,0x000416f0
0x14-0x17是字符串数量,(uint32_t stringCount),这里的数量是0x00001895
0x18-0x1b是style数量,(uint32_t styleCount),这里是0x0
0x1c-0x1f是flag,flag表示了string的编码格式,这里是0x0000010000,(UTF8_FLAG = 1<<8)所以这里的字符串是utf8编码。
0x20-0x23是字符串在文件中开始的偏移地址(uint32_t stringsStart),这里是0x00006270。
0x24-0x27是sytle在文件中开始的偏移,这里由于没有定义style,所以是0x0
在string头部后面是一系列的dword,标示相对于stringStart的偏移地址,下面我们看些检索到相应string的例子
1、string  0x28-0x2b   , 偏移地址是:0x0
   真实地址:location=stringStart+offset+headeroffset
            location=0x627c
2、string  0x2c-0x2f   , 偏移地址是:0x2f
   真实地址:location=0x6270+0x002f=0x629f



下面我们查看相应的数据:

0000627c  2c 2c 72 65 73 2f 64 72  61 77 61 62 6c 65 2f 61  |,,res/drawable/a|
0000628c  6c 6c 5f 61 70 70 73 5f  6c 69 73 74 5f 69 6e 64  |ll_apps_list_ind|
0000629c  65 78 5f 69 74 65 6d 5f  62 67 2e 78 6d 6c 00 2f  |ex_item_bg.xml./|
000062ac  2f 72 65 73 2f 64 72 61  77 61 62 6c 65 2f 61 70  |/res/drawable/ap|
000062bc  70 5f 64 6f 77 6e 6c 6f  61 64 5f 70 72 6f 67 72  |p_download_progr|
000062cc  65 73 73 62 61 72 5f 73  74 79 6c 65 2e 78 6d 6c  |essbar_style.xml|
000062dc  00 1a 1a 72                                       |...r|



ResTable_package在ResStringPool_header的后面
ResTable_package的偏移地址是:ResStringPool_header的size+0xc=0x416fc
下面是7f 007f 00

000416fc  00 02 1c 01 c0 af 03 00  7f 00 00 00 63 00 6f 00  |............c.o.|
0004170c  6d 00 2e 00 68 00 6f 00  6c 00 61 00 2e 00 6c 00  |m...h.o.l.a...l.|
0004171c  61 00 75 00 6e 00 63 00  68 00 65 00 72 00 00 00  |a.u.n.c.h.e.r...|
0004172c  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000417fc  00 00 00 00 00 00 00 00  00 00 00 00 1c 01 00 00  |................|
0004180c  0d 00 00 00 d4 01 00 00  3f 06 00 00 01 00 1c 00  |........?.......|
0004181c  b8 00 00 00 0d 00 00 00  00 00 00 00 00 01 00 00  |................|
0004182c  50 00 00 00 00 00 00 00  00 00 00 00 07 00 00 00  |P...............|
0004183c  12 00 00 00 1b 00 00 00  22 00 00 00 28 00 00 00  |........"...(...|
0004184c  2e 00 00 00 33 00 00 00  3b 00 00 00 43 00 00 00  |....3...;...C...|
0004185c  4b 00 00 00 54 00 00 00  5c 00 00 00 04 04 61 74  |K...T...\.....at|
0004186c  74 72 00 08 08 64 72 61  77 61 62 6c 65 00 06 06  |tr...drawable...|
0004187c  6c 61 79 6f 75 74 00 04  04 61 6e 69 6d 00 03 03  |layout...anim...|



前面8个字节是header结构,header type是0x0200  RES_TABLE_PACKAGE_TYPE


后面两个字节0x007f,是packageid。
在id后面的128个字节是packagename
接下来的160个字节分别对应上面的pakcagename后面的几个字段


在ResTable_package后面是若干 ResTable_type 和 ResTable_typeSpec ,分别代表一种资源类型(图片,attrs,字符串等)


后面是ResTable_typeSpec结构

<span style="font-weight: normal;">struct ResTable_typeSpec
{
    struct ResChunk_header header;


    // The type identifier this chunk is holding.  Type IDs start
    // at 1 (corresponding to the value of the type bits in a
    // resource identifier).  0 is invalid.
    uint8_t id;
    
    // Must be 0.
    uint8_t res0;
    // Must be 0.
    uint16_t res1;
    
    // Number of uint32_t entry configuration masks that follow.
    uint32_t entryCount;


    enum {
        // Additional flag indicating an entry is public.
        SPEC_PUBLIC = 0x40000000
    };
};


struct ResTable_type
{
    struct ResChunk_header header;


    enum {
        NO_ENTRY = 0xFFFFFFFF
    };
    
    // The type identifier this chunk is holding.  Type IDs start
    // at 1 (corresponding to the value of the type bits in a
    // resource identifier).  0 is invalid.
    uint8_t id;
    
    // Must be 0.
    uint8_t res0;
    // Must be 0.
    uint16_t res1;
    
    // Number of uint32_t entry indices that follow.
    uint32_t entryCount;


    // Offset from header where ResTable_entry data starts.
    uint32_t entriesStart;
    
    // Configuration this collection of entries is designed for.
    ResTable_config config;
};


struct ResTable_config


struct ResTable_entry
{
    // Number of bytes in this structure.
    uint16_t size;


    enum {
        // If set, this is a complex entry, holding a set of name/value
        // mappings.  It is followed by an array of ResTable_map structures.
        FLAG_COMPLEX = 0x0001,
        // If set, this resource has been declared public, so libraries
        // are allowed to reference it.
        FLAG_PUBLIC = 0x0002
    };
    uint16_t flags;
    
    // Reference into ResTable_package::keyStrings identifying this entry.
    struct ResStringPool_ref key;
};
</span>


后续还有很多没有分析的,日后在增加。


参考:
https://ekasiswanto.wordpress.com/2012/09/19/descriptions-of-androids-resources-arsc/
https://github.com/iBotPeaches/Apktool

你可能感兴趣的:(resource.asrc文件结构分析)