[转]Dex 文件格式详解

Dex 文件格式详解

2141人阅读 评论(1) 收藏 举报
分类:
  • 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 字节

sleb128、uleb128、uleb128p1:
  • 小端结尾的,第一个字节代表的是整形值的最低 7 比特位的值,第二个字节代表次低 7 位,以此类推。所以代码中每发现要多用一个字节,都要多向左移动 7 位
  • sleb128 需要进行符号位扩展,先左移到最左边,再算术右移同样的位数实现
  • uleb128p1 是将其当做 uleb128 编码的值进行解码,然后再减一。解码时要减一,那么反过来编码时就要加一

  • DEX 文件整体结构

结构体表示:

  1. struct DexFile  
  2. {  
  3.     DexHeader           Header;  
  4.     DexStringId          StringIds[stringIdsSize];  
  5.     DexTypeId           TypeIds[typeIdsSize];  
  6.     DexProtoId           ProtoIds[protoIdsSize];  
  7.     DexFieldId            FieldIds[fieldIdsSize];  
  8.     DexMethodId       MethodIds[methodIdsSize];  
  9.     DexClassDef         ClassDefs[classDefsSize];  
  10.     DexData                Data[];  
  11.     DexLink                 LinkData;  
  12. };  
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;
};

  • DexHeader
DexHeader 结构的数据分为 “索引结构区” 和 “数据区”,“索引结构区” 中各数据结构的偏移地址都是从 DexHeader 结构的 stringIdsOff~classDefsOff 字段的值指定的,它们并非真正的类数据,而是指向 DEX 文件的 data 数据区相对于 Dex 头的偏移或结构索引。

下面所说的偏移都是指相对于 Dex 头的偏移

结构体表示:
  1. typedef struct _DexHeader  
  2. {  
  3.     u1  magic[8];                       // dex 版本标识,"dex.035"  
  4.     u4  checksum;                       // adler32 检验  
  5.     u1  signature[kSHA1DigestLen];      // SHA-1 哈希值,20个字节  
  6.     u4  fileSize;                       // 整个 dex 文件大小  
  7.     u4  headerSize;                     // DexHeader 结构大小,0x70  
  8.     u4  endianTag;                      // 字节序标记,小端 "0x12345678",大端"0x78563412"  
  9.     u4  linkSize;                       // 链接段大小  
  10.     u4  linkOff;                        // 链接段偏移  
  11.     u4  mapOff;                         // DexMapList 的偏移  
  12.     u4  stringIdsSize;                  // DexStringId 的个数  
  13.     u4  stringIdsOff;                   // DexStringId 的偏移      字符串  
  14.     u4  typeIdsSize;                    // DexTypeId 的个数  
  15.     u4  typedeIdsOff;                   // DexTypeId 的偏移            类型  
  16.     u4  protoIdsSize;                   // DexProtoId 的个数  
  17.     u4  protoIdsOff;                    // DexProtoId 的偏移           声明  
  18.     u4  fieldIdsSize;                   // DexFieldId 的个数  
  19.     u4  fieldIdsOff;                    // DexFieldId 的偏移           字段  
  20.     u4  methodIdsSize;                  // DexMethodId 的个数  
  21.     u4  methodIdsOff;                   // DexMethodId 的偏移      方法  
  22.     u4  classDefsSize;                  // DexClassDef 的个数  
  23.     u4  classDefsOff;                   // DexClassDef 的偏移      类  
  24.     u4  dataSize;                       // 数据段的大小  
  25.     u4  dataOff;                        // 数据段的偏移  
  26. }DexHeader, *PDexHeader;  
typedef struct _DexHeader
{
	u1	magic[8];						// dex 版本标识,"dex.035"
	u4	checksum;						// adler32 检验
	u1	signature[kSHA1DigestLen];		// SHA-1 哈希值,20个字节
	u4	fileSize;						// 整个 dex 文件大小
	u4	headerSize;						// DexHeader 结构大小,0x70
	u4	endianTag;						// 字节序标记,小端 "0x12345678",大端"0x78563412"
	u4	linkSize;						// 链接段大小
	u4	linkOff;						// 链接段偏移
	u4	mapOff;							// DexMapList 的偏移
	u4	stringIdsSize;					// DexStringId 的个数
	u4	stringIdsOff;					// DexStringId 的偏移		字符串
	u4	typeIdsSize;					// DexTypeId 的个数
	u4	typedeIdsOff;					// 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;						// 数据段的偏移
}DexHeader, *PDexHeader;

magic  标识一个有效的 dex 文件,一般是 "dex.035"
checksum DEX 文件的校验和
signature 文件的哈希值,20个字节
fileSize 记录包括 DexHeader 在内的整个dex 文件的大小
headerSize 记录 DexHeader 结构本身占用的字节数,目前为 0x70
endianTag 指定 dex 运行环境的 CPU 字节序,小端:"0x12345678",大端:"0x78563412"
linkSize 表示链接段的大小,如果为 0 表示该 DEX 文件不是静态链接
linkOff 表示链接段距离 Dex 头的偏移,如果 linkSize 为 0,此值也为 0

  • mapOff 字段
指定 DexMapList 结构距离 Dex 头的偏移

DexMapList 结构体:
  1. struct     DexMapList  
  2. {  
  3.     u4     size;                                   // DexMapItem 的个数  
  4.     DexMapItem     list[1];               // DexMapItem 结构  
  5. };  
struct     DexMapList
{
	u4     size;                                   // DexMapItem 的个数
	DexMapItem     list[1];               // DexMapItem 结构
};
    • size:表示接下来有多少个 DexMapItem 
    • list:是一个 DexMapItem 结构体数组
DexMapItem 结构体:
  1. struct     DexMapItem  
  2. {  
  3.     u2     type;                    // kDexType 开头的类型  
  4.     u2     unused;               // 未使用,用于对齐  
  5.     u4     size;                     // 指定类型的个数  
  6.     u4     offset;                 // 指定类型数据的文件偏移  
  7. };  
struct     DexMapItem
{
	u2     type;                    // kDexType 开头的类型
	u2     unused;               // 未使用,用于对齐
	u4     size;                     // 指定类型的个数
	u4     offset;                 // 指定类型数据的文件偏移
};
    • type:一个枚举常量
      1. enum  
      2. {  
      3.     kDexTypeHeaderItem = 0x0000,    // 对应 DexHeader       
      4.     kDexTypeStringIdItem = 0x0001,  // 对应 stringIdsSize 与 stringIdsOff 字段       
      5.     kDexTypeTypeIdItem = 0x0002,    // 对应 typeIdsSize 与 typeIdsOff 字段       
      6.     kDexTypeProtoIdItem = 0x0003,   // 对应 protoIdsSize 与 protoIdsOff 字段       
      7.     kDexTypeFieldIdItem = 0x0004,   // 对应 fieldIdsSize 与 fieldIdsOff 字段       
      8.     kDexTypeMethodIdItem = 0x0005,  // 对应 methodIdsSize 与 methodIdsOff 字段       
      9.     kDexTypeClassDefItem = 0x0006,  // 对应 classDefsSize 与 classDefsOff 字段       
      10.     kDexTypeMapList = 0x1000,       
      11.     kDexTypeTypeList = 0x1001,       
      12.     kDexTypeAnnotationSetRefList = 0x1002,       
      13.     kDexTypeAnnotationSetItem = 0x1003,       
      14.     kDexTypeClassDataItem = 0x2000,       
      15.     kDexTypeCodeItem = 0x2001,       
      16.     kDexTypeStringDataItem = 0x2002,       
      17.     kDexTypeDebugInfoItem = 0x2003,       
      18.     kDexTypeAnnotationItem = 0x2004,      
      19.     kDexTypeEncodeArrayItem = 0x2005,      
      20.     kDexTypeAnnotationsDirectoryItem = 0x2006  
      21. };  
      enum
      {
      	kDexTypeHeaderItem = 0x0000,	// 对应 DexHeader     
      	kDexTypeStringIdItem = 0x0001,	// 对应 stringIdsSize 与 stringIdsOff 字段     
      	kDexTypeTypeIdItem = 0x0002,	// 对应 typeIdsSize 与 typeIdsOff 字段     
      	kDexTypeProtoIdItem = 0x0003,	// 对应 protoIdsSize 与 protoIdsOff 字段     
      	kDexTypeFieldIdItem = 0x0004,	// 对应 fieldIdsSize 与 fieldIdsOff 字段     
      	kDexTypeMethodIdItem = 0x0005,	// 对应 methodIdsSize 与 methodIdsOff 字段     
      	kDexTypeClassDefItem = 0x0006,	// 对应 classDefsSize 与 classDefsOff 字段     
      	kDexTypeMapList = 0x1000,     
      	kDexTypeTypeList = 0x1001,     
      	kDexTypeAnnotationSetRefList = 0x1002,     
      	kDexTypeAnnotationSetItem = 0x1003,     
      	kDexTypeClassDataItem = 0x2000,     
      	kDexTypeCodeItem = 0x2001,     
      	kDexTypeStringDataItem = 0x2002,     
      	kDexTypeDebugInfoItem = 0x2003,     
      	kDexTypeAnnotationItem = 0x2004,    
      	kDexTypeEncodeArrayItem = 0x2005,    
      	kDexTypeAnnotationsDirectoryItem = 0x2006
      };
    • size:指定类型的个数
    • offset:指定类型数据的偏移

  • DexStringId 结构体(stringIdsSize 与 stringIdsOff 字段) 
  1. typedef struct _DexStringId  
  2. {  
  3.     u4  stringDataOff;                  // 指向 MUTF-8 字符串的偏移  
  4. }DexStringId, *PDexStringId;  
typedef struct _DexStringId
{
	u4	stringDataOff;					// 指向 MUTF-8 字符串的偏移
}DexStringId, *PDexStringId;

MUTF-8 编码:
1) 使用 1~3 字节编码长度
2) 大于 16 位的 Unicode 编码 U+10000~U+10FFFF 使用 3 字节来编码
3) U+0000 采用 2 字节编码
4) 采用空字符 null 作为结尾
5) 第一个字节存放字节个数(不包含自已)

  • DexTypeId 结构体(typeIdsSize 与 typeIdsOff 字段)
是一个类型结构体
  1. typedef struct _DexTypeId  
  2. {  
  3.     u4     descriptorIdx;   // 指向 DexStringId 列表的索引  
  4. }DexTypeId, *PDexTypeId;  
typedef struct _DexTypeId
{
	u4     descriptorIdx;   // 指向 DexStringId 列表的索引
}DexTypeId, *PDexTypeId;
    • descriptorIdx:指向 DexStringId 列表的索引,它对应的字符串代表了具体类的类型

  • DexProtoId 结构体(protoIdsSize 与 protoIdsOff 字段)
是一个方法声明结构体,方法声明 = 返回类型 + 参数列表
  1. typedef struct _DexProtoId  
  2. {  
  3.     u4  shortyIdx;          // 方法声明字符串,指向 DexStringId 列表的索引  
  4.     u4  returnTypeIdx;      // 方法返回类型字符串,指向 DexStringId 列表的索引  
  5.     u4  parametersOff;      // 方法的参数列表,指向 DexTypeList 结构体的偏移  
  6. }DexProtoId, *PDexProtoId;  
typedef struct _DexProtoId
{
	u4	shortyIdx;			// 方法声明字符串,指向 DexStringId 列表的索引
	u4	returnTypeIdx;		// 方法返回类型字符串,指向 DexStringId 列表的索引
	u4	parametersOff;		// 方法的参数列表,指向 DexTypeList 结构体的偏移
}DexProtoId, *PDexProtoId;
    • shortyIdx:方法声明字符串,方法声明 = 返回类型 + 参数列表
    • returnTypeIdx:方法返回类型字符串
    • parametersOff:指向一个 DexTypeList 结构体,存放了方法的参数列表
DexTypeList 结构体:
  1. typedef struct _DexTypeList  
  2. {  
  3.     u4  size;               // 接下来 DexTypeItem 的个数  
  4.     DexTypeItem* list;      // DexTypeItem 结构  
  5. }DexTypeList, *PDexTypeList;  
typedef struct _DexTypeList
{
	u4	size;				// 接下来 DexTypeItem 的个数
	DexTypeItem* list;		// DexTypeItem 结构
}DexTypeList, *PDexTypeList;
    • size:接下来 DexTypeItem 的个数
    • list:是一个 DexTypeItem 结构体数组

DexTypeItem 结构体:
  1. typedef struct _DexTypeItem  
  2. {  
  3.     u2  typeIdx;            // 指向 DexTypeId 列表的索引  
  4. }DexTypeItem, *PDexTypeItem;  
typedef struct _DexTypeItem
{
	u2	typeIdx;			// 指向 DexTypeId 列表的索引
}DexTypeItem, *PDexTypeItem;
    • typeIdx:DexTypeId 列表的索引

  • DexFieldId 结构体(fieldIdsSize 与 fieldIdsOff 字段)
指明了字段所有的类、字段的类型以及字段名
  1. typedef struct _DexFieldId  
  2. {  
  3.     u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引  
  4.     u2  typeIdx;            // 字段的类型,指向 DexTypeId 列表的索引  
  5.     u4  nameIdx;            // 字段名,指向 DexStringId 列表的索引  
  6. }DexFieldId, *PDexFieldId;  
typedef struct _DexFieldId
{
	u2	classIdx;			// 类的类型,指向 DexTypeId 列表的索引
	u2	typeIdx;			// 字段的类型,指向 DexTypeId 列表的索引
	u4	nameIdx;			// 字段名,指向 DexStringId 列表的索引
}DexFieldId, *PDexFieldId;
    • classIdx:类的类型
    • typeIdx:字段的类型
    • nameIdx:字段名

  • DexMethodId 结构体(methodIdsSize 与 methodIdsOff 字段)
方法结构体
  1. typedef struct _DexMethodId  
  2. {  
  3.     u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引  
  4.     u2  protoIdx;           // 声明的类型,指向 DexProtoId 列表的索引  
  5.     u4  nameIdx;            // 方法名,指向 DexStringId 列表的索引  
  6. }DexMethodId, *PDexMethodId;  
typedef struct _DexMethodId
{
	u2	classIdx;			// 类的类型,指向 DexTypeId 列表的索引
	u2	protoIdx;			// 声明的类型,指向 DexProtoId 列表的索引
	u4	nameIdx;			// 方法名,指向 DexStringId 列表的索引
}DexMethodId, *PDexMethodId;
    • classIdx:类的类型
    • protoIdx:声明的类型
    • nameIdx:方法名

  • DexClassDef 结构体(classDefsSize 和 classDefsOff 字段)
类结构体
  1. typedef struct _DexClassDef  
  2. {  
  3.     u4     classIdx;                 // 类的类型,指向 DexTypeId 列表的索引  
  4.     u4     accessFlags;              // 访问标志  
  5.     u4     superclassIdx;            // 父类类型,指向 DexTypeId 列表的索引  
  6.     u4     interfacesOff;            // 接口,指向 DexTypeList 的偏移,否则为0  
  7.     u4     sourceFileIdx;            // 源文件名,指向 DexStringId 列表的索引  
  8.     u4     annotationsOff;           // 注解,指向 DexAnnotationsDirectoryItem 结构,或者为 0  
  9.     u4     classDataOff;             // 指向 DexClassData 结构的偏移,类的数据部分  
  10.     u4     staticValuesOff;          // 指向 DexEncodedArray 结构的偏移,记录了类中的静态数据,主要是静态方法  
  11. }DexClassDef, *PDexClassDef;  
typedef struct _DexClassDef
{
	u4     classIdx;                 // 类的类型,指向 DexTypeId 列表的索引
	u4     accessFlags;              // 访问标志
	u4     superclassIdx;            // 父类类型,指向 DexTypeId 列表的索引
	u4     interfacesOff;            // 接口,指向 DexTypeList 的偏移,否则为0
	u4     sourceFileIdx;            // 源文件名,指向 DexStringId 列表的索引
	u4     annotationsOff;           // 注解,指向 DexAnnotationsDirectoryItem 结构,或者为 0
	u4     classDataOff;             // 指向 DexClassData 结构的偏移,类的数据部分
	u4     staticValuesOff;          // 指向 DexEncodedArray 结构的偏移,记录了类中的静态数据,主要是静态方法
}DexClassDef, *PDexClassDef;
    • classIdx:类的类型,指向 DexTypeId 列表的索引
    • accessFlags:访问标志
    • superclassIdx:父类类型,指向 DexTypeId 列表的索引
    • interfacesOff:接口,指向 DexTypeList 的偏移,如果没有,则为 0
    • sourceFileIdx:源文件名,指向 DexStringId 列表的索引
    • annotationsOff:注解,指向 DexAnnotationsDirectoryItem 结构,或者为 0
    • classDataOff:指向 DexClassData 结构的偏移,类的数据部分
    • staticValuesOff:指向 DexEncodeArray 结构的偏移,记录了类中的静态数据,没有则为 0
DexClassData 结构体:
  1. typedef struct _DexClassData  
  2. {  
  3.     DexClassDataHeader      header;             // 指定字段与方法的个数  
  4.     DexField*               staticFields;       // 静态字段,DexField 结构  
  5.     DexField*               instanceFields;     // 实例字段,DexField 结构  
  6.     DexMethod*              directMethods;      // 直接方法,DexMethod 结构  
  7.     DexMethod*              virtualMethods;     // 虚方法,DexMethod 结构  
  8. }DexClassData, *PDexClassData;  
typedef struct _DexClassData
{
	DexClassDataHeader		header;				// 指定字段与方法的个数
	DexField*				staticFields;		// 静态字段,DexField 结构
	DexField*				instanceFields;		// 实例字段,DexField 结构
	DexMethod*				directMethods;		// 直接方法,DexMethod 结构
	DexMethod*				virtualMethods;		// 虚方法,DexMethod 结构
}DexClassData, *PDexClassData;
    • header:DexClassDataHeader 结构体,指定字段与方法的个数
    • staticFields:静态字段,DexField 结构体数组
    • instanceFields:实例字段,DexField 结构体数组
    • directMethods:直接方法,DexMthod 结构体数组
    • virtualMethods:虚方法,DexMethod 结构体数组
DexClassDataHeader 结构体:
  1. typedef struct _DexClassDataHeader  
  2. {  
  3.     uleb128 staticFieldsSize;                   // 静态字段个数  
  4.     uleb128 instanceFieldsSize;                 // 实例字段个数  
  5.     uleb128 directMethodsSize;                  // 直接方法个数  
  6.     uleb128 virtualMethodsSize;                 // 虚方法个数  
  7. }DexClassDataHeader, *PDexClassDataHeader;  
typedef struct _DexClassDataHeader
{
	uleb128	staticFieldsSize;					// 静态字段个数
	uleb128	instanceFieldsSize;					// 实例字段个数
	uleb128	directMethodsSize;					// 直接方法个数
	uleb128	virtualMethodsSize;					// 虚方法个数
}DexClassDataHeader, *PDexClassDataHeader;
    • staticFieldsSize:静态字段个数
    • instanceFieldsSize:实例字段个数
    • directMethodsSize:直接方法个数
    • virtualMethodsSize:虚方法个数
DexField 结构体:
  1. typedef struct _DexField  
  2. {  
  3.     uleb128 fieldIdx;           // 指向 DexFieldId 的索引  
  4.     uleb128 accessFlags;        // 访问标志  
  5. }DexField, *PDexField;  
typedef struct _DexField
{
	uleb128	fieldIdx;			// 指向 DexFieldId 的索引
	uleb128	accessFlags;		// 访问标志
}DexField, *PDexField;
    • fieldIdx:字段描述,指向 DexFieldId 的索引
    • accessFlags:访问标志
DexMethod 结构体:
  1. typedef struct _DexMethod  
  2. {  
  3.     uleb128 methodIdx;          // 指向 DexMethodId 的索引  
  4.     uleb128 accessFlags;        // 访问标志  
  5.     uleb128 codeOff;            // 指向 DexCode 结构的偏移  
  6. }DexMethod, *PDexMethod;  
typedef struct _DexMethod
{
	uleb128	methodIdx;			// 指向 DexMethodId 的索引
	uleb128	accessFlags;		// 访问标志
	uleb128	codeOff;			// 指向 DexCode 结构的偏移
}DexMethod, *PDexMethod;
    • methodIdx:方法描述,指向 DexMethodId 的索引
    • accessFlags:访问标志
    • codeOff:指向 DexCode 结构的偏移
DexCode 结构体:
  1. typedef struct _DexCode  
  2. {  
  3.     u2  registersSize;          // 使用的寄存器个数  
  4.     u2  insSize;                // 参数个数  
  5.     u2  outsSize;               // 调用其他方法时使用的寄存器个数  
  6.     u2  triesSize;              // Try/Catch 个数  
  7.     u4  debbugInfoOff;          // 指向调试信息的偏移  
  8.     u4  insnsSize;              // 指令集个数,以 2 字节为单位  
  9.     u2* insns;                  // 指令集  
  10. }DexCode, *PDexCode;  
typedef struct _DexCode
{
	u2	registersSize;			// 使用的寄存器个数
	u2	insSize;				// 参数个数
	u2	outsSize;				// 调用其他方法时使用的寄存器个数
	u2	triesSize;				// Try/Catch 个数
	u4	debbugInfoOff;			// 指向调试信息的偏移
	u4	insnsSize;				// 指令集个数,以 2 字节为单位
	u2*	insns;					// 指令集
}DexCode, *PDexCode;



还有一些不太常见的结构体,要用的时候再去看看就行了。Dex 文件的整体结构就这样,就是一个多层索引的结构。
为了熟悉 Dex 文件格式,写了一个程序去解析 Dex 文件里的类的信息,程序比较粗糙,学习为主

dex.h
  1. /* 
  2.  * Dex 文件中数据结构的声明 
  3.  */  
  4.   
  5. #pragma once  
  6. #include  <string>  
  7. typedef unsigned char uint8_t;  
  8. typedef unsigned short int uint16_t;  
  9. typedef unsigned int uint32_t;  
  10. typedef unsigned long long uint64_t;  
  11.   
  12. typedef uint8_t  u1;  
  13. typedef uint16_t u2;  
  14. typedef uint32_t u4;  
  15. typedef uint64_t u8;  
  16.   
  17. typedef unsigned int uleb128;  
  18. typedef unsigned int uleb128p1;  
  19. typedef int sleb128;  
  20.   
  21. #define kSHA1DigestLen  20  
  22.   
  23. enum {  
  24.     ACC_PUBLIC = 0x00000001,       // class, field, method, ic  
  25.     ACC_PRIVATE = 0x00000002,       // field, method, ic  
  26.     ACC_PROTECTED = 0x00000004,       // field, method, ic  
  27.     ACC_STATIC = 0x00000008,       // field, method, ic  
  28.     ACC_FINAL = 0x00000010,       // class, field, method, ic  
  29.     ACC_SYNCHRONIZED = 0x00000020,       // method (only allowed on natives)  
  30.     ACC_SUPER = 0x00000020,       // class (not used in Dalvik)  
  31.     ACC_VOLATILE = 0x00000040,       // field  
  32.     ACC_BRIDGE = 0x00000040,       // method (1.5)  
  33.     ACC_TRANSIENT = 0x00000080,       // field  
  34.     ACC_VARARGS = 0x00000080,       // method (1.5)  
  35.     ACC_NATIVE = 0x00000100,       // method  
  36.     ACC_INTERFACE = 0x00000200,       // class, ic  
  37.     ACC_ABSTRACT = 0x00000400,       // class, method, ic  
  38.     ACC_STRICT = 0x00000800,       // method  
  39.     ACC_SYNTHETIC = 0x00001000,       // field, method, ic  
  40.     ACC_ANNOTATION = 0x00002000,       // class, ic (1.5)  
  41.     ACC_ENUM = 0x00004000,       // class, field, ic (1.5)  
  42.     ACC_CONSTRUCTOR = 0x00010000,       // method (Dalvik only)  
  43.     ACC_DECLARED_SYNCHRONIZED =  
  44.     0x00020000,       // method (Dalvik only)  
  45.     ACC_CLASS_MASK =  
  46.     (ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT  
  47.     | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM),  
  48.     ACC_INNER_CLASS_MASK =  
  49.     (ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC),  
  50.     ACC_FIELD_MASK =  
  51.     (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL  
  52.     | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM),  
  53.     ACC_METHOD_MASK =  
  54.     (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL  
  55.     | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE  
  56.     | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR  
  57.     | ACC_DECLARED_SYNCHRONIZED),  
  58. };  
  59.   
  60.   
  61. /* 
  62.  * DexHeader 
  63.  */  
  64. typedef struct _DexHeader  
  65. {  
  66.     u1  magic[8];                       // dex 版本标识,"dex.035"  
  67.     u4  checksum;                       // adler32 检验  
  68.     u1  signature[kSHA1DigestLen];      // SHA-1 哈希值,20个字节  
  69.     u4  fileSize;                       // 整个 dex 文件大小  
  70.     u4  headerSize;                     // DexHeader 结构大小,0x70  
  71.     u4  endianTag;                      // 字节序标记,小端 "0x12345678",大端"0x78563412"  
  72.     u4  linkSize;                       // 链接段大小  
  73.     u4  linkOff;                        // 链接段偏移  
  74.     u4  mapOff;                         // DexMapList 的偏移  
  75.     u4  stringIdsSize;                  // DexStringId 的个数  
  76.     u4  stringIdsOff;                   // DexStringId 的偏移      字符串  
  77.     u4  typeIdsSize;                    // DexTypeId 的个数  
  78.     u4  typedeIdsOff;                   // DexTypeId 的偏移            类型  
  79.     u4  protoIdsSize;                   // DexProtoId 的个数  
  80.     u4  protoIdsOff;                    // DexProtoId 的偏移           声明  
  81.     u4  fieldIdsSize;                   // DexFieldId 的个数  
  82.     u4  fieldIdsOff;                    // DexFieldId 的偏移           字段  
  83.     u4  methodIdsSize;                  // DexMethodId 的个数  
  84.     u4  methodIdsOff;                   // DexMethodId 的偏移      方法  
  85.     u4  classDefsSize;                  // DexClassDef 的个数  
  86.     u4  classDefsOff;                   // DexClassDef 的偏移      类  
  87.     u4  dataSize;                       // 数据段的大小  
  88.     u4  dataOff;                        // 数据段的偏移  
  89. }DexHeader, *PDexHeader;  
  90.   
  91. /* 
  92.  * DexStringId 
  93.  */  
  94. typedef struct _DexStringId  
  95. {  
  96.     u4  stringDataOff;                  // 指向 MUTF-8 字符串的偏移  
  97. }DexStringId, *PDexStringId;  
  98.   
  99.   
  100. /* 
  101.  * DexTypeId 
  102.  */  
  103. typedef struct _DexTypeId  
  104. {  
  105.     u4     descriptorIdx;   // 指向 DexStringId 列表的索引  
  106. }DexTypeId, *PDexTypeId;  
  107.   
  108.   
  109. /* 
  110.  * DexProtoId 
  111.  */  
  112. typedef struct _DexProtoId  
  113. {  
  114.     u4  shortyIdx;          // 方法声明字符串,指向 DexStringId 列表的索引,方法声明 = 返回类型+参数列表  
  115.     u4  returnTypeIdx;      // 方法返回类型字符串,指向 DexStringId 列表的索引  
  116.     u4  parametersOff;      // 方法的参数列表,指向 DexTypeList 结构体的偏移  
  117. }DexProtoId, *PDexProtoId;  
  118.   
  119.   
  120. /* 
  121.  * DexFieldId 
  122.  */  
  123. typedef struct _DexFieldId  
  124. {  
  125.     u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引  
  126.     u2  typeIdx;            // 字段的类型,指向 DexTypeId 列表的索引  
  127.     u4  nameIdx;            // 字段名,指向 DexStringId 列表的索引  
  128. }DexFieldId, *PDexFieldId;  
  129.   
  130.   
  131. /* 
  132.  * DexMethodId 
  133.  */  
  134. typedef struct _DexMethodId  
  135. {  
  136.     u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引  
  137.     u2  protoIdx;           // 声明的类型,指向 DexProtoId 列表的索引  
  138.     u4  nameIdx;            // 方法名,指向 DexStringId 列表的索引  
  139. }DexMethodId, *PDexMethodId;  
  140.   
  141.   
  142. typedef struct _DexClassDataHeader  
  143. {  
  144.     uleb128 staticFieldsSize;                   // 静态字段个数  
  145.     uleb128 instanceFieldsSize;                 // 实例字段个数  
  146.     uleb128 directMethodsSize;                  // 直接方法个数  
  147.     uleb128 virtualMethodsSize;                 // 虚方法个数  
  148. }DexClassDataHeader, *PDexClassDataHeader;  
  149.   
  150. typedef struct _DexField  
  151. {  
  152.     uleb128 fieldIdx;           // 指向 DexFieldId 的索引  
  153.     uleb128 accessFlags;        // 访问标志  
  154. }DexField, *PDexField;  
  155.   
  156. typedef struct _DexMethod  
  157. {  
  158.     uleb128 methodIdx;          // 指向 DexMethodId 的索引  
  159.     uleb128 accessFlags;        // 访问标志  
  160.     uleb128 codeOff;            // 指向 DexCode 结构的偏移  
  161. }DexMethod, *PDexMethod;  
  162.   
  163.   
  164. /* 
  165. * DexCode 
  166. */  
  167. typedef struct _DexCode  
  168. {  
  169.     u2  registersSize;          // 使用的寄存器个数  
  170.     u2  insSize;                // 参数个数  
  171.     u2  outsSize;               // 调用其他方法时使用的寄存器个数  
  172.     u2  triesSize;              // Try/Catch 个数  
  173.     u4  debbugInfoOff;          // 指向调试信息的偏移  
  174.     u4  insnsSize;              // 指令集个数,以 2 字节为单位  
  175.     u2* insns;                  // 指令集  
  176. }DexCode, *PDexCode;  
  177.   
  178.   
  179. /* 
  180.  * DexClassDef 
  181.  */  
  182. typedef struct _DexClassDef  
  183. {  
  184.     u4     classIdx;                 // 类的类型,指向 DexTypeId 列表的索引  
  185.     u4     accessFlags;              // 访问标志  
  186.     u4     superclassIdx;            // 父类类型,指向 DexTypeId 列表的索引  
  187.     u4     interfacesOff;            // 接口,指向 DexTypeList 的偏移,否则为0  
  188.     u4     sourceFileIdx;            // 源文件名,指向 DexStringId 列表的索引  
  189.     u4     annotationsOff;           // 注解,指向 DexAnnotationsDirectoryItem 结构,或者为 0  
  190.     u4     classDataOff;             // 指向 DexClassData 结构的偏移,类的数据部分  
  191.     u4     staticValuesOff;          // 指向 DexEncodedArray 结构的偏移,记录了类中的静态数据  
  192. }DexClassDef, *PDexClassDef;  
  193.   
  194.   
  195. /* 
  196.  * DexClassData 
  197.  */  
  198. typedef struct _DexClassData  
  199. {  
  200.     DexClassDataHeader      header;             // 指定字段与方法的个数  
  201.     DexField*               staticFields;       // 静态字段,DexField 结构  
  202.     DexField*               instanceFields;     // 实例字段,DexField 结构  
  203.     DexMethod*              directMethods;      // 直接方法,DexMethod 结构  
  204.     DexMethod*              virtualMethods;     // 虚方法,DexMethod 结构  
  205. }DexClassData, *PDexClassData;  
  206.   
  207.   
  208.   
  209.   
  210.   
  211.   
  212. /* 
  213.  * DexData 
  214.  */  
  215. typedef struct _DexData  
  216. {  
  217.   
  218. }DexData, *PDexData;  
  219.   
  220.   
  221. /* 
  222.  * DexLink 
  223.  */  
  224. typedef struct _DexLink  
  225. {  
  226.   
  227. }DexLink, *PDexLink;  
  228.   
  229. /* 
  230. * DexTypeItem 
  231. */  
  232. typedef struct _DexTypeItem  
  233. {  
  234.     u2  typeIdx;            // 指向 DexTypeId 列表的索引  
  235. }DexTypeItem, *PDexTypeItem;  
  236.   
  237.   
  238. /* 
  239. * DexTypeList 
  240. */  
  241. typedef struct _DexTypeList  
  242. {  
  243.     u4  size;               // 接下来 DexTypeItem 的个数  
  244.     DexTypeItem* list;      // DexTypeItem 结构  
  245. }DexTypeList, *PDexTypeList;  
  246.   
  247.   
  248. /* 
  249.  * DexFile 
  250.  */  
  251. class DexFile  
  252. {  
  253.     // Dex 文件结构  
  254. private:  
  255.     PDexHeader      dexHeader;          // dex 头  
  256.     PDexStringId    stringIds;          // 字符串  
  257.     PDexTypeId      typeIds;            // 类型  
  258.     PDexProtoId     protoIds;           // 声明  
  259.     PDexFieldId     fieldIds;           // 字段  
  260.     PDexMethodId    methodIds;          // 方法  
  261.     PDexClassDef    classDefs;          // 类  
  262.     PDexData        data;               // 数据  
  263.     PDexLink        linkData;           // 静态链接数据区,对于未优化的 Dex 文件始终为空  
  264.   
  265. public:  
  266.     DexFile(char* file);  
  267.   
  268.     void parseAllClass();  
  269. private:  
  270.     std::string parseStringId(u4 index);  
  271.     std::string parseTypeId(u4 index);  
  272.     std::string parseProtoId(u4 index);  
  273.     std::string parseFieldId(u4 index);  
  274.     std::string parseMethodId(u4 index);  
  275.     std::string parseClassDef(u4 index);  
  276.   
  277.     std::string parseDataTypeList(PDexTypeList);  
  278.     std::string parseClassData(PDexClassData);  
  279. private:  
  280.     /* 
  281.      * MUTF8 转换成 ASCII 
  282.      */  
  283.     inline char* MUTF8ToASCII(char *stream)  
  284.     {  
  285.         char* ptr = stream + 1;  
  286.         return ptr;  
  287.     }  
  288.   
  289.     /* 
  290.      * int to string 
  291.      */  
  292.     std::string IntToString(int num);  
  293.     int uleb128ToInt(u1**);  
  294.     int sleb128ToInt(u1**);  
  295. };  
/*
 * Dex 文件中数据结构的声明
 */

#pragma once
#include  <string>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;

typedef uint8_t	 u1;
typedef uint16_t u2;
typedef uint32_t u4;
typedef uint64_t u8;

typedef unsigned int uleb128;
typedef unsigned int uleb128p1;
typedef int sleb128;

#define kSHA1DigestLen	20

enum {
	ACC_PUBLIC = 0x00000001,       // class, field, method, ic
	ACC_PRIVATE = 0x00000002,       // field, method, ic
	ACC_PROTECTED = 0x00000004,       // field, method, ic
	ACC_STATIC = 0x00000008,       // field, method, ic
	ACC_FINAL = 0x00000010,       // class, field, method, ic
	ACC_SYNCHRONIZED = 0x00000020,       // method (only allowed on natives)
	ACC_SUPER = 0x00000020,       // class (not used in Dalvik)
	ACC_VOLATILE = 0x00000040,       // field
	ACC_BRIDGE = 0x00000040,       // method (1.5)
	ACC_TRANSIENT = 0x00000080,       // field
	ACC_VARARGS = 0x00000080,       // method (1.5)
	ACC_NATIVE = 0x00000100,       // method
	ACC_INTERFACE = 0x00000200,       // class, ic
	ACC_ABSTRACT = 0x00000400,       // class, method, ic
	ACC_STRICT = 0x00000800,       // method
	ACC_SYNTHETIC = 0x00001000,       // field, method, ic
	ACC_ANNOTATION = 0x00002000,       // class, ic (1.5)
	ACC_ENUM = 0x00004000,       // class, field, ic (1.5)
	ACC_CONSTRUCTOR = 0x00010000,       // method (Dalvik only)
	ACC_DECLARED_SYNCHRONIZED =
	0x00020000,       // method (Dalvik only)
	ACC_CLASS_MASK =
	(ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT
	| ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM),
	ACC_INNER_CLASS_MASK =
	(ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC),
	ACC_FIELD_MASK =
	(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
	| ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM),
	ACC_METHOD_MASK =
	(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
	| ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE
	| ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR
	| ACC_DECLARED_SYNCHRONIZED),
};


/*
 * DexHeader
 */
typedef struct _DexHeader
{
	u1	magic[8];						// dex 版本标识,"dex.035"
	u4	checksum;						// adler32 检验
	u1	signature[kSHA1DigestLen];		// SHA-1 哈希值,20个字节
	u4	fileSize;						// 整个 dex 文件大小
	u4	headerSize;						// DexHeader 结构大小,0x70
	u4	endianTag;						// 字节序标记,小端 "0x12345678",大端"0x78563412"
	u4	linkSize;						// 链接段大小
	u4	linkOff;						// 链接段偏移
	u4	mapOff;							// DexMapList 的偏移
	u4	stringIdsSize;					// DexStringId 的个数
	u4	stringIdsOff;					// DexStringId 的偏移		字符串
	u4	typeIdsSize;					// DexTypeId 的个数
	u4	typedeIdsOff;					// 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;						// 数据段的偏移
}DexHeader, *PDexHeader;

/*
 * DexStringId
 */
typedef struct _DexStringId
{
	u4	stringDataOff;					// 指向 MUTF-8 字符串的偏移
}DexStringId, *PDexStringId;


/*
 * DexTypeId
 */
typedef struct _DexTypeId
{
	u4     descriptorIdx;   // 指向 DexStringId 列表的索引
}DexTypeId, *PDexTypeId;


/*
 * DexProtoId
 */
typedef struct _DexProtoId
{
	u4	shortyIdx;			// 方法声明字符串,指向 DexStringId 列表的索引,方法声明 = 返回类型+参数列表
	u4	returnTypeIdx;		// 方法返回类型字符串,指向 DexStringId 列表的索引
	u4	parametersOff;		// 方法的参数列表,指向 DexTypeList 结构体的偏移
}DexProtoId, *PDexProtoId;


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


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


typedef struct _DexClassDataHeader
{
	uleb128	staticFieldsSize;					// 静态字段个数
	uleb128	instanceFieldsSize;					// 实例字段个数
	uleb128	directMethodsSize;					// 直接方法个数
	uleb128	virtualMethodsSize;					// 虚方法个数
}DexClassDataHeader, *PDexClassDataHeader;

typedef struct _DexField
{
	uleb128	fieldIdx;			// 指向 DexFieldId 的索引
	uleb128	accessFlags;		// 访问标志
}DexField, *PDexField;

typedef struct _DexMethod
{
	uleb128	methodIdx;			// 指向 DexMethodId 的索引
	uleb128	accessFlags;		// 访问标志
	uleb128	codeOff;			// 指向 DexCode 结构的偏移
}DexMethod, *PDexMethod;


/*
* DexCode
*/
typedef struct _DexCode
{
	u2	registersSize;			// 使用的寄存器个数
	u2	insSize;				// 参数个数
	u2	outsSize;				// 调用其他方法时使用的寄存器个数
	u2	triesSize;				// Try/Catch 个数
	u4	debbugInfoOff;			// 指向调试信息的偏移
	u4	insnsSize;				// 指令集个数,以 2 字节为单位
	u2*	insns;					// 指令集
}DexCode, *PDexCode;


/*
 * DexClassDef
 */
typedef struct _DexClassDef
{
	u4     classIdx;                 // 类的类型,指向 DexTypeId 列表的索引
	u4     accessFlags;              // 访问标志
	u4     superclassIdx;            // 父类类型,指向 DexTypeId 列表的索引
	u4     interfacesOff;            // 接口,指向 DexTypeList 的偏移,否则为0
	u4     sourceFileIdx;            // 源文件名,指向 DexStringId 列表的索引
	u4     annotationsOff;           // 注解,指向 DexAnnotationsDirectoryItem 结构,或者为 0
	u4     classDataOff;             // 指向 DexClassData 结构的偏移,类的数据部分
	u4     staticValuesOff;          // 指向 DexEncodedArray 结构的偏移,记录了类中的静态数据
}DexClassDef, *PDexClassDef;


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






/*
 * DexData
 */
typedef struct _DexData
{

}DexData, *PDexData;


/*
 * DexLink
 */
typedef struct _DexLink
{

}DexLink, *PDexLink;

/*
* DexTypeItem
*/
typedef struct _DexTypeItem
{
	u2	typeIdx;			// 指向 DexTypeId 列表的索引
}DexTypeItem, *PDexTypeItem;


/*
* DexTypeList
*/
typedef struct _DexTypeList
{
	u4	size;				// 接下来 DexTypeItem 的个数
	DexTypeItem* list;		// DexTypeItem 结构
}DexTypeList, *PDexTypeList;


/*
 * DexFile
 */
class DexFile
{
	// Dex 文件结构
private:
	PDexHeader		dexHeader;			// dex 头
	PDexStringId	stringIds;			// 字符串
	PDexTypeId		typeIds;			// 类型
	PDexProtoId		protoIds;			// 声明
	PDexFieldId		fieldIds;			// 字段
	PDexMethodId	methodIds;			// 方法
	PDexClassDef	classDefs;			// 类
	PDexData		data;				// 数据
	PDexLink		linkData;			// 静态链接数据区,对于未优化的 Dex 文件始终为空

public:
	DexFile(char* file);

	void parseAllClass();
private:
	std::string parseStringId(u4 index);
	std::string parseTypeId(u4 index);
	std::string parseProtoId(u4 index);
	std::string parseFieldId(u4 index);
	std::string parseMethodId(u4 index);
	std::string parseClassDef(u4 index);

	std::string parseDataTypeList(PDexTypeList);
	std::string parseClassData(PDexClassData);
private:
	/*
	 * MUTF8 转换成 ASCII
	 */
	inline char* MUTF8ToASCII(char *stream)
	{
		char* ptr = stream + 1;
		return ptr;
	}

	/*
	 * int to string
	 */
	std::string IntToString(int num);
	int uleb128ToInt(u1**);
	int sleb128ToInt(u1**);
};


dex.cpp
  1. /* 
  2.  * 解析 Dex 文件 
  3.  */  
  4.   
  5. #include "dex.h"  
  6. #include <sstream>  
  7. #include <string>  
  8. #include <iostream>  
  9.   
  10. void DexFile::parseAllClass()  
  11. {  
  12.     for (u4 i = 0; i < dexHeader->classDefsSize; ++i)  
  13.     {  
  14.         std::cout << parseClassDef(i) << std::endl;  
  15.         std::cout << std::endl;  
  16.     }  
  17. }  
  18.   
  19. DexFile::DexFile(char* file)  
  20. {  
  21.     // dex 头  
  22.     dexHeader = reinterpret_cast<PDexHeader>(file);  
  23.     if (dexHeader == nullptr)  
  24.     {  
  25.         return;  
  26.     }  
  27.     else  
  28.     {  
  29.         // 字符串  
  30.         if (dexHeader->stringIdsOff != 0)  
  31.         {  
  32.             stringIds = reinterpret_cast<PDexStringId>((dexHeader->stringIdsOff) + reinterpret_cast<char*>(dexHeader));  
  33.         }  
  34.         else  
  35.         {  
  36.             stringIds = nullptr;  
  37.         }  
  38.   
  39.         // 类型  
  40.         if (dexHeader->typedeIdsOff == 0)  
  41.         {  
  42.             typeIds = nullptr;  
  43.         }  
  44.         else  
  45.         {  
  46.             typeIds = reinterpret_cast<PDexTypeId>((dexHeader->typedeIdsOff) + reinterpret_cast<char*>(dexHeader));  
  47.         }  
  48.   
  49.         // 声明  
  50.         if (dexHeader->protoIdsOff == 0)  
  51.         {  
  52.             protoIds = nullptr;  
  53.         }  
  54.         else  
  55.         {  
  56.             protoIds = reinterpret_cast<PDexProtoId>((dexHeader->protoIdsOff) + reinterpret_cast<char*>(dexHeader));  
  57.         }  
  58.   
  59.         // 字段  
  60.         if (dexHeader->fieldIdsOff == 0)  
  61.         {  
  62.             fieldIds = nullptr;  
  63.         }  
  64.         else  
  65.         {  
  66.             fieldIds = reinterpret_cast<PDexFieldId>((dexHeader->fieldIdsOff) + reinterpret_cast<char*>(dexHeader));  
  67.         }  
  68.   
  69.         // 方法  
  70.         if (dexHeader->methodIdsOff == 0)  
  71.         {  
  72.             methodIds = nullptr;  
  73.         }  
  74.         else  
  75.         {  
  76.             methodIds = reinterpret_cast<PDexMethodId>((dexHeader->methodIdsOff) + reinterpret_cast<char*>(dexHeader));  
  77.         }  
  78.   
  79.         // 类  
  80.         if (dexHeader->classDefsOff == 0)  
  81.         {  
  82.             classDefs = nullptr;  
  83.         }  
  84.         else  
  85.         {  
  86.             classDefs = reinterpret_cast<PDexClassDef>((dexHeader->classDefsOff) + reinterpret_cast<char*>(dexHeader));  
  87.         }  
  88.   
  89.         // 数据  
  90.         if (dexHeader->dataOff == 0)  
  91.         {  
  92.             data = nullptr;  
  93.         }  
  94.         else  
  95.         {  
  96.             data = reinterpret_cast<PDexData>((dexHeader->dataOff) + reinterpret_cast<char*>(dexHeader));  
  97.         }  
  98.   
  99.         // 静态链接数据区  
  100.         if (dexHeader->linkOff == 0)  
  101.         {  
  102.             linkData = nullptr;  
  103.         }  
  104.         else  
  105.         {  
  106.             linkData = reinterpret_cast<PDexLink>((dexHeader->linkOff) + reinterpret_cast<char*>(dexHeader));  
  107.         }  
  108.     }  
  109.     return;  
  110. }  
  111.   
  112. /*  
  113.  * 根据索引获取字符串 
  114.  *  DexStringId 结构体 
  115.  *  typedef struct _DexStringId 
  116.  *  { 
  117.  *      u4  stringDataOff;          // 指向 MUTF-8 字符串的偏移 
  118.  *  }DexStringId, *PDexStringId; 
  119.  */  
  120. std::string DexFile::parseStringId(u4 index)  
  121. {  
  122.     return std::string(MUTF8ToASCII(reinterpret_cast<char *>(stringIds[index].stringDataOff + reinterpret_cast<char*>(dexHeader))));  
  123. }  
  124.   
  125. /* 
  126.  * 根据索引获取类型 
  127.  * DexTypeId 结构体 
  128.  * typedef struct _DexTypeId 
  129.  * { 
  130.  *      u4  descriptorIdx;      // 指向 DexStringId 列表的索引 
  131.  * }DexTypeId, *PDexTypeId; 
  132.  */  
  133. std::string DexFile::parseTypeId(u4 index)  
  134. {  
  135.     return parseStringId(typeIds[index].descriptorIdx);  
  136. }  
  137.   
  138.   
  139. /* 
  140.  * 根据索引解析方法声明 
  141.  * DexProtoId 结构体 
  142.  * typedef struct _DexProtoId 
  143.  * { 
  144.  *      u4  shortyIdx;              // 方法声明字符串,指向 DexStringId 列表的索引,方法声明 = 返回类型+参数列表 
  145.  *      u4  returnTypeIdx;          // 方法返回类型字符串,指向 DexStringId 列表的索引 
  146.  *      u4  parametersOff;          // 方法的参数列表,指向 DexTypeList 结构的偏移 
  147.  * }DexProtoId, *PDexProtoId; 
  148.  */  
  149. std::string DexFile::parseProtoId(u4 index)  
  150. {  
  151.     // 方法声明 = 返回类型+参数列表  
  152.     std::string funcString = parseStringId(protoIds[index].shortyIdx);  
  153.   
  154.     // 参数  
  155.     if (protoIds[index].parametersOff != 0)  
  156.     {  
  157.         funcString.append(parseDataTypeList(reinterpret_cast<PDexTypeList>((protoIds[index].parametersOff) + reinterpret_cast<char*>(dexHeader))));  
  158.     }  
  159.       
  160.     // 返回值  
  161.     funcString.append(parseTypeId(protoIds[index].returnTypeIdx));  
  162.   
  163.     return funcString;  
  164. }  
  165.   
  166.   
  167. /* 
  168.  * 根据索引解析字段 
  169.  * DexFieldId 结构体 
  170.  * typedef struct _DexFieldId 
  171.  * { 
  172.  *      u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引 
  173.  *      u2  typeIdx;            // 字段的类型,指向 DexTypeId 列表的索引 
  174.  *      u4  nameIdx;            // 字段名,指向 DexStringId 列表的索引 
  175.  * }DexFieldId, *PDexFieldId; 
  176.  */  
  177. std::string DexFile::parseFieldId(u4 index)  
  178. {  
  179.     std::string  fieldString = parseTypeId(fieldIds[index].classIdx);  
  180.     fieldString.append(parseTypeId(fieldIds[index].typeIdx));  
  181.     fieldString.append(parseStringId(fieldIds[index].nameIdx));  
  182.   
  183.     return fieldString;  
  184. }  
  185.   
  186. /* 
  187.  * 根据索引解析方法 
  188.  * DexMethodId 结构体 
  189.  * typedef struct _DexMethodId 
  190.  * { 
  191.  *      u2  classIdx;           // 类的类型,指向 DexTypeId 列表的索引 
  192.  *      u2  protoIdx;           // 声明的类型,指向 DexProtoId 列表的索引 
  193.  *      u4  nameIdx;            // 方法名,指向 DexStringId 列表的索引 
  194.  * }DexMethodId, *PDexMethodId; 
  195.  */  
  196. std::string DexFile::parseMethodId(u4 index)  
  197. {  
  198.     std::string methodString = parseTypeId(methodIds[index].classIdx);  
  199.     methodString.append(parseProtoId(methodIds[index].protoIdx));  
  200.     methodString.append(parseStringId(methodIds[index].nameIdx));  
  201.   
  202.     return methodString;  
  203. }  
  204.   
  205.   
  206.   
  207. /* 
  208.  * 根据索引解析类 
  209.  * DexClassDef 结构 
  210.  * typedef struct _DexClassDef 
  211.  * { 
  212.  *      u4  classIdx;               // 类的类型,指向 DexTypeId 列表的索引 
  213.  *      u4  accessFlags;            // 类的访问标志 
  214.  *      u4  superclassIdx;          // 父类类型索引值,指向 DexTypeId 列表的索引,如果没有父类? 
  215.  *      u4  interfacesOff;          // 接口,如果有指向 DexTypeList 结构,否则为0 
  216.  *      u4  sourceFileIdx;          // 源文件名,指向 DexStringId 列表的索引 
  217.  *      u4  annotationsOff;         // 注解,指向 DexAnnotationsDirectoryItem,或者为0 
  218.  *      u4  classDataOff;           // 指向 DexClassData 结构的偏移,类的数据部分 
  219.  *      u4  staticValuesOff;        // 指向 DexEncodeArray 结构的偏移,记录了类中的静态数据 
  220.  */  
  221. std::string DexFile::parseClassDef(u4 index)  
  222. {  
  223.     std::string classString = "类类型:";  
  224.     // 类类型  
  225.     classString.append(parseTypeId(classDefs[index].classIdx));  
  226.       
  227.     // 类的访问标志  
  228.   
  229.     // 父类  
  230.     classString.append("\n父类:");  
  231.     classString.append(parseTypeId(classDefs[index].superclassIdx));  
  232.   
  233.     // 接口  
  234.     if (classDefs[index].interfacesOff != 0)  
  235.     {  
  236.         classString.append("\n接口:");  
  237.         classString.append(parseDataTypeList(reinterpret_cast<PDexTypeList>((classDefs[index].interfacesOff) + reinterpret_cast<char*>(dexHeader))));  
  238.     }  
  239.   
  240.     // 源文件名  
  241.     classString.append("\n源文件名:");  
  242.     classString.append(parseStringId(classDefs[index].sourceFileIdx));  
  243.   
  244.     // 注解  
  245.     // 暂时不处理  
  246.   
  247.     // 类的数据  
  248.     if (classDefs[index].classDataOff != 0)  
  249.     {  
  250.         classString.append(parseClassData(reinterpret_cast<PDexClassData>((classDefs[index].classDataOff) + reinterpret_cast<char*>(dexHeader))));  
  251.     }  
  252.   
  253.     // 类的静态数据  
  254.     if (classDefs[index].staticValuesOff != 0)  
  255.     {  
  256.         // do something  
  257.     }  
  258.     return classString;  
  259. }  
  260.   
  261.   
  262. /* 
  263.  * DexClassData 结构体 
  264.  * typedef struct _DexClassData 
  265.  * { 
  266.  *      DexClassDataHeader  header;             // 指定字段与方法的个数 
  267.  *      DexField*           staticFields;       // 静态字段 
  268.  *      DexField*           instanceFields;     // 实例字段 
  269.  *      DexMethod*          directMethods;      // 直接方法 
  270.  *      DexMethod*          virtualMethods;     // 虚方法 
  271.  * }DexClassData, *PDexClassData; 
  272.  * 
  273.  * DexClassDataHeader 结构体 
  274.  * typedef struct _DexClassDataHeader 
  275.  * { 
  276.  *      uleb128 staticFieldsSize;       // 静态字段个数 
  277.  *      uleb128 instanceFieldsSize;     // 实例字段个数 
  278.  *      uleb128 directMethodsSize;      // 直接方法个数 
  279.  *      uleb128 virtualMethodsSize;     // 虚方法个数 
  280.  * }DexClassDataHeader, *PDexClassDataHeader; 
  281.  */  
  282. std::string DexFile::parseClassData(PDexClassData classData)  
  283. {  
  284.     u1* ptr = reinterpret_cast<u1*>(classData);  
  285.     std::string str = "";  
  286.   
  287.     u4 staticFieldsSize = uleb128ToInt(&ptr);  
  288.     u4 instanceFieldsSize = uleb128ToInt(&ptr);  
  289.     u4 directMethodsSize = uleb128ToInt(&ptr);  
  290.     u4 virtualMethodsSize = uleb128ToInt(&ptr);  
  291.   
  292.     // 静态字段  
  293.     if (staticFieldsSize != 0)  
  294.     {  
  295.         str.append("\n静态字段个数:");  
  296.         str.append(IntToString(staticFieldsSize));  
  297.   
  298.         // 解析 DexField  
  299.         for (u4 i = 0; i < staticFieldsSize; ++i)  
  300.         {  
  301.             str.append("\n静态字段:");  
  302.             str.append(parseFieldId(uleb128ToInt(&ptr)));  
  303.             str.append("\n访问标志:");  
  304.             str.append(IntToString(uleb128ToInt(&ptr)));  
  305.         }  
  306.     }  
  307.   
  308.     // 实例字段  
  309.     if (instanceFieldsSize != 0)  
  310.     {  
  311.         str.append("\n实例字段个数:");  
  312.         str.append(IntToString(instanceFieldsSize));  
  313.   
  314.         // 解析 DexField  
  315.         for (u4 i = 0; i < instanceFieldsSize; ++i)  
  316.         {  
  317.             str.append("\n实例字段:");  
  318.             str.append(parseFieldId(uleb128ToInt(&ptr)));  
  319.             str.append("\n访问标志");  
  320.             str.append(IntToString(uleb128ToInt(&ptr)));  
  321.         }  
  322.     }  
  323.   
  324.     // 直接方法  
  325.     if (directMethodsSize != 0)  
  326.     {  
  327.         str.append("\n直接方法个数:");  
  328.         str.append(IntToString(directMethodsSize));  
  329.   
  330.         // 解析 DexMethod  
  331.         for (u4 i = 0; i < directMethodsSize; ++i)  
  332.         {  
  333.             str.append("\n直接方法:");  
  334.             str.append(parseMethodId(uleb128ToInt(&ptr)));  
  335.             str.append("\n访问标志:");  
  336.             str.append(IntToString(uleb128ToInt(&ptr)));  
  337.             str.append("\nDexCode的偏移:");  
  338.             str.append(IntToString(uleb128ToInt(&ptr)));  
  339.         }  
  340.     }  
  341.   
  342.     // 虚方法  
  343.     if (virtualMethodsSize != 0)  
  344.     {  
  345.         str.append("\n虚方法个数:");  
  346.         str.append(IntToString(virtualMethodsSize));  
  347.   
  348.         // 解析 DexMethod  
  349.         for (u4 i = 0; i < virtualMethodsSize; ++i)  
  350.         {  
  351.             str.append("\n虚方法:");  
  352.             str.append(parseMethodId(uleb128ToInt(&ptr)));  
  353.             str.append("\n访问标志:");  
  354.             str.append(IntToString(uleb128ToInt(&ptr)));  
  355.             str.append("\nDexCode的偏移:");  
  356.             str.append(IntToString(uleb128ToInt(&ptr)));  
  357.         }  
  358.     }  
  359.   
  360.     return str;  
  361. }  
  362.   
  363.   
  364. /************************************************ 
  365. * DexTypeList 结构体 
  366. * typedef struct _DexTypeList 
  367. * { 
  368. *       u4  size;               // 接下来 DexTypeItem 的个数 
  369. *       PDexTypeItem    list;   // DexTypeItem 结构 
  370. * }DexTypeList, *PDexTypeList; 
  371. * 
  372. * DexTypeItem 结构体 
  373. * typedef struct _DexTypeItem 
  374. * { 
  375. *       u2  typeIdx;            // 指向 DexTypeId 列表的索引 
  376. * }DexTypeItem, *PDexTypeItem; 
  377. ************************************************/  
  378. std::string DexFile::parseDataTypeList(PDexTypeList typeList)  
  379. {  
  380.     std::string str = "";  
  381.     PDexTypeItem ptr = reinterpret_cast<PDexTypeItem>((reinterpret_cast<char*>(typeList)) + sizeof(u4));  
  382.     for (u4 i = 0; i < typeList->size; ++i)  
  383.     {  
  384.         str.append(parseTypeId(ptr[i].typeIdx));  
  385.     }  
  386.   
  387.     return str;  
  388. }  
  389.   
  390.   
  391.   
  392. int DexFile::uleb128ToInt(u1** pStream)   
  393. {  
  394.     u1* ptr = *pStream;  
  395.     int result = *(ptr++);  
  396.   
  397.     if (result > 0x7f) {  
  398.         int cur = *(ptr++);  
  399.         result = (result & 0x7f) | ((cur & 0x7f) << 7);  
  400.         if (cur > 0x7f) {  
  401.             cur = *(ptr++);  
  402.             result |= (cur & 0x7f) << 14;  
  403.             if (cur > 0x7f) {  
  404.                 cur = *(ptr++);  
  405.                 result |= (cur & 0x7f) << 21;  
  406.                 if (cur > 0x7f) {  
  407.                     /* 
  408.                     * Note: We don't check to see if cur is out of 
  409.                     * range here, meaning we tolerate garbage in the 
  410.                     * high four-order bits. 
  411.                     */  
  412.                     cur = *(ptr++);  
  413.                     result |= cur << 28;  
  414.                 }  
  415.             }  
  416.         }  
  417.     }  
  418.     *pStream = ptr;  
  419.     return result;  
  420. }  
  421.   
  422. int DexFile::sleb128ToInt(u1** pStream)   
  423. {  
  424.     u1* ptr = *pStream;  
  425.     int result = *(ptr++);  
  426.   
  427.     if (result <= 0x7f) {  
  428.         result = (result << 25) >> 25;  
  429.     }  
  430.     else {  
  431.         int cur = *(ptr++);  
  432.         result = (result & 0x7f) | ((cur & 0x7f) << 7);  
  433.         if (cur <= 0x7f) {  
  434.             result = (result << 18) >> 18;  
  435.         }  
  436.         else {  
  437.             cur = *(ptr++);  
  438.             result |= (cur & 0x7f) << 14;  
  439.             if (cur <= 0x7f) {  
  440.                 result = (result << 11) >> 11;  
  441.             }  
  442.             else {  
  443.                 cur = *(ptr++);  
  444.                 result |= (cur & 0x7f) << 21;  
  445.                 if (cur <= 0x7f) {  
  446.                     result = (result << 4) >> 4;  
  447.                 }  
  448.                 else {  
  449.                     /* 
  450.                     * Note: We don't check to see if cur is out of 
  451.                     * range here, meaning we tolerate garbage in the 
  452.                     * high four-order bits. 
  453.                     */  
  454.                     cur = *(ptr++);  
  455.                     result |= cur << 28;  
  456.                 }  
  457.             }  
  458.         }  
  459.     }  
  460.     *pStream = ptr;  
  461.     return result;  
  462. }  
  463.   
  464.   
  465. std::string DexFile::IntToString(int num)  
  466. {  
  467.     std::stringstream strStream;  
  468.     std::string str;  
  469.     strStream << num;  
  470.     strStream >> str;  
  471.     return str;  
  472. }  
/*
 * 解析 Dex 文件
 */

#include "dex.h"
#include <sstream>
#include <string>
#include <iostream>

void DexFile::parseAllClass()
{
	for (u4 i = 0; i < dexHeader->classDefsSize; ++i)
	{
		std::cout << parseClassDef(i) << std::endl;
		std::cout << std::endl;
	}
}

DexFile::DexFile(char* file)
{
	// dex 头
	dexHeader = reinterpret_cast<PDexHeader>(file);
	if (dexHeader == nullptr)
	{
		return;
	}
	else
	{
		// 字符串
		if (dexHeader->stringIdsOff != 0)
		{
			stringIds = reinterpret_cast<PDexStringId>((dexHeader->stringIdsOff) + reinterpret_cast<char*>(dexHeader));
		}
		else
		{
			stringIds = nullptr;
		}

		// 类型
		if (dexHeader->typedeIdsOff == 0)
		{
			typeIds = nullptr;
		}
		else
		{
			typeIds = reinterpret_cast<PDexTypeId>((dexHeader->typedeIdsOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 声明
		if (dexHeader->protoIdsOff == 0)
		{
			protoIds = nullptr;
		}
		else
		{
			protoIds = reinterpret_cast<PDexProtoId>((dexHeader->protoIdsOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 字段
		if (dexHeader->fieldIdsOff == 0)
		{
			fieldIds = nullptr;
		}
		else
		{
			fieldIds = reinterpret_cast<PDexFieldId>((dexHeader->fieldIdsOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 方法
		if (dexHeader->methodIdsOff == 0)
		{
			methodIds = nullptr;
		}
		else
		{
			methodIds = reinterpret_cast<PDexMethodId>((dexHeader->methodIdsOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 类
		if (dexHeader->classDefsOff == 0)
		{
			classDefs = nullptr;
		}
		else
		{
			classDefs = reinterpret_cast<PDexClassDef>((dexHeader->classDefsOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 数据
		if (dexHeader->dataOff == 0)
		{
			data = nullptr;
		}
		else
		{
			data = reinterpret_cast<PDexData>((dexHeader->dataOff) + reinterpret_cast<char*>(dexHeader));
		}

		// 静态链接数据区
		if (dexHeader->linkOff == 0)
		{
			linkData = nullptr;
		}
		else
		{
			linkData = reinterpret_cast<PDexLink>((dexHeader->linkOff) + reinterpret_cast<char*>(dexHeader));
		}
	}
	return;
}

/* 
 * 根据索引获取字符串
 *	DexStringId 结构体
 *	typedef struct _DexStringId
 *	{
 *		u4	stringDataOff;			// 指向 MUTF-8 字符串的偏移
 *	}DexStringId, *PDexStringId;
 */
std::string DexFile::parseStringId(u4 index)
{
	return std::string(MUTF8ToASCII(reinterpret_cast<char *>(stringIds[index].stringDataOff + reinterpret_cast<char*>(dexHeader))));
}

/*
 * 根据索引获取类型
 * DexTypeId 结构体
 * typedef struct _DexTypeId
 * {
 *		u4	descriptorIdx;		// 指向 DexStringId 列表的索引
 * }DexTypeId, *PDexTypeId;
 */
std::string DexFile::parseTypeId(u4 index)
{
	return parseStringId(typeIds[index].descriptorIdx);
}


/*
 * 根据索引解析方法声明
 * DexProtoId 结构体
 * typedef struct _DexProtoId
 * {
 *		u4	shortyIdx;				// 方法声明字符串,指向 DexStringId 列表的索引,方法声明 = 返回类型+参数列表
 *		u4	returnTypeIdx;			// 方法返回类型字符串,指向 DexStringId 列表的索引
 *		u4	parametersOff;			// 方法的参数列表,指向 DexTypeList 结构的偏移
 * }DexProtoId, *PDexProtoId;
 */
std::string DexFile::parseProtoId(u4 index)
{
	// 方法声明 = 返回类型+参数列表
	std::string funcString = parseStringId(protoIds[index].shortyIdx);

	// 参数
	if (protoIds[index].parametersOff != 0)
	{
		funcString.append(parseDataTypeList(reinterpret_cast<PDexTypeList>((protoIds[index].parametersOff) + reinterpret_cast<char*>(dexHeader))));
	}
	
	// 返回值
	funcString.append(parseTypeId(protoIds[index].returnTypeIdx));

	return funcString;
}


/*
 * 根据索引解析字段
 * DexFieldId 结构体
 * typedef struct _DexFieldId
 * {
 *		u2	classIdx;			// 类的类型,指向 DexTypeId 列表的索引
 *		u2	typeIdx;			// 字段的类型,指向 DexTypeId 列表的索引
 *		u4	nameIdx;			// 字段名,指向 DexStringId 列表的索引
 * }DexFieldId, *PDexFieldId;
 */
std::string DexFile::parseFieldId(u4 index)
{
	std::string  fieldString = parseTypeId(fieldIds[index].classIdx);
	fieldString.append(parseTypeId(fieldIds[index].typeIdx));
	fieldString.append(parseStringId(fieldIds[index].nameIdx));

	return fieldString;
}

/*
 * 根据索引解析方法
 * DexMethodId 结构体
 * typedef struct _DexMethodId
 * {
 *		u2	classIdx;			// 类的类型,指向 DexTypeId 列表的索引
 *		u2	protoIdx;			// 声明的类型,指向 DexProtoId 列表的索引
 *		u4	nameIdx;			// 方法名,指向 DexStringId 列表的索引
 * }DexMethodId, *PDexMethodId;
 */
std::string DexFile::parseMethodId(u4 index)
{
	std::string methodString = parseTypeId(methodIds[index].classIdx);
	methodString.append(parseProtoId(methodIds[index].protoIdx));
	methodString.append(parseStringId(methodIds[index].nameIdx));

	return methodString;
}



/*
 * 根据索引解析类
 * DexClassDef 结构
 * typedef struct _DexClassDef
 * {
 *		u4	classIdx;				// 类的类型,指向 DexTypeId 列表的索引
 *		u4	accessFlags;			// 类的访问标志
 *		u4	superclassIdx;			// 父类类型索引值,指向 DexTypeId 列表的索引,如果没有父类?
 *		u4	interfacesOff;			// 接口,如果有指向 DexTypeList 结构,否则为0
 *		u4	sourceFileIdx;			// 源文件名,指向 DexStringId 列表的索引
 *		u4	annotationsOff;			// 注解,指向 DexAnnotationsDirectoryItem,或者为0
 *		u4	classDataOff;			// 指向 DexClassData 结构的偏移,类的数据部分
 *		u4	staticValuesOff;		// 指向 DexEncodeArray 结构的偏移,记录了类中的静态数据
 */
std::string DexFile::parseClassDef(u4 index)
{
	std::string classString = "类类型:";
	// 类类型
	classString.append(parseTypeId(classDefs[index].classIdx));
	
	// 类的访问标志

	// 父类
	classString.append("\n父类:");
	classString.append(parseTypeId(classDefs[index].superclassIdx));

	// 接口
	if (classDefs[index].interfacesOff != 0)
	{
		classString.append("\n接口:");
		classString.append(parseDataTypeList(reinterpret_cast<PDexTypeList>((classDefs[index].interfacesOff) + reinterpret_cast<char*>(dexHeader))));
	}

	// 源文件名
	classString.append("\n源文件名:");
	classString.append(parseStringId(classDefs[index].sourceFileIdx));

	// 注解
	// 暂时不处理

	// 类的数据
	if (classDefs[index].classDataOff != 0)
	{
		classString.append(parseClassData(reinterpret_cast<PDexClassData>((classDefs[index].classDataOff) + reinterpret_cast<char*>(dexHeader))));
	}

	// 类的静态数据
	if (classDefs[index].staticValuesOff != 0)
	{
		// do something
	}
	return classString;
}


/*
 * DexClassData 结构体
 * typedef struct _DexClassData
 * {
 *		DexClassDataHeader	header;				// 指定字段与方法的个数
 *		DexField*			staticFields;		// 静态字段
 *		DexField*			instanceFields;		// 实例字段
 *		DexMethod*			directMethods;		// 直接方法
 *		DexMethod*			virtualMethods;		// 虚方法
 * }DexClassData, *PDexClassData;
 *
 * DexClassDataHeader 结构体
 * typedef struct _DexClassDataHeader
 * {
 *		uleb128	staticFieldsSize;		// 静态字段个数
 *		uleb128	instanceFieldsSize;		// 实例字段个数
 *		uleb128	directMethodsSize;		// 直接方法个数
 *		uleb128	virtualMethodsSize;		// 虚方法个数
 * }DexClassDataHeader, *PDexClassDataHeader;
 */
std::string DexFile::parseClassData(PDexClassData classData)
{
	u1* ptr = reinterpret_cast<u1*>(classData);
	std::string str = "";

	u4 staticFieldsSize = uleb128ToInt(&ptr);
	u4 instanceFieldsSize = uleb128ToInt(&ptr);
	u4 directMethodsSize = uleb128ToInt(&ptr);
	u4 virtualMethodsSize = uleb128ToInt(&ptr);

	// 静态字段
	if (staticFieldsSize != 0)
	{
		str.append("\n静态字段个数:");
		str.append(IntToString(staticFieldsSize));

		// 解析 DexField
		for (u4 i = 0; i < staticFieldsSize; ++i)
		{
			str.append("\n静态字段:");
			str.append(parseFieldId(uleb128ToInt(&ptr)));
			str.append("\n访问标志:");
			str.append(IntToString(uleb128ToInt(&ptr)));
		}
	}

	// 实例字段
	if (instanceFieldsSize != 0)
	{
		str.append("\n实例字段个数:");
		str.append(IntToString(instanceFieldsSize));

		// 解析 DexField
		for (u4 i = 0; i < instanceFieldsSize; ++i)
		{
			str.append("\n实例字段:");
			str.append(parseFieldId(uleb128ToInt(&ptr)));
			str.append("\n访问标志");
			str.append(IntToString(uleb128ToInt(&ptr)));
		}
	}

	// 直接方法
	if (directMethodsSize != 0)
	{
		str.append("\n直接方法个数:");
		str.append(IntToString(directMethodsSize));

		// 解析 DexMethod
		for (u4 i = 0; i < directMethodsSize; ++i)
		{
			str.append("\n直接方法:");
			str.append(parseMethodId(uleb128ToInt(&ptr)));
			str.append("\n访问标志:");
			str.append(IntToString(uleb128ToInt(&ptr)));
			str.append("\nDexCode的偏移:");
			str.append(IntToString(uleb128ToInt(&ptr)));
		}
	}

	// 虚方法
	if (virtualMethodsSize != 0)
	{
		str.append("\n虚方法个数:");
		str.append(IntToString(virtualMethodsSize));

		// 解析 DexMethod
		for (u4 i = 0; i < virtualMethodsSize; ++i)
		{
			str.append("\n虚方法:");
			str.append(parseMethodId(uleb128ToInt(&ptr)));
			str.append("\n访问标志:");
			str.append(IntToString(uleb128ToInt(&ptr)));
			str.append("\nDexCode的偏移:");
			str.append(IntToString(uleb128ToInt(&ptr)));
		}
	}

	return str;
}


/************************************************
* DexTypeList 结构体
* typedef struct _DexTypeList
* {
*		u4	size;				// 接下来 DexTypeItem 的个数
*		PDexTypeItem	list;	// DexTypeItem 结构
* }DexTypeList, *PDexTypeList;
*
* DexTypeItem 结构体
* typedef struct _DexTypeItem
* {
*		u2	typeIdx;			// 指向 DexTypeId 列表的索引
* }DexTypeItem, *PDexTypeItem;
************************************************/
std::string DexFile::parseDataTypeList(PDexTypeList typeList)
{
	std::string str = "";
	PDexTypeItem ptr = reinterpret_cast<PDexTypeItem>((reinterpret_cast<char*>(typeList)) + sizeof(u4));
	for (u4 i = 0; i < typeList->size; ++i)
	{
		str.append(parseTypeId(ptr[i].typeIdx));
	}

	return str;
}



int DexFile::uleb128ToInt(u1** pStream) 
{
	u1* ptr = *pStream;
	int result = *(ptr++);

	if (result > 0x7f) {
		int cur = *(ptr++);
		result = (result & 0x7f) | ((cur & 0x7f) << 7);
		if (cur > 0x7f) {
			cur = *(ptr++);
			result |= (cur & 0x7f) << 14;
			if (cur > 0x7f) {
				cur = *(ptr++);
				result |= (cur & 0x7f) << 21;
				if (cur > 0x7f) {
					/*
					* Note: We don't check to see if cur is out of
					* range here, meaning we tolerate garbage in the
					* high four-order bits.
					*/
					cur = *(ptr++);
					result |= cur << 28;
				}
			}
		}
	}
	*pStream = ptr;
	return result;
}

int DexFile::sleb128ToInt(u1** pStream) 
{
	u1* ptr = *pStream;
	int result = *(ptr++);

	if (result <= 0x7f) {
		result = (result << 25) >> 25;
	}
	else {
		int cur = *(ptr++);
		result = (result & 0x7f) | ((cur & 0x7f) << 7);
		if (cur <= 0x7f) {
			result = (result << 18) >> 18;
		}
		else {
			cur = *(ptr++);
			result |= (cur & 0x7f) << 14;
			if (cur <= 0x7f) {
				result = (result << 11) >> 11;
			}
			else {
				cur = *(ptr++);
				result |= (cur & 0x7f) << 21;
				if (cur <= 0x7f) {
					result = (result << 4) >> 4;
				}
				else {
					/*
					* Note: We don't check to see if cur is out of
					* range here, meaning we tolerate garbage in the
					* high four-order bits.
					*/
					cur = *(ptr++);
					result |= cur << 28;
				}
			}
		}
	}
	*pStream = ptr;
	return result;
}


std::string DexFile::IntToString(int num)
{
	std::stringstream strStream;
	std::string	str;
	strStream << num;
	strStream >> str;
	return str;
}















 

 
0
0
 

 

posted @ 2017-06-15 16:17  sudenbutcher  阅读(663)  评论(0)    收藏  举报