Dex文件内的数据类型


dex文件使用到的数据类型

类型

含义

u1

等同于uint8_t,表示1字节的无符号数

u2

等同于uint16_t,表示2字节的无符号数

u4

等同于uint32_t,表示4字节的无符号数

u8

等同于uint64_t,表示8字节的无符号数

sleb128

有符号LEB128,可变长度1~5字节

uleb128

无符号LEB128,可变长度1~5字节

uleb128p1

无符号LEB128值加1,可变长度1~5字节


dex文件结构

dex header

string_ids

type_ids

proto_ids

field_ids

method_ids

class_def

data

link_data



struct DexFile {
	DexHeader		Header;
	DexStringId		StringIds[stringIdsSize];
	DexTypeId		TypeIds[typeIdsSize];
	DexProtoId		ProtoIds[protoIdsSize];
	DexFieldId		FieldIds[fieldIdsSize];
	DexMethodId		MethodIds[methodIdsSize];
	DexClassDef		ClassDefs[classDefsSize];
	DexData			Data[];
	DexLink			LinkData;
}


struct DexHeader{
	u1			        magic[8];				//dex版本标识
	u4				checksum;				//adler32检验									u1				signature[kSHA1DIgestLen];	        //SHA-1 哈希值
	u4				fileSize;					//整个文件大小
	u4				headerSize;				//DexHeader结构大小
	u4				endianTag;				//字节序标记
	u4				linkSize;					//链接段大小
	u4				linkOff;					//链接段偏移
	u4				mapOff;					//DexMapList的文件偏移
	u4				stringIdsSize;				//DexStringId的个数
	u4				stringIdsOff;				//DexStringId的文件偏移
	u4				typeIdsSize;				//DexTypeId的个数
	u4				typeIdsOff;				//DexTypeId文件的偏移
	u4				protoIdsSize;				//DexProtoId的个数
	u4				protoIdsOff;				//DexProtoId文件的偏移
	u4				fieldIdsSize;				//DexFieldId的个数
	u4				fieldIdsOff;				//DexFieldId文件的偏移
	u4				methodIdsSize;				//DexMethodId的个数
	u4				methodIdsOff;				//DexMethodId文件的偏移
	u4				classDefsSize;				//DexClassDef的个数
	u4				classDefsOff;				//DexClassDef文件的偏移
	u4				dataSize;					//数据段的大小
	u4				dataOff;					//数据段的文件偏移
}


struct DexMapList{
	u4				size;						//DexMapItem的个数
	DexMapItem 		        list[1];					//DexMapItem结构
}


struct DexMapItem{
	u2				type;						//kDexType开头的类型
	u2				unused;					//未使用 用于字节对齐
	u4				size;						//指定类型的个数
	u4				offset;					//指定类型数据的文件偏移
}



type字段为一枚常量通过类型名称判断具体类型
enum{
kDexTypeHeaderItem              = 0x0000,
       kDexTypeStringIdItem             = 0x0001,
       kDexTypeTypeIdItem               = 0x0002,
       kDexTypeProtoIdItem              = 0x0003,
       kDexTypeFieldIdItem              = 0x0004,
       kDexTypeMethodIdItem             = 0x0005,
       kDexTypeClassDefItem             = 0x0006,
       kDexTypeMapList                  = 0x1000,
       kDexTypeTypeList                 = 0x1001,
       kDexTypeAnnotationSetRefList     = 0x1002,
       kDexTypeAnnotationSetItem        = 0x1003,
       kDexTypeClassDataItem            = 0x2000,
       kDexTypeCodeItem                 = 0x2001,
       kDexTypeStringDataItem           = 0x2002,
       kDexTypeDebugInfoItem                  = 0x2003,
       kDexTypeAnnotationItem           = 0x2004,
       kDexTypeEncodedArrayItem            = 0x2005,
       kDexTypeAnnotationsDirectoryItem = 0x2006,
}


struct DexStringId{
	u4 				stringDataOff;			       //字符串数据的偏移
}


struct	 DexTypeId{
	u4				descriptorIdx;				//指向DexStringId列表的索引
}



struct DexProtoId{
	u4				shortIdx;					//指向DexStringId列表的索引
	u4				returnTypeIdx;				//指向DexTypeId列表的索引
	u4				parametersOff;			//指向DexTypeList的偏移
}


struct DexTypeList{
	u4				Size;						//DexTypeItem的个数
	DexTypeItem 		list[1];					//DexTypeItem结构
}


struct DexTypeItem{
	u2				typeIdx;					//指向DexTypeId列表的索引
}



struct DexFieldId{
	u2				classIdx;					//类的类型 指向DexTypeId列表的索引
	u2				typeIdx;					//字段类型 指向DexTypeId列表的索引
	u4				nameIdx;					//字段名   指向DexStringId列表的索引
}



struct DexMethodId{
	u2			         classIdx;					//类的类型 指向DexTypeId列表的索引
	u2				protoIdx;					//声明类型  指向DexProtoId列表的索引
	u4				nameIdx;					//方法名   指向DexStringId列表的索引					
}


struct DexClassDef{
          u4  classIdx;           							//类的类型 指向DexTypeId列表的索引
         u4  accessFlags;           						//访问标识
         u4  superclassIdx;      		                            //父类类型 指向DexTypeId列表的索引
         u4  interfacesOff;                                                    //接口   指向DexTypeList的偏移
         u4  sourceFileIdx;                                                    //源文件名              
         u4  annotationsOff;                      		      //注解
         u4  classDataOff;       		             	   //指向DexClassDATA 结构的偏移
         u4  staticValuesOff; 	                                   //指向DexEncodeArray结构的偏移

}


struct DexClassData{
	DexClassDataHeader		header;			//指定字段与方法的个数
	DexField*					staticFields;		//静态字段 DexField结构
	DexField*					instanceFields;	//实例字段 DexField结构
	DexMethod* 				directMethods;	//直接方法 DexMethod结构
	DexMethod*				virtualMethods;	//虚方法  DexMethod结构
}



struct DexClassDataHeader{
	u4						staticFieldsSize;	//静态字段个数
	u4						instanceFieldsSize;	//实例字段个数
	u4						directMethodsSize;	//直接方法的个数
	u4						virtualMethodsSize; //虚方法的个数
}



struct DexField{
	u4						fieldIdx;			//指向DexFieldId的索引
	u4						accessFlags;		//访问标识
}



struct DexMethod{
	u4						methodIdx;		//指向DexMethodId的索引
	u4						accessFlags;		//访问标识
	u4						codeOff;			//指向DexCode结构的偏移
}



struct DexCode{
	u2						registersSize;		//使用寄存器的个数
	u2						inSize;			//参数个数
	u2						outsSize;			//调用其他方法时使用的寄存器个数
	u2						triesSize;			//tryCatch 个数
 	u4						debugInfoOff;		//指向调试信息的偏移
	u4						InsnsSize;			//指令集个数以2字节为单位
	u2						Insns[1];			//指令集
	
}



PS:参考书籍

你可能感兴趣的:(Android)