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