-
-
[翻译]Android资源文件结构分析,包括AndroidManifest,layout等
-
发表于: 2014-11-10 11:43 8714
-
一些说明:
安卓资源文件头,每一个都是按照这种格式定义的。
uint16_t,表示是16位即两个字节。
uint32_t,表示是32位即4个字节。
我觉得翻译多来,不如读原文。后面会有列子解析。
axmlprinter是根据这个格式进行编写的,不是很全面。
例子:
1.对于给的这个test.xml文件,这是一个AndroidManifest.xml文件,
对照ResChunk_header结构。前8个字节依次是 03 00 08 00 ,18 06 00 00
类型为0003,为RES_XML_TYPE,该块长度为0008个字节,该快所拥有的整体字节,
00 00 06 18,对比该test.xml文件,恰好。
2.往下看,01 00 1C 00 , 14 03 00 00,1c 00 00 00,00 00 00 00,
00 00 00 00, 8C 00 00 00, 00 00 00 00 为第2个块,
类型为1, RES_STRING_POOL_TYPE,是一个字符串池。对比ResStringPool_header结构体,
该结构体大小正好为28个字节。
1c即描述该块的大小字节数为
28个字节,整体块大小为0314。1c为字符串的个数。
下面是style的个数,为0,flag标志为为0,8C为字符串开始偏移位置,后面那个四个字节为style的偏移
也是0
3.其他的结构体,分析类似。
4.根据后面的分析,可以建立好资源映射等。读者可自己分析,以加强印象。
5.该文件在Android的源代码中。位置在4.4版本中是
frameworks/base/include/androidfw/ResourceTypes.h
6.那个text.xml.txt把后缀名字修改一下,就是一个AndroidManifest.xml文件了。是,资源格式的。
/** ********************************************************************
* Base Types
*
* These are standard types that are shared between multiple specific
* resource types.
*
*********************************************************************** */
/**
* Header that appears at the front of every data chunk in a resource.
*/
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;
};
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
};
/**
* Representation of a value in a resource, supplying type
* information.
*/
struct Res_value
{
// Number of bytes in this structure.
uint16_t size;
// Always set to 0.
uint8_t res0;
// Type of the data value.
enum {
// Contains no data.
TYPE_NULL = 0x00,
// The 'data' holds a ResTable_ref, a reference to another resource
// table entry.
TYPE_REFERENCE = 0x01,
// The 'data' holds an attribute resource identifier.
TYPE_ATTRIBUTE = 0x02,
// The 'data' holds an index into the containing resource table's
// global value string pool.
TYPE_STRING = 0x03,
// The 'data' holds a single-precision floating point number.
TYPE_FLOAT = 0x04,
// The 'data' holds a complex number encoding a dimension value,
// such as "100in".
TYPE_DIMENSION = 0x05,
// The 'data' holds a complex number encoding a fraction of a
// container.
TYPE_FRACTION = 0x06,
// Beginning of integer flavors...
TYPE_FIRST_INT = 0x10,
// The 'data' is a raw integer value of the form n..n.
TYPE_INT_DEC = 0x10,
// The 'data' is a raw integer value of the form 0xn..n.
TYPE_INT_HEX = 0x11,
// The 'data' is either 0 or 1, for input "false" or "true" respectively.
TYPE_INT_BOOLEAN = 0x12,
// Beginning of color integer flavors...
TYPE_FIRST_COLOR_INT = 0x1c,
// The 'data' is a raw integer value of the form #aarrggbb.
TYPE_INT_COLOR_ARGB8 = 0x1c,
// The 'data' is a raw integer value of the form #rrggbb.
TYPE_INT_COLOR_RGB8 = 0x1d,
// The 'data' is a raw integer value of the form #argb.
TYPE_INT_COLOR_ARGB4 = 0x1e,
// The 'data' is a raw integer value of the form #rgb.
TYPE_INT_COLOR_RGB4 = 0x1f,
// ...end of integer flavors.
TYPE_LAST_COLOR_INT = 0x1f,
// ...end of integer flavors.
TYPE_LAST_INT = 0x1f
};
uint8_t dataType;
// Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
enum {
// Where the unit type information is. This gives us 16 possible
// types, as defined below.
COMPLEX_UNIT_SHIFT = 0,
COMPLEX_UNIT_MASK = 0xf,
// TYPE_DIMENSION: Value is raw pixels.
COMPLEX_UNIT_PX = 0,
// TYPE_DIMENSION: Value is Device Independent Pixels.
COMPLEX_UNIT_DIP = 1,
// TYPE_DIMENSION: Value is a Scaled device independent Pixels.
COMPLEX_UNIT_SP = 2,
// TYPE_DIMENSION: Value is in points.
COMPLEX_UNIT_PT = 3,
// TYPE_DIMENSION: Value is in inches.
COMPLEX_UNIT_IN = 4,
// TYPE_DIMENSION: Value is in millimeters.
COMPLEX_UNIT_MM = 5,
// TYPE_FRACTION: A basic fraction of the overall size.
COMPLEX_UNIT_FRACTION = 0,
// TYPE_FRACTION: A fraction of the parent size.
COMPLEX_UNIT_FRACTION_PARENT = 1,
// Where the radix information is, telling where the decimal place
// appears in the mantissa. This give us 4 possible fixed point
// representations as defined below.
COMPLEX_RADIX_SHIFT = 4,
COMPLEX_RADIX_MASK = 0x3,
// The mantissa is an integral number -- i.e., 0xnnnnnn.0
COMPLEX_RADIX_23p0 = 0,
// The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
COMPLEX_RADIX_16p7 = 1,
// The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
COMPLEX_RADIX_8p15 = 2,
// The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
COMPLEX_RADIX_0p23 = 3,
// Where the actual value is. This gives us 23 bits of
// precision. The top bit is the sign.
COMPLEX_MANTISSA_SHIFT = 8,
COMPLEX_MANTISSA_MASK = 0xffffff
};
// The data for this item, as interpreted according to dataType.
uint32_t data;
void copyFrom_dtoh(const Res_value& src);
};
/**
* This is a reference to a unique entry (a ResTable_entry structure)
* in a resource table. The value is structured as: 0xpptteeee,
* where pp is the package index, tt is the type index in that
* package, and eeee is the entry index in that type. The package
* and type values start at 1 for the first item, to help catch cases
* where they have not been supplied.
*/
struct ResTable_ref
{
uint32_t ident;
};
/**
* Reference to a string in a string pool.
*/
struct ResStringPool_ref
{
// Index into the string pool table (uint32_t-offset from the indices
// immediately after ResStringPool_header) at which to find the location
// of the string data in the pool.
uint32_t index;
};
/** ********************************************************************
* String Pool
*
* A set of strings that can be references by others through a
* ResStringPool_ref.
*
*********************************************************************** */
/**
* Definition for a pool of strings. The data of this chunk is an
* array of uint32_t providing indices into the pool, relative to
* stringsStart. At stringsStart are all of the UTF-16 strings
* concatenated together; each starts with a uint16_t of the string's
* length and each ends with a 0x0000 terminator. If a string is >
* 32767 characters, the high bit of the length is set meaning to take
* those 15 bits as a high word and it will be followed by another
* uint16_t containing the low word.
*
* If styleCount is not zero, then immediately following the array of
* uint32_t indices into the string table is another array of indices
* into a style table starting at stylesStart. Each entry in the
* style table is an array of ResStringPool_span structures.
*/
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;
};
/**
* This structure defines a span of style information associated with
* a string in the pool.
*/
struct ResStringPool_span
{
enum {
END = 0xFFFFFFFF
};
// This is the name of the span -- that is, the name of the XML
// tag that defined it. The special value END (0xFFFFFFFF) indicates
// the end of an array of spans.
ResStringPool_ref name;
// The range of characters in the string that this span applies to.
uint32_t firstChar, lastChar;
};
/** ********************************************************************
* XML Tree
*
* Binary representation of an XML document. This is designed to
* express everything in an XML document, in a form that is much
* easier to parse on the device.
*
*********************************************************************** */
/**
* XML tree header. This appears at the front of an XML tree,
* describing its content. It is followed by a flat array of
* ResXMLTree_node structures; the hierarchy of the XML document
* is described by the occurrance of RES_XML_START_ELEMENT_TYPE
* and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
*/
struct ResXMLTree_header
{
struct ResChunk_header header;
};
/**
* Basic XML tree node. A single item in the XML document. Extended info
* about the node can be found after header.headerSize.
*/
struct ResXMLTree_node
{
struct ResChunk_header header;
// Line number in original source file at which this element appeared.
uint32_t lineNumber;
// Optional XML comment that was associated with this element; -1 if none.
struct ResStringPool_ref comment;
};
/**
* Extended XML tree node for CDATA tags -- includes the CDATA string.
* Appears header.headerSize bytes after a ResXMLTree_node.
*/
struct ResXMLTree_cdataExt
{
// The raw CDATA character data.
struct ResStringPool_ref data;
// The typed value of the character data if this is a CDATA node.
struct Res_value typedData;
};
/**
* Extended XML tree node for namespace start/end nodes.
* Appears header.headerSize bytes after a ResXMLTree_node.
*/
struct ResXMLTree_namespaceExt
{
// The prefix of the namespace.
struct ResStringPool_ref prefix;
// The URI of the namespace.
struct ResStringPool_ref uri;
};
/**
* Extended XML tree node for element start/end nodes.
* Appears header.headerSize bytes after a ResXMLTree_node.
*/
struct ResXMLTree_endElementExt
{
// String of the full namespace of this element.
struct ResStringPool_ref ns;
// String name of this node if it is an ELEMENT; the raw
// character data if this is a CDATA node.
struct ResStringPool_ref name;
};
/**
* Extended XML tree node for start tags -- includes attribute
* information.
* Appears header.headerSize bytes after a ResXMLTree_node.
*/
struct ResXMLTree_attrExt
{
// String of the full namespace of this element.
struct ResStringPool_ref ns;
// String name of this node if it is an ELEMENT; the raw
// character data if this is a CDATA node.
struct ResStringPool_ref name;
// Byte offset from the start of this structure where the attributes start.
uint16_t attributeStart;
// Size of the ResXMLTree_attribute structures that follow.
uint16_t attributeSize;
// Number of attributes associated with an ELEMENT. These are
// available as an array of ResXMLTree_attribute structures
// immediately following this node.
uint16_t attributeCount;
// Index (1-based) of the "id" attribute. 0 if none.
uint16_t idIndex;
// Index (1-based) of the "class" attribute. 0 if none.
uint16_t classIndex;
// Index (1-based) of the "style" attribute. 0 if none.
uint16_t styleIndex;
};
struct ResXMLTree_attribute
{
// Namespace of this attribute.
struct ResStringPool_ref ns;
// Name of this attribute.
struct ResStringPool_ref name;
// The original raw string value of this attribute.
struct ResStringPool_ref rawValue;
// Processesd typed value of this attribute.
struct Res_value typedValue;
};
/** ********************************************************************
* RESOURCE TABLE
*
*********************************************************************** */
/**
* Header for a resource table. Its data contains a series of
* additional chunks:
* * A ResStringPool_header containing all table values. This string pool
* contains all of the string values in the entire resource table (not
* the names of entries or type identifiers however).
* * One or more ResTable_package chunks.
*
* Specific entries within a resource table can be uniquely identified
* with a single integer as defined by the ResTable_ref structure.
*/
struct ResTable_header
{
struct ResChunk_header header;
// The number of ResTable_package structures.
uint32_t packageCount;
};
/**
* A collection of resource data types within a package. Followed by
* one or more ResTable_type and ResTable_typeSpec structures containing the
* entry values for each resource type.
*/
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.
char16_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;
};
/**
* A specification of the resources defined by a particular type.
*
* There should be one of these chunks for each resource type.
*
* This structure is followed by an array of integers providing the set of
* configuration change flags (ResTable_config::CONFIG_*) that have multiple
* resources for that configuration. In addition, the high bit is set if that
* resource has been made public.
*/
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
};
};
/**
* A collection of resource entries for a particular resource data
* type. Followed by an array of uint32_t defining the resource
* values, corresponding to the array of type strings in the
* ResTable_package::typeStrings string block. Each of these hold an
* index from entriesStart; a value of NO_ENTRY means that entry is
* not defined.
*
* There may be multiple of these chunks for a particular resource type,
* supply different configuration variations for the resource values of
* that type.
*
* It would be nice to have an additional ordered index of entries, so
* we can do a binary search if trying to find a resource by string name.
*/
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;
};
/**
* This is the beginning of information about an entry in the resource
* table. It holds the reference to the name of this entry, and is
* immediately followed by one of:
* * A Res_value structure, if FLAG_COMPLEX is -not- set.
* * An array of ResTable_map structures, if FLAG_COMPLEX is set.
* These supply a set of name/value mappings of data.
*/
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;
};
/**
* Extended form of a ResTable_entry for map entries, defining a parent map
* resource from which to inherit values.
*/
struct ResTable_map_entry : public ResTable_entry
{
// Resource identifier of the parent mapping, or 0 if there is none.
ResTable_ref parent;
// Number of name/value pairs that follow for FLAG_COMPLEX.
uint32_t count;
};
/**
* A single name/value mapping that is part of a complex resource
* entry.
*/
struct ResTable_map
{
// The resource identifier defining this mapping's name. For attribute
// resources, 'name' can be one of the following special resource types
// to supply meta-data about the attribute; for all other resource types
// it must be an attribute resource.
ResTable_ref name;
// Special values for 'name' when defining attribute resources.
enum {
// This entry holds the attribute's type code.
ATTR_TYPE = Res_MAKEINTERNAL(0),
// For integral attributes, this is the minimum value it can hold.
ATTR_MIN = Res_MAKEINTERNAL(1),
// For integral attributes, this is the maximum value it can hold.
ATTR_MAX = Res_MAKEINTERNAL(2),
// Localization of this resource is can be encouraged or required with
// an aapt flag if this is set
ATTR_L10N = Res_MAKEINTERNAL(3),
// for plural support, see android.content.res.PluralRules#attrForQuantity(int)
ATTR_OTHER = Res_MAKEINTERNAL(4),
ATTR_ZERO = Res_MAKEINTERNAL(5),
ATTR_ONE = Res_MAKEINTERNAL(6),
ATTR_TWO = Res_MAKEINTERNAL(7),
ATTR_FEW = Res_MAKEINTERNAL(8),
ATTR_MANY = Res_MAKEINTERNAL(9)
};
// Bit mask of allowed types, for use with ATTR_TYPE.
enum {
// No type has been defined for this attribute, use generic
// type handling. The low 16 bits are for types that can be
// handled generically; the upper 16 require additional information
// in the bag so can not be handled generically for TYPE_ANY.
TYPE_ANY = 0x0000FFFF,
// Attribute holds a references to another resource.
TYPE_REFERENCE = 1<<0,
// Attribute holds a generic string.
TYPE_STRING = 1<<1,
// Attribute holds an integer value. ATTR_MIN and ATTR_MIN can
// optionally specify a constrained range of possible integer values.
TYPE_INTEGER = 1<<2,
// Attribute holds a boolean integer.
TYPE_BOOLEAN = 1<<3,
// Attribute holds a color value.
TYPE_COLOR = 1<<4,
// Attribute holds a floating point value.
TYPE_FLOAT = 1<<5,
// Attribute holds a dimension value, such as "20px".
TYPE_DIMENSION = 1<<6,
// Attribute holds a fraction value, such as "20%".
TYPE_FRACTION = 1<<7,
// Attribute holds an enumeration. The enumeration values are
// supplied as additional entries in the map.
TYPE_ENUM = 1<<16,
// Attribute holds a bitmaks of flags. The flag bit values are
// supplied as additional entries in the map.
TYPE_FLAGS = 1<<17
};
// Enum of localization modes, for use with ATTR_L10N.
enum {
L10N_NOT_REQUIRED = 0,
L10N_SUGGESTED = 1
};
// This mapping's value.
Res_value value;
};
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)