您的位置:首页 > 其它

resource.asrc文件结构分析

2015-04-16 15:57 253 查看


以下所有关于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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: