AndroidManifest.xml二进制文件格式分析
MindMac
2014/11/9
AndroidManifest.xml二进制文件格式分析byMindMac
1
AndroidManifest.xml文件的二进制格式没有公开文档,以下是根据AXMLPrinter2的源码
进行的分析,可能会存在错误!
最终的AndroidManifest.xml文件二进制格式如图1所示。
MagicNumber(0x00080003)4bytes
FileSize4bytes
StringChunk
ResourceIdChunk
XmlContentChunk
StringChunk
ChunkType(0x001C0001)4bytes
ChunkSize4bytes
StringCount4bytes
Unknown4bytes
StringPoolOffset4bytes
StylePoolOffset4bytes
StringOffsetsStringCount4bytes
StyleOffsetsStyleCount4bytes
StyleCount4bytes
StringPool
StylePool
ResourceIdChunk
ChunkType(0x00080180)4bytes
ChunkSize4bytes
ResourceIds(ChunkSize/4-2)4bytes
StartTagChunk
ChunkType(0x00100102)4bytes
ChunkSize4bytes
LineNumber4bytes
Unknown(0xFFFFFFFF)4bytes
NamespaceUri4bytes
Name4bytes
Flags(0x00140014)4bytes
AttributeCount4bytes
ClassAttribute4bytes
AttributesAttributeCount54bytes
EndTagChunk
ChunkType(0x00100103)4bytes
ChunkSize4bytes
LineNumber4bytes
Unknown(0xFFFFFFFF)4bytes
NamespaceUri4bytes
Name4bytes
TextChunk
ChunkType(0x00100104)4bytes
ChunkSize4bytes
LineNumber4bytes
Unknown(0xFFFFFFFF)4bytes
Name4bytes
Unknown4bytes
Unknown4bytes
BinaryAndroidManifest.xml
XmlContentChunkcancontain5kindsofchunks:StartNamespaceChunk,EndNamespaceChunk,StartTagChunk,EndTagChunkandTextChunk
StartNamespaceChunk
ChunkType(0x00100100)4bytes
ChunkSize4bytes
LineNumber4bytes
Unknown(0xFFFFFFFF)4bytes
Prefix4bytes
Uri4bytes
EndNamespaceChunk
ChunkType(0x00100101)4bytes
ChunkSize4bytes
LineNumber4bytes
Unknown(0xFFFFFFFF)4bytes
Prefix4bytes
Uri4bytes
BinaryAndroidManifest.xmlFormatByMindMac
图1AndroidManifest.xml二进制文件格式
下面根据一个实际的AndroidManifest文件进行对应的分析,编码前的文件内容如图2
图2编码前的AndroidManifest.xml文件内容
AndroidManifest.xml二进制文件格式分析byMindMac
2
所示,注意行号值,行号信息会反映在二进制文件内容中。
图3AndroidManifest二进制内容
根据图1中的文件格式对照图3可以发现二进制XML文件魔数为0x00080003,该文
件大小为0x00000704,即1796bytes;从0x00000008开始为StringChunk的内容,首先是
StringChunk的标识,值为0x001C0001,StringChunk的大小为0x000003A8,即936bytes,
所以这部分内容区间为0x00000008-0x000003AF。0x00000010开始的4个字节内容为字符
串的个数,因此本文件中字符个数为0x0000001B,即一共有27个字符串,这些字符串存放
在相对于StringChunk开头偏移量为0x00000088(0x0000001C处的4个字节内容)的地方,即
0x00000008+0x0000000088=0x00000090。0x00000014开始处的4个字节内容为Style个数,
至于Style为何物,因为找了很多APK,发现该处的值始终为0x00000000,也就是没有Style
内容,所以暂时无法确定Style具体意思。0x00000018开始处的4个字节内容始终为0x000000
00,具体含义不确定。0x00000020开始处的4字节内容为Style内容相对于StringChunk开
头位置的偏移量,因为Style个数为0,所以此处的值为0x00000000。从0x00000024位置
开始,后面连续跟着27个字符串的偏移量(相对于字符串内容的起始位置,在本次分析的
AndroidManifest中即为0x00000090),第一个字符串偏移量当然为0了,第二个字符串开始
位置为0x00000090+0x0000001A=0x000000AA。
图4AndroidManifest字符串以及Style
图5字符串内容格式
图5为AndroidManifest中字符串的内容格式,开始2个字节内容为字符串长度,该长
度指的是字符串中字符个数,而非字节数,因此此处字符串字符个数为0x0000000B,即11
个,接着开始的是字符串的内容,每个字符对应两个字节,因为是11个字符,因此一共有
22个字节,值为versionCode,在字符串末尾还有两个字节为字符串终止符,即0x0000。根
据此规则,27个字符串的内容如表1所示,其中第12个字符串内容为空,在分析时需要
注意。因为本文分析的AndroidManifest没有Style内容,所以StringPool结束后会进入Resource
ID内容。
所谓的ResourceID,即对应Android源码中/frameworks/base/core/res/res/values/public.xml
文件中每行的id值,如图6所示。图7为ResourceIdChunk的内容,开始处的4个字节内
AndroidManifest.xml二进制文件格式分析byMindMac
3
表127个字符串内容
编号字符串内容
0versionCode
1versionName
2minSdkVersion
3targetSdkVersion
4name
5allowBackup
6icon
7label
8theme
9android
10http://schemas.android.com/apk/res/android
11空字符串
12package
13manifest
14com.android.test
151.0
16uses-sdk
17uses-permission
18android.permission.INTERNET
19application
20activity
21com.android.test.MainActivity
22intent-filter
23action
24android.intent.action.MAIN
25category
26android.intent.category.LAUNCHER
图6public.xml文件部分内容
AndroidManifest.xml二进制文件格式分析byMindMac
4
图7ResourceIdChunk
容为0x00080180,即为ResourcdIdChunk的标识,接着的4个字节为本Chunk的大小,此处
为0x0000002C,即为44bytes,每个ResouceId值为4个字节,除去开头固定的8个字节,
因此本AndroidManifest一共有(44-42)/4=9个ResourceId。0x00003B08开始的4个字节内
容0x0101021B即为ResourceId值,根据public.xml文件内容,可知其对应值如下,但是在
分析AXMLPrinter2的源码过程中发现ResourceId的值貌似没有使用到,ResourceId对应的
name在StringPool中有直接对应的值。
1.
接下来即为XMLContent的内容,此部分一共有5中类型的Chunk,分别为Start
NamespaceChunk(0x00100100),EndNamespaceChunk(0x00100101),StartTag
Chunk(0x00100102),EndTagChunk(0x00100103)以及TextChunk(0x00100104)。这5种Chunk
的开头4个属性(16bytes)的含义都是一样的,分别表示Chunk类型标识、ChunkSize,行号(对
应编码前原文件内容的行号)、固定值0xFFFFFFFF。
ResourceIdChunk结束后,首先是StartNamespaceChunk,类型标识为0x00100100;大
小为0x00000018,即24bytes;行号为0x00000002,对应编码前文件的第2行内容,即
其表示StringPool中的字符串索引值,即android;Uri值为0x0000000A,其同样为StringPool
中的字符串索引值,即http://schemas.android.com/apk/res/android,Prefix与Uri在此处是对
应关系,后续的StartChunkType中的Attribute会根据Uri来获得Prefix值。
图8StartNamespaceChunk
StartTagChunk的标识为0x00100102;0x00000060为ChunkSize,即96bytes,因此其
区间为0x000003F4-0x00000453;0x00000404处的4字节内容为0xFFFFFFFF为命名空间的
Uri,即为-1,根据AXMLPrinter2的源码当为-1时,返回值为null,命名空间为空;接下来的
4个字节内容为该Tag的名称的字符串索引值0x0000000D,因此值为manifest;0x00000410
开始处的4个字节内容为XML标签下的属性个数,此处值为0x00000003,即一共3个属性,
图9StartTagChunk
AndroidManifest.xml二进制文件格式分析byMindMac
5
正好对应原文件内容中的pacakge,android:versionCode,android:versionName3个属性。每个
属性由54bytes构成,实际上就是一个长度为5的数组,数组中每个值的含义为[Namespace
Uri,Name,ValueString,Type,Data],继续以图9来分析。第一个属性的数组内容为[0x0000000A,
0x00000000,0xFFFFFFFF,0x10000008,0x00000001],而数组第4个值在实际处理过程中会首
先右移24位(0x10000008>>>24),因此数组值实际为[10,0,-1,16,1],第1个值为命名空间的
Uri,前面在StartNamespaceChunk中已经对应了Prefix和Uri,因此Uri为10即对应到值为
9的Prefix,字符串内容为android;第2个值为属性名称的字符串索引,因此值为versionCode;
第3个值在当Type为表示字符串时与Data值相同;第4个值表示数据的类型,包括String、
Attribute、Reference、Float、IntHex、IntBoolean、Int等(具体可以参考AXMLPrinter2的源码
test/AXMLPrinter类中的getAttributeValue函数),由于此处Type值为16,表示是个整数值;
第5个值即为属性的内容,由于Type指示为整数值,因此属性内容即为整数1。综上,第
一个属性解码后应为:android:VersionCode=”1”。
其他几个Chunk比较简单,可以自行分析。
|
|