2020-09-20 手动解析dex文件

//
//  DexFile.hpp
//  DexParser
//
//  Created by Nop on 2020/9/19.
//

#ifndef DexFile_hpp
#define DexFile_hpp

#include 
#include 
#include 

typedef uint8_t             u1;
typedef uint16_t            u2;
typedef uint32_t            u4;
typedef uint64_t            u8;
typedef int8_t              s1;
typedef int16_t             s2;
typedef int32_t             s4;
typedef int64_t             s8;

enum { kSHA1DigestLen = 20,
       kSHA1DigestOutputLen = kSHA1DigestLen*2 +1 };

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),
};

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 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;
};

struct DexStringId {
    u4 stringDataOff;      /* file offset to string_data_item */
};

struct DexTypeId {
    u4  descriptorIdx;      /* index into stringIds list for type descriptor */
};

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 */
};

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 */
};

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 */
};

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 */
};

struct DexTypeItem {
    u2  typeIdx;            /* index into typeIds */
};

/*
 * Direct-mapped "type_list".
 */
struct DexTypeList {
    u4  size;               /* #of entries in list */
    DexTypeItem list[1];    /* entries */
};

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 */
};

struct DexMapList {
    u4  size;               /* #of entries in list */
    DexMapItem list[1];     /* entries */
};

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] */
};

struct DexClassDataHeader {
    u4 staticFieldsSize;
    u4 instanceFieldsSize;
    u4 directMethodsSize;
    u4 virtualMethodsSize;
};

/* expanded form of encoded_field */
struct DexField {
    u4 fieldIdx;    /* index to a field_id_item */
    u4 accessFlags;
};

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

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

#endif /* DexFile_hpp */
//
//  dexParser.hpp
//  DexParser
//
//  Created by Nop on 2020/9/19.
//

#ifndef dexParser_hpp
#define dexParser_hpp

#include 
#include 
#include 
#include "DexFile.hpp"

int getDexHeader(u1* dexfptr, struct DexHeader* dexHeader);

void loadDexStringId(u1* dexfptr, long offset, struct DexStringId* ids, int size);

void loadDexTypeId(u1* dexfptr, long offset, struct DexTypeId* ids, int size);

void loadDexProtoId(u1* dexfptr, long offset, struct DexProtoId* ids, int size);

void loadDexFieldId(u1* dexfptr, long offset, struct DexFieldId* ids, int size);

void loadDexMethodId(u1* dexfptr, long offset, struct DexMethodId* ids, int size);

void loadDexClassDef(u1* dexfptr, long offset, struct DexClassDef* ids, int size);

void loadDexTypeList(u1* dexfptr, long offset, struct DexTypeList* list);

void loadMap(u1* dexfptr, long offset, struct DexMapList* list);

const char* accessIntValueOfString(int v);
const char* dexMapItemToString(int v);

void loadDexCode(u1* dexfpter, long offset, struct DexCode* dexCode, int size);
#endif /* dexParser_hpp */

//
//  dexParser.cpp
//  DexParser
//
//  Created by Nop on 2020/9/19.
//

#include "dexParser.hpp"

int getDexHeader(u1* dexfptr, struct DexHeader* dexHeader) {
    int offset = 0;
    
    memcpy(dexHeader->magic, dexfptr, sizeof(dexHeader->magic));
    offset += sizeof(dexHeader->magic);
    memcpy(&(dexHeader->checksum), dexfptr + offset, sizeof(dexHeader->checksum));
    offset += sizeof(dexHeader->checksum);
    memcpy(dexHeader->signature, dexfptr + offset, sizeof(dexHeader->signature));
    offset += sizeof(dexHeader->signature);
    memcpy(&(dexHeader->fileSize), dexfptr + offset, sizeof(dexHeader->fileSize));
    offset += sizeof(dexHeader->fileSize);
    memcpy(&(dexHeader->headerSize), dexfptr + offset, sizeof(dexHeader->headerSize));
    offset += sizeof(dexHeader->headerSize);
    memcpy(&(dexHeader->endianTag), dexfptr + offset, sizeof(dexHeader->endianTag));
    offset += sizeof(dexHeader->endianTag);
    
    memcpy(&(dexHeader->linkSize), dexfptr + offset, sizeof(dexHeader->linkSize));
    offset += sizeof(dexHeader->linkSize);
    memcpy(&(dexHeader->linkOff), dexfptr + offset, sizeof(dexHeader->linkOff));
    offset += sizeof(dexHeader->linkOff);
    
    memcpy(&(dexHeader->mapOff), dexfptr + offset, sizeof(dexHeader->mapOff));
    offset += sizeof(dexHeader->mapOff);
    
    memcpy(&(dexHeader->stringIdsSize), dexfptr + offset, sizeof(dexHeader->stringIdsSize));
    offset += sizeof(dexHeader->stringIdsSize);
    memcpy(&(dexHeader->stringIdsOff), dexfptr + offset, sizeof(dexHeader->stringIdsOff));
    offset += sizeof(dexHeader->stringIdsOff);
    
    memcpy(&(dexHeader->typeIdsSize), dexfptr + offset, sizeof(dexHeader->typeIdsSize));
    offset += sizeof(dexHeader->typeIdsSize);
    memcpy(&(dexHeader->typeIdsOff), dexfptr + offset, sizeof(dexHeader->typeIdsOff));
    offset += sizeof(dexHeader->typeIdsOff);
    memcpy(&(dexHeader->protoIdsSize), dexfptr + offset, sizeof(dexHeader->protoIdsSize));
    offset += sizeof(dexHeader->protoIdsSize);
    memcpy(&(dexHeader->protoIdsOff), dexfptr + offset, sizeof(dexHeader->protoIdsOff));
    offset += sizeof(dexHeader->protoIdsOff);
   
    memcpy(&(dexHeader->fieldIdsSize), dexfptr + offset, sizeof(dexHeader->fieldIdsSize));
    offset += sizeof(dexHeader->fieldIdsSize);
    memcpy(&(dexHeader->fieldIdsOff), dexfptr + offset, sizeof(dexHeader->fieldIdsOff));
    offset += sizeof(dexHeader->fieldIdsOff);
    memcpy(&(dexHeader->methodIdsSize), dexfptr + offset, sizeof(dexHeader->methodIdsSize));
    offset += sizeof(dexHeader->methodIdsSize);
    memcpy(&(dexHeader->methodIdsOff), dexfptr + offset, sizeof(dexHeader->methodIdsOff));
    offset += sizeof(dexHeader->methodIdsOff);
  
    memcpy(&(dexHeader->classDefsSize), dexfptr + offset, sizeof(dexHeader->classDefsSize));
    offset += sizeof(dexHeader->classDefsSize);
    memcpy(&(dexHeader->classDefsOff), dexfptr + offset, sizeof(dexHeader->classDefsOff));
    offset += sizeof(dexHeader->classDefsOff);
    memcpy(&(dexHeader->dataSize), dexfptr + offset, sizeof(dexHeader->dataSize));
    offset += sizeof(dexHeader->dataSize);
    memcpy(&(dexHeader->dataOff), dexfptr + offset, sizeof(dexHeader->dataOff));
    offset += sizeof(dexHeader->dataOff);
  
    return dexHeader->headerSize;
}

void loadDexStringId(u1* dexfptr, long offset, struct DexStringId* ids, int size) {
    for (int i = 0; i < size; i++) {
        memcpy(&((ids + i)->stringDataOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}

void loadDexTypeId(u1* dexfptr, long offset, struct DexTypeId* ids, int size) {
    for (int i = 0; i < size; i++) {
        memcpy(&((ids + i)->descriptorIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}

void loadDexProtoId(u1* dexfptr, long offset, struct DexProtoId* ids, int size) {
    for (int i = 0; i < size; i++) {
        memcpy(&((ids + i)->shortyIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        memcpy(&((ids + i)->returnTypeIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        memcpy(&((ids + i)->parametersOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}


void loadDexFieldId(u1* dexfptr, long offset, struct DexFieldId* ids, int size) {

    for (int i = 0; i < size; i++) {
        memcpy(&((ids + i)->classIdx), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&((ids + i)->typeIdx), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&((ids + i)->nameIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}

void loadDexMethodId(u1* dexfptr, long offset, struct DexMethodId* ids, int size) {
    for (int i = 0; i < size; i++) {
        memcpy(&((ids + i)->classIdx), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&((ids + i)->protoIdx), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&((ids + i)->nameIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}

void loadDexClassDef(u1* dexfptr, long offset, struct DexClassDef* ids, int size) {

    for (int i = 0; i < size; i++) {
        
        memcpy(&((ids + i)->classIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->accessFlags), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->superclassIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->interfacesOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->sourceFileIdx), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->annotationsOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->classDataOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&((ids + i)->staticValuesOff), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
    
}

void loadDexTypeList(u1* dexfptr, long offset, struct DexTypeList* typelist) {
    memcpy(&typelist->size, dexfptr + offset, sizeof(u4));
    offset += sizeof(u4);
    memcpy(typelist->list, dexfptr + offset, sizeof(u2));
}

void loadMap(u1* dexfptr, long offset, struct DexMapList* list) {
    memcpy(&list->size, dexfptr + offset, sizeof(u4));
    offset += sizeof(u4);
    for (int i = 0; i < list->size; i++) {
        memcpy(&(list->list[i].type), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        memcpy(&(list->list[i].unused), dexfptr + offset, sizeof(u2));
        offset += sizeof(u2);
        memcpy(&(list->list[i].size), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
        memcpy(&(list->list[i].offset), dexfptr + offset, sizeof(u4));
        offset += sizeof(u4);
    }
}

const char* accessIntValueOfString(int v) {
    switch (v) {
        case ACC_PUBLIC:
            return "public";
        case ACC_PRIVATE:
            return "private";
        case ACC_PROTECTED:
            return "protected";
        case ACC_STATIC:
            return "static";
        case ACC_FINAL:
            return "final";
        case ACC_SYNCHRONIZED:
            return "synchronized or super";
        case ACC_VOLATILE:
            return "volaile";
        default:
            return "other";
    }
}


/*

 211    kDexTypeClassDefItem             = 0x0006,
 212    kDexTypeMapList                  = 0x1000,
 213    kDexTypeTypeList                 = 0x1001,
 214    kDexTypeAnnotationSetRefList     = 0x1002,
 215    kDexTypeAnnotationSetItem        = 0x1003,
 216    kDexTypeClassDataItem            = 0x2000,
 217    kDexTypeCodeItem                 = 0x2001,
 218    kDexTypeStringDataItem           = 0x2002,
 219    kDexTypeDebugInfoItem            = 0x2003,
 220    kDexTypeAnnotationItem           = 0x2004,
 221    kDexTypeEncodedArrayItem         = 0x2005,
 222    kDexTypeAnnotationsDirectoryItem = 0x2006,
 223};
 */
const char* dexMapItemToString(int v) {
    switch (v) {
        case kDexTypeHeaderItem:
            return "kDexTypeHeaderItem";
        case kDexTypeStringIdItem:
            return "kDexTypeStringIdItem";
        case kDexTypeTypeIdItem:
            return "kDexTypeTypeIdItem";
        case kDexTypeProtoIdItem:
            return "kDexTypeProtoIdItem";
        case kDexTypeFieldIdItem:
            return "kDexTypeFieldIdItem";
        case kDexTypeMethodIdItem:
            return "kDexTypeMethodIdItem";
        case kDexTypeClassDefItem:
            return "kDexTypeClassDefItem";
        case kDexTypeMapList:
            return "kDexTypeMapList";
        case kDexTypeTypeList:
            return "kDexTypeTypeList";
        case kDexTypeAnnotationSetRefList:
            return "kDexTypeAnnotationSetRefList";
        case kDexTypeAnnotationSetItem:
            return "kDexTypeAnnotationSetItem";
        case kDexTypeClassDataItem:
            return "kDexTypeClassDataItem";
        case kDexTypeCodeItem:
            return "kDexTypeCodeItem";
        case kDexTypeStringDataItem:
            return "kDexTypeStringDataItem";
        case kDexTypeDebugInfoItem:
            return "kDexTypeDebugInfoItem";
        case kDexTypeAnnotationItem:
            return "kDexTypeAnnotationItem";
        case kDexTypeEncodedArrayItem:
            return "kDexTypeEncodedArrayItem";
        case kDexTypeAnnotationsDirectoryItem:
            return "kDexTypeAnnotationsDirectoryItem";
        default:
            return "other";
    }
}

void loadDexCode(u1* dexfpter, long offset, struct DexCode* dexCode, int size) {
    for (int i = 0; i < size; i++) {
        memcpy(&dexCode[i].registersSize, dexfpter + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&dexCode[i].insns, dexfpter + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&dexCode[i].outsSize, dexfpter + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&dexCode[i].triesSize, dexfpter + offset, sizeof(u2));
        offset += sizeof(u2);
        
        memcpy(&dexCode[i].debugInfoOff, dexfpter + offset, sizeof(u4));
        offset += sizeof(u4);
        
        memcpy(&dexCode[i].insnsSize, dexfpter + offset, sizeof(u4));
        offset += sizeof(u4);
        
        for (int j = 0; j < dexCode->insnsSize; j++) {
            memcpy(&(dexCode[i].insns[j]), dexfpter + offset, sizeof(u2));
            offset += sizeof(u2);
        }
        
    }
}

//
//  main.cpp
//  DexParser
//
//  Created by Nop on 2020/9/19.
//

#include 
#include "dexParser.hpp"

#define classes_dex "/Users/zhouliqun/Desktop/MyClass.dex"

int main(int argc, const char * argv[]) {
    FILE* fptr = fopen(classes_dex, "r+");
    if (fptr == nullptr) {
        printf("Open %s error: %s.\n", argv[1], strerror(errno));
        return 1;
    }
    
    fseek(fptr, 0, SEEK_END);
    long length  = ftell(fptr);
    fseek(fptr, 0, SEEK_SET);
    
    u1 dexData[length];
    fread(dexData, sizeof(u1), length, fptr);
    
    fclose(fptr);
    fptr = nullptr;
    

    struct DexHeader dexHeader;
    getDexHeader(dexData, &dexHeader);

    struct DexMapList mapList;
    loadMap(dexData, dexHeader.mapOff, &mapList);
       
    printf("\nDexMapList: DexMapList.size %d, mapOff %d\n", mapList.size, dexHeader.mapOff);
       

    for (int i = 0; i < mapList.size; i++) {
        printf("DexMapItem: type %s, unused %d, size %d, offset %d\n",
                dexMapItemToString(mapList.list[i].type),
                mapList.list[i].unused,
                mapList.list[i].size,
                mapList.list[i].offset);
        
        if (mapList.list[i].type == kDexTypeCodeItem) {
            DexCode dexCode[mapList.list[i].size];
            loadDexCode(dexData, mapList.list[i].offset, dexCode, mapList.list[i].size);
            
            for (int j = 0; j < mapList.list[i].size; j++) {
                printf("DexCode: registersSize=%d, insSize=%d, outsSize=%d, triesSize=%d, debugInfoOff=%d, insnsSize=%d\n",
                       dexCode[j].registersSize, dexCode[j].insSize, dexCode[j].outsSize, dexCode[j].triesSize, dexCode[j].debugInfoOff, dexCode[j].insnsSize);
                
                for (int n = 0 ; n < dexCode[j].insnsSize; n++) {
                    // 指令
                }
            }
            
        }
    }
    
    struct DexStringId strIds[dexHeader.stringIdsSize];
    loadDexStringId(dexData, dexHeader.stringIdsOff, strIds, dexHeader.stringIdsSize);

    printf("\nDexStringId: stringIdsSize %d, stringIdsOff %d\n", dexHeader.stringIdsSize, dexHeader.stringIdsOff);
    
    u1 stringList[dexHeader.stringIdsSize][128];
    
    // 字符串在data区的偏移
    for (int i = 0; i < dexHeader.stringIdsSize; i++) {
        u1 len = dexData[strIds[i].stringDataOff];
        u1 strDst[128];
        memset(strDst, 0, 128);
        memcpy(strDst, &dexData[strIds[i].stringDataOff + 1], len + 1);
        printf("String: %02d %s\n", len, strDst);

        memset(stringList[i], 0, 128);
        memcpy(stringList[i], strDst, len);
    }
    
    struct DexTypeId typeIds[dexHeader.typeIdsSize];
    loadDexTypeId(dexData, dexHeader.typeIdsOff, typeIds, dexHeader.typeIdsSize);
    
    printf("\nDexTypeId: typeIdsSize %d, typeIdsOff %d\n", dexHeader.typeIdsSize, dexHeader.typeIdsOff);
    
    u4 typeids[dexHeader.typeIdsSize];
    // 为类型描述符索引到stringIds列表
    for (int i = 0; i < dexHeader.typeIdsSize; i++) {
        printf("descriptorIdx %d %s\n", (typeIds+i)->descriptorIdx, stringList[(typeIds+i)->descriptorIdx]);
        
        typeids[i] = (typeIds+i)->descriptorIdx;
    }
    
    
    struct DexProtoId protoIds[dexHeader.protoIdsSize];
    loadDexProtoId(dexData, dexHeader.protoIdsOff, protoIds, dexHeader.protoIdsSize);
    
    printf("\nDexProtoId: protoIdsSize %d, protoIdsOff %d\n", dexHeader.protoIdsSize, dexHeader.protoIdsOff);
    
    for (int i = 0; i < dexHeader.protoIdsSize; i++) {
        
        printf("DexProtoId shortyIdx %d %s \n", (protoIds+i)->shortyIdx, stringList[(protoIds+i)->shortyIdx]);
        //parameter types
        if ((protoIds+i)->parametersOff == 0) {
            printf("shorty descriptor %s, return type: %s, parameters size %d %s\n",
                   stringList[(protoIds+i)->shortyIdx],
                   stringList[typeids[(protoIds+i)->returnTypeIdx]],
                   0,
                   "null");
        } else {
            DexTypeList typeList;
            loadDexTypeList(dexData,  (protoIds+i)->parametersOff, &typeList);
            
            printf("shorty descriptor %s, return type: %s, parameters size %d %s\n",
                   stringList[(protoIds+i)->shortyIdx],
                   stringList[typeids[(protoIds+i)->returnTypeIdx]],
                   typeList.size,
                   stringList[typeids[typeList.list[0].typeIdx]]);
        }
    }
    
    struct DexFieldId fieldIds[dexHeader.fieldIdsSize];
    loadDexFieldId(dexData, dexHeader.fieldIdsOff, fieldIds, dexHeader.fieldIdsSize);
    
    printf("\nDexFieldId: fieldIdsSize %d, fieldIdsOff %d\n", dexHeader.fieldIdsSize, dexHeader.fieldIdsOff);
    
    for (int i = 0; i < dexHeader.fieldIdsSize; i++) {
        printf("DexFieldId{%s, %s, %s}\n", stringList[typeids[(fieldIds+i)->classIdx]],
               stringList[typeids[(fieldIds+i)->typeIdx]],
               stringList[(fieldIds+i)->nameIdx]);
    }
    
    struct DexMethodId methodIds[dexHeader.methodIdsSize];
    loadDexMethodId(dexData, dexHeader.methodIdsOff, methodIds, dexHeader.methodIdsSize);
    
    printf("\nDexMethodId: methodIdsSize %d, methodIdsOff %d\n", dexHeader.methodIdsSize, dexHeader.methodIdsOff);
    
    for (int i = 0; i < dexHeader.methodIdsSize; i++) {
        printf("DexMethodId{%s, %d, %s}\n",
               stringList[typeids[(methodIds+i)->classIdx]],
               (methodIds+i)->protoIdx,
               stringList[(methodIds+i)->nameIdx]);
    }
    
    struct DexClassDef classDef[dexHeader.classDefsSize];
    loadDexClassDef(dexData, dexHeader.classDefsOff, classDef, dexHeader.classDefsSize);
    
    printf("\nDexClassDef: classDefsSize %d, classDefsOff %d\n", dexHeader.classDefsSize, dexHeader.classDefsOff);
    
    for (int i = 0; i < dexHeader.classDefsSize; i++) {
        printf("DexClassDef{%s, %s, %s, %d, %s, %d, %d, %d}\n",
               stringList[typeids[(classDef+i)->classIdx]],
               accessIntValueOfString((classDef+i)->accessFlags),
               stringList[typeids[(classDef+i)->superclassIdx]],
               (classDef+i)->interfacesOff,
               stringList[(classDef+i)->sourceFileIdx],
               (classDef+i)->annotationsOff,
               (classDef+i)->classDataOff,
               (classDef+i)->staticValuesOff
               );
        
        struct DexClassData classData;
        int off = (classDef+i)->classDataOff;
        memcpy(&classData.header.staticFieldsSize, dexData + off, sizeof(u4));
        off += sizeof(u4);
        
        memcpy(&classData.header.instanceFieldsSize, dexData + off, sizeof(u4));
        off += sizeof(u4);
        
        memcpy(&classData.header.directMethodsSize, dexData + off, sizeof(u4));
        off += sizeof(u4);
        
        memcpy(&classData.header.virtualMethodsSize, dexData + off, sizeof(u4));
        off += sizeof(u4);
        
        for (int n = 0; n < classData.header.staticFieldsSize; n++) {
            memcpy(&(classData.staticFields + n)->fieldIdx, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.staticFields + n)->accessFlags, dexData + off, sizeof(u4));
            off += sizeof(u4);
        }
        
        for (int n = 0; n < classData.header.instanceFieldsSize; n++) {
            memcpy(&(classData.instanceFields + n)->fieldIdx, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.instanceFields + n)->accessFlags, dexData + off, sizeof(u4));
            off += sizeof(u4);
        }
        
        for (int n = 0; n < classData.header.directMethodsSize; n++) {
            memcpy(&(classData.directMethods + n)->methodIdx, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.directMethods + n)->accessFlags, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.directMethods + n)->codeOff, dexData + off, sizeof(u4));
            off += sizeof(u4);
        }
        
        for (int n = 0; n < classData.header.virtualMethodsSize; n++) {
            memcpy(&(classData.virtualMethods + n)->methodIdx, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.virtualMethods + n)->accessFlags, dexData + off, sizeof(u4));
            off += sizeof(u4);
            
            memcpy(&(classData.virtualMethods + n)->codeOff, dexData + off, sizeof(u4));
            off += sizeof(u4);
        }
        
    }
    
   
    return 0;
}



你可能感兴趣的:(2020-09-20 手动解析dex文件)