Android學習心得(15) --- Dex檔案結構解析(1)

來源:互聯網
上載者:User

標籤:android   dex分析   dex   結構   android應用   

我在部落格上發表一些我的Android學習心得,希望對大家能有協助。
這一篇我們講述一下Android可執行檔dex的結構解析。

參考Leb128資料類型 Android學習心得(5) --- dex資料類型LEB128
參考執行個體分析學習理解dex檔案結構Android學習心得(15) --- Dex檔案結構解析(1)

1、Dex背景
    Android應用開發和Dalvik虛擬機器Android應用所使用的程式設計語言是Java語言,在編譯時間使用JDK將Java來源程式編程成標準的Java位元組碼檔案。    而後通過工具軟體DX把所有的位元組碼檔案轉成Android DEX檔案(classes.dex)。    最後使用Android打包工具(aapt)將DEX檔案,資源檔以及AndroidManifest.xml檔案(二進位格式)組合成一個應用程式套件組合(APK)。     應用程式套件組合可以被發布到手機上運行。 
2、Dex檔案整體結構



從中我們可以看到,dex檔案是由多個結構體組成。Dex Header是dex標頭檔,定義了一些屬性,記錄了其他資料結構的位移地址。從String table ~ Class Def table是位移索引的地區。Data Section則是真實資料存放地方。 

首先我們通過/dalvik/libdex/DexFile.h查看DexFile結構

/* * Structure representing a DEX file. * * Code should regard DexFile as opaque, using the API calls provided here * to access specific structures. */typedef struct DexFile {    /* directly-mapped "opt" header */    const DexOptHeader* pOptHeader;    /* pointers to directly-mapped structs and arrays in base DEX */    const DexHeader*    pHeader;    const DexStringId*  pStringIds;    const DexTypeId*    pTypeIds;    const DexFieldId*   pFieldIds;    const DexMethodId*  pMethodIds;    const DexProtoId*   pProtoIds;    const DexClassDef*  pClassDefs;    const DexLink*      pLinkData;    /* mapped in "auxillary" section */    const DexClassLookup* pClassLookup;    /* points to start of DEX file data */    const u1*           baseAddr;    /* track memory overhead for auxillary structures */    int                 overhead;    /* additional app-specific data structures associated with the DEX */    void*               auxData;} DexFile;
3、Dex Header解析

我們通過/dalvik/libdex/DexFile.h查看header_item

/* * Direct-mapped "header_item" struct. */typedef struct DexHeader {    u1  magic[8];           /* includes version number */    u4  checksum;           /* adler32 checksum */    u1  signature[kSHA1DigestLen]; /* SHA-1 hash */    u4  fileSize;           /* length of entire file */    u4  headerSize;         /* offset to start of next section */    u4  endianTag;          /*位元組序標號*/    u4  linkSize;    u4  linkOff;    u4  mapOff;    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;} DexHeader;


4、Mapoff指向MapList

DexHeader結構中MapList資料結構

/* * Direct-mapped "map_item". */typedef struct DexMapItem {    u2  type;              /* type code (see kDexType* above) */    u2  unused;    u4  size;              /* count of items of the indicated type */    u4  offset;            /* file offset to the start of data */} DexMapItem;/* * Direct-mapped "map_list". */typedef struct DexMapList {    u4  size;               /* #of entries in list */    DexMapItem list[1];     /* entries */} DexMapList;

在DexMapItem結構中,type是一個枚舉常量

/* map item type codes */ 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, };
5、部分結構

通過DexMapList結構產生的表格,來分別找出其中DexMapItem中的結構
由於class_def_item比較複雜,單獨敘述

/*  * Direct-mapped "string_id_item".  */ typedef struct DexStringId {     u4  stringDataOff;      /* file offset to string_data_item */ } DexStringId; /*  * Direct-mapped "type_id_item".  */ typedef struct DexTypeId {     u4  descriptorIdx;      /* index into stringIds list for type descriptor */ } DexTypeId; /*  * Direct-mapped "field_id_item".  */ typedef struct DexFieldId {     u2  classIdx;           /* index into typeIds list for defining class */     u2  typeIdx;            /* index into typeIds for field type */     u4  nameIdx;            /* index into stringIds for field name */ } DexFieldId; /*  * Direct-mapped "method_id_item".  */ typedef struct DexMethodId {     u2  classIdx;           /* index into typeIds list for defining class */     u2  protoIdx;           /* index into protoIds for method prototype */     u4  nameIdx;            /* index into stringIds for method name */ } DexMethodId; /*  * Direct-mapped "proto_id_item".  */ typedef struct DexProtoId {     u4  shortyIdx;          /* index into stringIds for shorty descriptor */     u4  returnTypeIdx;      /* index into typeIds list for return type */     u4  parametersOff;      /* file offset to type_list for parameter types */ } DexProtoId;

在DexProtoId結構中,parameterOff是type_list的位移

/*  * Direct-mapped "type_item".  */ typedef struct DexTypeItem {     u2  typeIdx;            /* index into typeIds */ } DexTypeItem; /*  * Direct-mapped "type_list".  */ typedef struct DexTypeList {     u4  size;               /* #of entries in list */     DexTypeItem list[1];    /* entries */ } DexTypeList;
6、DexClassDef結構
/*  * Direct-mapped "class_def_item".  */ typedef struct DexClassDef {     u4  classIdx;           /* index into typeIds for this class */     u4  accessFlags;     u4  superclassIdx;      /* index into typeIds for superclass */     u4  interfacesOff;      /* file offset to DexTypeList */     u4  sourceFileIdx;      /* index into stringIds for source file name */     u4  annotationsOff;     /* file offset to annotations_directory_item */     u4  classDataOff;       /* file offset to class_data_item */     u4  staticValuesOff;    /* file offset to DexEncodedArray */ } DexClassDef;

annotationsOff是註解目錄結構位移,目前暫不詳細說明,如果沒有註解,其值為0。

classDataOff是指向class_data_item位移,下面介紹其結構
路徑為/dalvik/libdex/DexClass.h

/* expanded form of class_data_item. Note: If a particular item is  * absent (e.g., no static fields), then the corresponding pointer  * is set to NULL. */ typedef struct DexClassData {     DexClassDataHeader header;     DexField*          staticFields;     DexField*          instanceFields;     DexMethod*         directMethods;     DexMethod*         virtualMethods; } DexClassData;/* expanded form of a class_data_item header */ typedef struct DexClassDataHeader {     u4 staticFieldsSize;     u4 instanceFieldsSize;     u4 directMethodsSize;     u4 virtualMethodsSize; } DexClassDataHeader;

DexField & DexMethod

 /* expanded form of encoded_field */ typedef struct DexField {     u4 fieldIdx;    /* index to a field_id_item */     u4 accessFlags; } DexField; /* expanded form of encoded_method */ typedef struct DexMethod {     u4 methodIdx;    /* index to a method_id_item */     u4 accessFlags;     u4 codeOff;      /* file offset to a code_item */ } DexMethod;

code_item位於/dalvik/libdex/DexFile.h中定義

/*  * Direct-mapped "code_item".  *  * The "catches" table is used when throwing an exception,  * "debugInfo" is used when displaying an exception stack trace or  * debugging. An offset of zero indicates that there are no entries.  */ typedef struct DexCode {     u2  registersSize;     u2  insSize;     u2  outsSize;     u2  triesSize;     u4  debugInfoOff;       /* file offset to debug info stream */     u4  insnsSize;          /* size of the insns array, in u2 units */     u2  insns[1];     /* followed by optional u2 padding */     /* followed by try_item[triesSize] */     /* followed by uleb128 handlersSize */     /* followed by catch_handler_item[handlersSize] */ } DexCode;

到目前為止,基本上我們把dex檔案組成結構給大家展示了出來。
下面要進行的就是對dex檔案執行個體結合這篇來進行分析
Android學習心得(16) --- Dex檔案結構解析(2)

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android學習心得(15) --- Dex檔案結構解析(1)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.