resources.arsc 格式

https://ekasiswanto.wordpress.com/2012/09/19/descriptions-of-androids-resources-arsc/

Descriptions of Android’s Resources.arsc

I’ve made this article because in the course of completing one of my projects that involved android infrastructure, I came across certain problem in trying to generate R.java file using aapt.exe.

Because this is the first time of my involvement in android platform, I planned to perform a study using existing sample application given android sdk which is LunarLander application.

I’ve perform proper settings in my netbeans’ Lunarlander project and resolves almost all of the references, except the requirement of R.java which is somewhat missing.

After perform researching on the net, it is found that R.java can be generated using aapt command as follows:

aapt package -a -v -f -m -J d:\projects\lunarlander -I android.jar -MAndroidManifest.xml -S D:\Projects\LunarLander\res -J .\gen –generate-dependencies

But it comes up with the “String types not allowed” error:

By perform checks to the existing resources given in LunarLander sample, I realized there’s no definition for layout_width, so I presume this must be inside android.jar file.

This *.jar file can be opened using any decompressing application that can understand *.jar format such as 7-zip, etc and contains, among the *.class files, also contains resources.arsc and compressed xml inside the res directory.

By performing the search of “layout_width” using hex editor against files inside the res directory, it is found that there are many of these instances and also inside resources.arsc files. So here comes the question of which files in either inside res directory the aapt.exesearches for layout_width definition.

Since aapt.exe is an open source application, although I do not have the debug symbol files in *.PDB format which is windows specific, I can download the related source code and perform analysis to figure out the working of assembly routines inside aapt.exe. This is certainly slows down the code analysis process comparing to when the debug symbol is present.

The scarcity of debug symbol seems to be a plague of all open source application. I just wonder why there’s no attention focused to provide the debug symbol just as windows platform that provide debug symbol through their symbol servers.

Then, I realized that to find the “layout_width” definition, aapt.exe do not use files in res directory, but it used resources.arsc instead. This file contains some format, and since it is an open source application, I think I will easily find the documentation regarding this structure.

But in fact, again I disappointed by lack of documentation that seems also an another plague that will hamper the progress of adoption of this platform by IT community.

Seems it is also useless by just complaining, I decided to perform in depth analysis of this structure, using the only available benefit of open source application by analyzing the assembly execution and try to make sense of its working routine by examining the given source code.

This is also can be a first step of creating a solid foundation of understanding the android platform and also can be used whenever I encounter another kind of problems or issues beside that one above.

Below is some descriptions of this structure that is obtained using the above described methods. Each of the structure definition can be found at ResourceTypes.h file in original android’s source code.

The typical resources.arsc files consists of 1 big block defined by ResTable_header structure:

If you examine from the above structure, besides the packageCount, it contains another structure called ResChunk_header:

Based on information given by the above structure, let’s examine the actual data (from resources.arsc):

Word bytes (uint16_t) at offset 0 to 1 is type identifier, in the above sample, it contains 0x0002 which is RES_TABLE_TYPE.

Word bytes (uint16_t) at offset 2 to 3 is the header size, in the above sample, it contains 0x000C as denoted by the red box above.

Dword bytes (uint32_t) at offset 4 to 7 which is 0x001A1530 is total block size and in this particular file, it is the entire length or the file size of resources.arsc file.

Dword (uint32_t) at offset 8 to 0xB which is 0x00000001 is certainly a package count.

The data portion of this block, after removing the ResTable_header structure size of 0x0C contains another 2 big blocks defined by ResStringPool_header structure followed by ResTable_package structure:

It can be seen that each block contains header information and other items that is specific for each block.

Below is the sample description of ResStringPool_header structure from actual resources.arsc file:

Word bytes at offset 0 to 1 is again a type identifier, this time it contains 0x0001 which is RES_STRING_POOL_TYPE.

Word bytes at offset 2 to 3 is the header size, in the above sample, it contains 0x001C as denoted by the red box above.

Dword bytes at offset 4 to 7 which is 0x000E7900 is total block size

Dword bytes at offset 8 to 0x0B which is 0x00002864 is stringCount

Dword bytes at offset 0x0C to 0x0F which is 0x00001E21 is styleCount

Dword bytes at offset 0x10 to 0x13 which is 0x00000000 is flags

Dword bytes at offset 0x14 to 0x17 which is 0x00011A30 is stringsStart or starting offset of strings pool

Dword bytes at offset 0x18 to 0x1B which is 0x000DFEA0 is stylesStart or starting offset of styles

Immediately followed by this header record is series of dword data denotes the offset location relative to stringsStart. Let’s view some of this sample to get a feel of how to navigate each string items:

Dword bytes at offset 0 to 3 is the string data for index 0. It contains 0x0 and to locate the string position, add this to stringsStart value:

Let’s navigate to this offset location:

For each string pool item, the first two bytes contains the string length followed by actual string data. In this case, at string index 0 contains an empty string.

Let’s navigate to another offset location. The dword data at offset 4 to 7 contains 0x00000004. By applying the above formula:

From the above picture, at the offset location 0x11A34 contains 0x0006 word value. This is the string length, starting at offset 0x11A36 and so on, contains “Cancel” string.

To retrieve all these strings data, repeat the above steps until stringsCount is reached.

Followed by this block is ResTable_package:

It has a rather big header size of 0x11C. This block is of RES_TABLE_PACKAGE_TYPE (0x0200). Inside this structures contains typeStrings block, keyStrings block, followed by one or more ResTable_type and ResTable_typeSpec structures.

To find the typeStrings offset location, find the offset value at offset 0x10C to 0x10F. In the above sample, the value is 0x0000011C starting from the start of the block. By navigating to this location:

This is again the ResStringPool_header structure that contains 0x0F number of string with index value of relative locations offset as follows:

Index 0 (or first string) in the string pool is located at offset 0x58 (see red box at the above structure):

At that location, the string contains “attr”, index 1 is at 0x64 (i.e. 0x58 + 0xC) which is “id” etc.

Immediately followed the typeStrings structure is keyStrings structure:

By examining the type id, it also in the form of ResStringPool_header structure, of 0x225DC size. To find the next available block, adds the offset location with the size of this block, which is 0x225DC:

Type 0x202 is registered as RES_TABLE_TYPE_SPEC_TYPE which has structure definition as follows:

This block has the size of 0xB0C, by adding this value to the existing file to find the next offset location we arrive at:

The type of this block (0x201) is RES_TABLE_TYPE_TYPE with structure definitions as follows:

By traversing in this way, we can retrieve all of these kind of blocks until it reaches the end of ResTable_package block.

Each ResTable_Type block contains one or many ResTable_entry structures indexed by array of uint32_t located just after ResTable_type of size 0x34:

To locate each ResTable_entry structure, just add the above values with entriesStart value. For example, let’s located the second entry (index 1) which has 0x1C value. By adding it to entriesStart 0xB30, we have:

Depending of the record size, there are actually two form of ResTable_entry structure, i.e. ResTable_entry (record size 0x8) itself:

And ResTable_map_entry (record size 0x10) which extends the existing ResTable_entry structure:

The ResStringPool_ref field at offset 4 through 7 (0x1) can be used to find descriptions of this entry by referring it to keyStrings block by using the formula:

By using the above formula, we have 28 + 4 = 32 (0x20). This is the offset location of value to be added as an offset to the stringsStart of ResStringPool_header of keyStrings block, so at offset 0x20 we have:

Adding this to stringsStart of (0x3220) = 0x3220 + 0x0E we have 0x322E:

Because flags field at offset 2 to 3 (0x03) has the FLAG_COMPLEX, according to the definition, it is followed by ResTable_map instead of Res_value structures. The total number of ResTable_map structure is determined by count field value at offset C to F which is 0x1. This structure is used to find the actual value assigned to particular keyStrings item, and for the above illustrations, the value of “label” item.

Here is the description of ResTable_map structure (for the sake of brevity, I’ve omitted the available enumerated values):

And of Res_value structure:

The ResTable_ref structure contains just one field of uint32_t which has 0x08 bytes of size. So here is the ResTable_map for “label” item:

It’s name of value 0x01000000 is of ATTR_TYPE, a special form of name that denotes attribute’s type code according to android’s definition. The dataType field at offset 7 (0x10) is of TYPE_FIRST_INT and it has 0x3 as its value (attribute’s type code).

Based on the above illustrations, let’s try to find available value of “layout_width” that causes the “string types not allowed” error. First, we have to identify this value using dump command:

From dump information we have:

spec resource 0x010100f4 android:attr/layout_width: flags=0x40000000

Based on android definition, the id is in the form of 0xpptteeee, so this id came from package 1, type 1 with item index 0xF4. The first task is to find offset location of this entry using this formula:

For 0xF4 (244) thus we have 52 + 4 * 244 = 1028 (0x404):

So at offset 0x404 we have 0x2350, by adding this to entriesStart of 0xB30 we have 0x2E80:

It is clearly of FLAG_COMPLEX type and has 3 enumerated entries as follows:

Entry #1:

The attribute’s type code for layout_width is 0x00010040

Entry #2:

This has 0x010200E2 as its name and by referencing to the dump file we get:

spec resource 0x010200e2 android:id/fill_parent: flags=0x00000000

It has 0xFFFFFFFF (-1) as its value and “fill_parent” for the name

Entry #3:

0x010200E3 refers to:

spec resource 0x010200e3 android:id/wrap_content: flags=0x00000000

So, the causes of the error is that layout_width do not has “match_parent” as its recognized enumerated values.

你可能感兴趣的:(resources.arsc 格式)