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

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

#ifndef DexFile_hpp
#define DexFile_hpp

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

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 <stdio.h>
#include <errno.h>
#include <string.h>
#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 <iostream>
#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;
}



?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352