整体结构:
文件头
字符串列表
类型列表
原型列表
字段列表
方法列表
类定义列表
数据
u1 magic[8]; //dex\n035
u4 checksum; //adler32校验
u1 signature[kSHA1DigestLen]; //SHA-1签名
u4 fileSize; //文件大小
u4 headerSize; //DexHeader结构大小
u4 endianTag; //字节序标记
u4 linkSize; u4 linkOff; //链接段大小和偏移
u4 mapOff; //DexMapList文件偏移
u4 stringIdsSize; u4 stringIdsOff;
u4 typeIdsSize; u4 typeIdsOff;
u4 protoIdsSize; u4 protoIdsOff;
u4 fieldIdsSize; u4 fieldIdsOff;
u4 methodIdsSize; u4 methodIdsOff;
u4 classDefsSize; u4 classDefsOff;
u4 dataSize; u4 dataOff;
};
字符串和类型列表
struct DexStringId{
u4 stringDataOff; //指向字符串数据起始地址
};
struct DexTypeId{
u4 descriptorIdx; //指向DexStringId列表的索引
};
原型列表
struct DexProtoId{
u4 shortyIdx; // 指向DexStringId列表的索引
u4 returnTypeIdx; // 指向DexTypeId列表的索引
u4 parametersOff; // 指向DexTypeList的偏移
};
struct DexTypeList{
u4 size; // DexTypeItem的个数
DexTypeItem list[1];
};
struct DexTypeItem{
u2 typeIdx; // 指向DexTypeId列表的索引
};
字段和方法列表
struct DexFieldId{
u2 classIdx; //字段类类型,指向DexTypeId列表索引
u2 typeIdx; //字段类型,指向DexTypeId列表索引
u4 nameIdx; //字段名,指向DexStringId列表索引
};
struct DexMethodId{
u2 classIdx; //类类型,指向DexTypeId列表索引
u2 protoIdx; //声明类型,指向DexTypeId列表索引
u4 nameIdx; //方法名,指向DexStringId列表索引
};
类列表
struct DexClassDef{
u4 classIdx; //类类型,指向DexTypeId列表索引
u4 accessFlags; //访问标志,ACC_为前缀的枚举值
u4 superclassIdx; //父类类型,指向DexTypeId列表索引
u4 interfacesOff; //接口,指向DexTypeList
u4 sourceFileIdx; //源文件名,指向DexStringId列表索引
u4 annotationsOff; //注解,指向DexAnnotationsDirectoryItem
u4 classDataOff; //指向DexClassData结构偏移
u4 staticValuesOff; //指向DexEncodedArray结构偏移
};
struct DexClassData{
DexClassDataHeader header; //字段和方法个数的描述
DexField* staticFields; //静态字段
DexField* instanceFields; //实例字段
DexMethod* directMethods; //直接方法
DexMethod* virtualMethods; //虚方法
}
struct DexClassDataHeader{
u4 staticFieldsSize; //静态字段个数
u4 instanceFieldsSize; //实例字段个数
u4 directMethodsSize; //直接方法个数
u4 virtualMethodsSize; //虚方法个数
};
struct DexField{
u4 fieldIdx; //DexFieldId列表索引
u4 accessFlags; //访问标志
};
struct DexMethod{
u4 methodIdx; //方法列表索引
u4 accessFlags; //访问标志
u4 codeOff; //指向DexCode偏移
};
struct DexCode{
u2 registersSize; //使用寄存器个数
u2 insSize; //参数个数
u2 outsSize; //调用其他方法使用的寄存器个数
u2 triesSize; //try catch个数
u4 debugInfoOff; //调试信息偏移
u4 insnsSize; //指令个数
u2 insns[1]; //指令
// u2 padding //结构体对齐
// try_item[triesSize] //DexTry结构
// uleb128 handlersSize //Try hanlder个数
// catch_handler_item[handlersSize] //DexCatchHanlder
};