首页
社区
课程
招聘
010 Editor 模板解析dex文件格式
2016-3-23 23:21 19613

010 Editor 模板解析dex文件格式

2016-3-23 23:21
19613
在学习<<Android软件安全与逆向分析>>中的dex文件格式时写的基于010 Editor的模板,算是重新温习了一下010模板编写,希望刚接触android的可以"可视化方式"来学习DEX文件格式

模板的使用方法:

1.将下面的代码复制并保存到文本文件,文件后缀名可以是任意或默认的*.bt后缀。

2.菜单栏—>模板—>打开模板,选择保存的文本文件,按F5运行模板。


一、010文件格式模板缺点:

1.语法类似于伪C代码不能使用指针和new/delete/malloc/free等C/c++运行库。

2.目前不支持调试,仅支持打印日志。

3.对打印日志支持不够完美,例如:struct {int xxx}aaa<read=ReadEventFunc,read=WriteEnentFunc>; 对于读写结构事件回调函数中不能声明结构体和使用Print函数打印日志。

二、010文件格式模板介绍:

1).虽然010模板采用了类似伪C语法,学习前建议大概浏览一下帮助文档(010 界面按F1)。
2).基本类型:
8-Bit Signed Integer – char, byte, CHAR, BYTE

8-Bit Unsigned Integer – uchar, ubyte, UCHAR, UBYTE

16-Bit Signed Integer – short, int16, SHORT, INT16

16-Bit Unsigned Integer – ushort, uint16, USHORT, UINT16, WORD

32-Bit Signed Integer – int, int32, long, INT, INT32, LONG

32-Bit Unsigned Integer – uint, uint32, ulong, UINT, UINT32, ULONG, DWORD

64-Bit Signed Integer – int64, quad, QUAD, INT64, __int64

64-Bit Unsigned Integer – uint64, uquad, UQUAD, UINT64, QWORD, __uint64

32-Bit Floating Point Number – float, FLOAT

64-Bit Floating Point Number – double, DOUBLE

string type: string, wstring

3).特有的数据结构:
Date Types – DOSDATE, DOSTIME, FILETIME, OLETIME, time_t (for more information on date types, see Using the Inspector)

声明和使用几乎和C语言没有什么区别,char var[8]和string var长度相同情况下几乎是相等的,能相互赋值.

4).结构类型:
enum能指定枚举成员长度byte/word/dword/float…..等基本类型长度,在解析文件时是非常非常有用的。
enum MYENUM 
{ 
   COMP_1,
   COMP_2 = 5, 
   COMP_3 
} var1;

//enum指定成员数据长度
enum <ushort> MYENUM 
{ 
   COMP_1, 
   COMP_2 = 5, 
   COMP_3 
} var1;


struct基本和C语言一致:
typedef struct
{
  int xxx;
}strVar;

struct
{
  int xxx;
}strVar;


5).属性:
这里的属性可以针对整个结构或结构成员,关于结构读/写事件回调注意的地方请参考010缺点章节.
< format=hex|decimal|octal|binary, //按?进制显示
fgcolor=<color>, //前景色
bgcolor=<color>, //背景色
comment=”<string>”, //注释
open=true|false|suppress,
hidden=true|false,
read=<function_name>, //读取数据结构体回调,(仅用于结构变量, 回调原型参数是跟据结构类型来决定,string ReadCallback(structType &structVar);)
write=<function_name> >//hex编辑窗口写入数据回调(仅用于结构变量, 回调原型参数是跟据结构类型来决定, void WriteCallback(structType &structVar, string hexEditData);)

6).当文件的数据结构被定义时
结构成员以变量名来命名,逐个从第一个成员开始读取,每读取一个成员文件蕴含的文件指针将被自动增加,增加的步长以数据类型长度为基准,读取完毕之后调用读取回调函数,回调函数执行完毕之后返回模板的值
//**************被定义的数据结构**************
typedef struct
{
   int myInt;
   short myShort;
   char myCharArray[6];
}MyStruct<read=ReadCallback,write=WriteCallback>;

//**************回调函数**************
//当MyStruct结构被定义时(实例化时:使用结构MyStruct myVar),ReadCallback将被调用,参数为读取该结构的引用.
string ReadCallback(MyStruct &myStruct)
{
   local string value = “value”;
   return value;  //返回值见下图,返回给检查器的值列的
}


当一个数据结构设置读回调时,模板可以有返回值并显示在"值“列


7).文件指针

在模板执行中会蕴含一个文件指针,刚执行模板时默认文件指针偏移0当结构模板被定义后变量值默认为全局,局部变量可以加local 前缀定义。

8).010模板和脚本函数库:
函数库可以适当查看帮助文档,在此列出函数库类型:
Interface Functions : 包含了书签、剪贴板、文件信息获取、结构成员的属性设置等杂类函数
I/O Functions : 大小尾设置、文件读/写、文件指针等等
String Functions : 字符串比较、复制、转换等
Math Functions : 数学计算相关的函数
Tool Functions : 范围内的数据HASH计算

DEX文件格式解析脚本:

以下脚本在010 Editor v3.1.3测试通过,其中DEX中的数据结构部分来自Android源码。

//--------------------------------------
//--- 010 Editor v3.1.3 Binary Template
//
// File:
// Author:
// Revision:
// Purpose:
//--------------------------------------
//configure
local byte bShow_DexTypeList = 0;

//enum
enum { kSHA1DigestLen = 20,
       kSHA1DigestOutputLen = kSHA1DigestLen*2 +1 };
/*
 * access flags and masks; the "standard" ones are all <= 0x4000
 *
 * Note: There are related declarations in vm/oo/Object.h in the ClassFlags
 * enum.
 */
enum <uint> AccessFlags{
    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),
};

//Dex Header
struct DexHeader {
    unsigned char  magic[8];           /* includes version number */
    unsigned int   checksum;           /* adler32 checksum */
    unsigned char  signature[kSHA1DigestLen]; /* SHA-1 hash */
    unsigned int   fileSize;           /* length of entire file */
    unsigned int   headerSize;         /* offset to start of next section */
    unsigned int   endianTag;
    unsigned int   linkSize;
    unsigned int   linkOff;
    unsigned int   mapOff;
    unsigned int   stringIdsSize;
    unsigned int   stringIdsOff;
    unsigned int   typeIdsSize;
    unsigned int   typeIdsOff;
    unsigned int   protoIdsSize;
    unsigned int   protoIdsOff;
    unsigned int   fieldIdsSize;
    unsigned int   fieldIdsOff;
    unsigned int   methodIdsSize;
    unsigned int   methodIdsOff;
    unsigned int   classDefsSize;
    unsigned int   classDefsOff;
    unsigned int   dataSize;
    unsigned int   dataOff;
};

//******************** map list*******************

/* map item type codes, DexMapItem.type used*/
//DexHeader.mapOff  ---> pointer to data struct
enum <ushort> kDexType{
    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 DexMapItem {
    kDexType type;              /* type code (see kDexType* above) */
    ushort  unused;
    uint    size<format=decimal>;              /* count of items of the indicated type */
    uint    offset;            /* file offset to the start of data */
};

struct DexMapList 
{
    uint size<format=decimal>;               /* #of entries in list */    
    //ref field DexMapList.size
    DexMapItem list[size];   /* entries */ 
};

//********************strings index table********************
/*
 * Direct-mapped "string_id_item".
 */
typedef struct 
{
    uint stringDataOff;      /* file offset to string_data_item */
}DexStringId<read=TemplateRead_StringId>;

//********************types index table********************
/*
 * Direct-mapped "type_id_item".
 */
typedef struct
{
    uint  descriptorIdx;      /* index into stringIds list for type descriptor */
}DexTypeId<read=TemplateRead_TypeId>;

//********************protos index table********************

/*
 * Direct-mapped "type_item".
 */
struct DexTypeItem {
    ushort  typeIdx;            /* index into typeIds */
};

/*
 * Direct-mapped "type_list".
 */
typedef struct  {
    uint  size;               /* #of entries in list */
    DexTypeItem list[size];    /* entries */
}DexTypeList<read=TemplateRead_TypeList>;

/*
 * Direct-mapped "proto_id_item".
 */
typedef struct  
{
    uint  shortyIdx;          /* index into stringIds for shorty descriptor */
    uint  returnTypeIdx;      /* index into typeIds list for return type */
    uint  parametersOff;      /* file offset to type_list for parameter types */  
    if(parametersOff > 0x70)
    {
        local int64 oldOffset = FTell();  
        FSeek(parametersOff);    
        DexTypeList typeList_Params;
        FSeek(oldOffset);  
    }         
}DexProtoId<read=TemplateRead_ProtoId>;


//********************field index table********************
/*
 * Direct-mapped "field_id_item".
 */
typedef struct  {
    ushort  classIdx;           /* index into typeIds list for defining class */
    ushort  typeIdx;            /* index into typeIds for field type */
    uint  nameIdx;            /* index into stringIds for field name */
}DexFieldId<read=TemplateRead_FieldId>;

//********************method index table********************
/*
 * Direct-mapped "method_id_item".
 */
typedef struct  {
    ushort  classIdx;           /* index into typeIds list for defining class */
    ushort  protoIdx;           /* index into protoIds for method prototype */
    uint  nameIdx;            /* index into stringIds for method name */
}DexMethodId<read=TemplateRead_MethodId>;

//********************Class Define table********************

/* expanded form of a class_data_item header */
struct DexClassDataHeader {
    local int64 oldOffset = FTell();
    local int64 currOffset = oldOffset;  
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    local int len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte staticFieldsSize<comment="uleb128 staticFieldsSize">; break;
        case 2: ushort staticFieldsSize<comment="uleb128 staticFieldsSize">; break;
        case 3: ubyte staticFieldsSize[3]<comment="uleb128 staticFieldsSize">; break;
        case 4: uint staticFieldsSize<comment="uleb128 staticFieldsSize">; break;
        case 5: ubyte staticFieldsSize[5]<comment="uleb128 staticFieldsSize">; break;
    }    
    
    oldOffset = FTell();
    currOffset = oldOffset; 
    //Printf("*******************************\n");
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte instanceFieldsSize<comment="uleb128 instanceFieldsSize">; break;
        case 2: ushort instanceFieldsSize<comment="uleb128 instanceFieldsSize">; break;
        case 3: ubyte instanceFieldsSize[3]<comment="uleb128 instanceFieldsSize">; break;
        case 4: uint instanceFieldsSize<comment="uleb128 instanceFieldsSize">; break;
        case 5: ubyte instanceFieldsSize[5]<comment="uleb128 instanceFieldsSize">; break;
    }        


    oldOffset = FTell();
    currOffset = oldOffset; 
    //Printf("*******************************\n");
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte directMethodsSize<comment="uleb128 directMethodsSize">; break;
        case 2: ushort directMethodsSize<comment="uleb128 directMethodsSize">; break;
        case 3: ubyte directMethodsSize[3]<comment="uleb128 directMethodsSize">; break;
        case 4: uint directMethodsSize<comment="uleb128 directMethodsSize">; break;
        case 5: ubyte directMethodsSize[5]<comment="uleb128 directMethodsSize">; break;
    }        
    
    oldOffset = FTell();
    currOffset = oldOffset; 
    //Printf("*******************************\n");
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset);
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte virtualMethodsSize<comment="uleb128 virtualMethodsSize">; break;
        case 2: ushort virtualMethodsSize<comment="uleb128 virtualMethodsSize">; break;
        case 3: ubyte virtualMethodsSize[3]<comment="uleb128 virtualMethodsSize">; break;
        case 4: uint virtualMethodsSize<comment="uleb128 virtualMethodsSize">; break;
        case 5: ubyte virtualMethodsSize[5]<comment="uleb128 virtualMethodsSize">; break;
    }            
};

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

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

/* 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. */
struct DexClassData {
    DexClassDataHeader header;

    local int64 oldOffset = FTell();
    local int64 currOffset = oldOffset;  
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    local int len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte staticFields<comment="uleb128 staticFields">; break;
        case 2: ushort staticFields<comment="uleb128 staticFields">; break;
        case 3: ubyte staticFields[3]<comment="uleb128 staticFields">; break;
        case 4: uint staticFields<comment="uleb128 staticFields">; break;
        case 5: ubyte staticFields[5]<comment="uleb128 staticFields">; break;
    }

    oldOffset = FTell();
    currOffset = oldOffset;  
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte instanceFields<comment="uleb128 instanceFields">; break;
        case 2: ushort instanceFields<comment="uleb128 instanceFields">; break;
        case 3: ubyte instanceFields[3]<comment="uleb128 instanceFields">; break;
        case 4: uint instanceFields<comment="uleb128 instanceFields">; break;
        case 5: ubyte instanceFields[5]<comment="uleb128 instanceFields">; break;
    }

    oldOffset = FTell();
    currOffset = oldOffset;  
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte directMethods<comment="uleb128 directMethods">; break;
        case 2: ushort directMethods<comment="uleb128 directMethods">; break;
        case 3: ubyte directMethods[3]<comment="uleb128 directMethods">; break;
        case 4: uint directMethods<comment="uleb128 directMethods">; break;
        case 5: ubyte directMethods[5]<comment="uleb128 directMethods">; break;
    }
    
    oldOffset = FTell();
    currOffset = oldOffset;  
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x\n",currOffset);   
    len = readUnsignedLeb128(currOffset); 
    //Printf("oldOffset=%x,",oldOffset);
    //Printf("currOffset=%x,",currOffset);
    //Printf("field size:%x,",currOffset - oldOffset);
    //Printf("size:%x\n",len);
    switch(currOffset - oldOffset)
    {
        case 1: ubyte virtualMethods<comment="uleb128 virtualMethods">; break;
        case 2: ushort virtualMethods<comment="uleb128 virtualMethods">; break;
        case 3: ubyte virtualMethods[3]<comment="uleb128 virtualMethods">; break;
        case 4: uint virtualMethods<comment="uleb128 virtualMethods">; break;
        case 5: ubyte virtualMethods[5]<comment="uleb128 virtualMethods">; break;
    }    
    //DexField*          staticFields;   
    //DexField*          instanceFields;
    //DexMethod*         directMethods;
    //DexMethod*         virtualMethods;
};

/*
 * Direct-mapped "class_def_item".
 */
typedef struct  {
    uint  classIdx;           /* index into typeIds for this class */
    AccessFlags  accessFlags;
    uint  superclassIdx;      /* index into typeIds for superclass */
    uint  interfacesOff;      /* file offset to DexTypeList */
    if(interfacesOff > 0 && interfacesOff != 0xFFFFFFFF)
    {
        local int64 oldOffset = FTell();  
        FSeek(interfacesOff);    
        DexTypeList typeList_Interfaces;
        FSeek(oldOffset);  
    }
    uint  sourceFileIdx;      /* index into stringIds for source file name */
    uint  annotationsOff;     /* file offset to annotations_directory_item */
    uint  classDataOff;       /* file offset to class_data_item */
    if(classDataOff > 0 && classDataOff != 0xFFFFFFFF)
    {
        local int64 oldOff = FTell();  
        FSeek(classDataOff);    
        DexClassData dexClassData;
        FSeek(oldOff);
    }
    uint  staticValuesOff;    /* file offset to DexEncodedArray */
    if(staticValuesOff > 0)
    {
        local int64 offset = FTell();  
        FSeek(staticValuesOff);    
        //
        FSeek(offset);
    }
}DexClassDef<read=TemplateRead_ClassDefs>;

/*
 * Direct-mapped "annotations_directory_item".
 */
struct DexAnnotationsDirectoryItem {
    uint  classAnnotationsOff;  /* offset to DexAnnotationSetItem */
    uint  fieldsSize;           /* count of DexFieldAnnotationsItem */
    uint  methodsSize;          /* count of DexMethodAnnotationsItem */
    uint  parametersSize;       /* count of DexParameterAnnotationsItem */
    /* followed by DexFieldAnnotationsItem[fieldsSize] */
    /* followed by DexMethodAnnotationsItem[methodsSize] */
    /* followed by DexParameterAnnotationsItem[parametersSize] */
};

void Dump_DexHeader(int64 startOffset)
{    
    local int64 oldOffset = FTell();
    FSeek(startOffset);
    DexHeader dexHdr;
    FSeek(oldOffset);

    Printf("file size: 0x%x\n", dexHdr.fileSize);
    Printf("file header size: 0x%x\n", dexHdr.headerSize);
    Printf("strings count: %d\n", dexHdr.stringIdsSize);
    Printf("types count: %d\n", dexHdr.typeIdsSize);
    Printf("proto count: %d\n", dexHdr.protoIdsSize);
    Printf("fields count: %d\n", dexHdr.fieldIdsSize);
    Printf("methods count: %d\n", dexHdr.methodIdsSize);
    Printf("classDefs count: %d\n", dexHdr.classDefsSize);
    Printf("data size count: %d\n", dexHdr.dataSize);
    Printf("mapOff: 0x%x\n", dexHdr.mapOff);
}

void Dump_MapList(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);
    DexMapList mapList;
    FSeek(oldOffset);   
}


void Dump_StringItems(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);
    DexStringId dexStringId[dexHdr.stringIdsSize];
    FSeek(oldOffset);   
}

void Dump_TypeItems(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);
    DexTypeId dexTypeId[dexHdr.typeIdsSize];
    FSeek(oldOffset);   
}

void Dump_ProtoItems(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);
    DexProtoId dexProtoId[dexHdr.protoIdsSize]<optimize=true>;    

    FSeek(oldOffset);
}

void Dump_FieldItems(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);   
    DexFieldId dexFieldId[dexHdr.fieldIdsSize];
    FSeek(oldOffset);
}

void Dump_MethodItems(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);   
    DexMethodId dexMethodId[dexHdr.methodIdsSize];
    FSeek(oldOffset);
}

void Dump_ClassDef(int64 startOffset)
{
    local int64 oldOffset = FTell();
    FSeek(startOffset);   
    DexClassDef dexClassDef[dexHdr.classDefsSize]<optimize=false>;
    FSeek(oldOffset);
}

int readUnsignedLeb128(int64 &streamPos) 
{    
    local int result = ReadUByte(streamPos);// read first byte
  streamPos++;
  
    if (result > 0x7f) 
  {
        local int cur = ReadUByte(streamPos);	//read second byte
    streamPos++;
        result = (result & 0x7f) | ((cur & 0x7f) << 7);
        if (cur > 0x7f) 
    {
            cur = ReadUByte(streamPos);		//read third byte
      streamPos++;
            result |= (cur & 0x7f) << 14;
            if (cur > 0x7f) 
      {
                cur = ReadUByte(streamPos);	//read fourth byte
        streamPos++;
                result |= (cur & 0x7f) << 21;
                if (cur > 0x7f) 
        {
                    /*
                     * Note: We don't check to see if cur is out of
                     * range here, meaning we tolerate garbage in the
                     * high four-order bits.
                     */
                    cur = ReadUByte(streamPos);	//read fifth byte
          streamPos++;
                    result |= cur << 28;
                }
            }
        }
    }
    
    return result;
}

//display checker value
string TemplateRead_StringId(DexStringId &stringId)
{    
    local string str = "";
    local int64 offset = stringId.stringDataOff;
    local int strLen = readUnsignedLeb128(offset); //--->>>Warning,only pause one string
    str = ReadString(offset);  
    
    return str;
}

string TemplateRead_TypeId(DexTypeId &typeId )
{    
    local string str = "";
    local int64 offset = dexStringId[typeId.descriptorIdx].stringDataOff;
    local int strLen = readUnsignedLeb128(offset);
    str = ReadString(offset);
    str = TemplateRead_StringId(dexStringId[typeId.descriptorIdx]);
    return str;
}

string TemplateRead_ProtoId(DexProtoId &protoId )
{    
    local int64 oldOffset = FTell();   
    local string str = "";
    local int i = 0, count = 0;
    local short typeIdx = -1;
    
    if(protoId.parametersOff > 0)
    {
        local string method = TemplateRead_StringId(dexStringId[protoId.shortyIdx]);
        local string retType = TemplateRead_TypeId(dexTypeId[protoId.returnTypeIdx]);
        local string params = "";

        count = ReadInt(protoId.parametersOff);
        while(i < count)
        {
            typeIdx = ReadShort(protoId.parametersOff + sizeof(int) +
                            i * sizeof(short));
            params += TemplateRead_TypeId(dexTypeId[typeIdx]);
            i++;
            
            //function args delimiter 
            //if(i < count)
                //params += " , ";
        }       
        
        //join: return + method + args
        SPrintf(str, "<%s%s(%s)>",retType, method, params);
    }    
    
    FSeek(oldOffset);
    return str;
}

string TemplateRead_FieldId(DexFieldId &fieldId)
{
    local string classTypeName = "";
    local string fieldTypeName = "";
    local string fieldName = "";
    local string result = "";

    classTypeName = TemplateRead_TypeId(dexTypeId[fieldId.classIdx]);
    fieldTypeName = TemplateRead_TypeId(dexTypeId[fieldId.typeIdx]);
    fieldName = TemplateRead_StringId(dexStringId[fieldId.nameIdx]);
    result = classTypeName + "@" + fieldTypeName + "@" + fieldName;

    return result;
}

string TemplateRead_MethodId(DexMethodId &methodId)
{
    local string result = "";
    local string classTypeName = "";
    local string protoTypeName = "";
    local string methodName = "";
    
    classTypeName = TemplateRead_TypeId(dexTypeId[methodId.classIdx]);
    protoTypeName = TemplateRead_ProtoId(dexProtoId[methodId.protoIdx]);
    methodName = TemplateRead_StringId(dexStringId[methodId.nameIdx]);
    result = classTypeName + "@" + protoTypeName + "@" + methodName;

    return result;
}

string TemplateRead_ClassDefs(DexClassDef &classDef)
{
    local string result = "";
    local string classTypeName = "";
    local string superClassTypeName = "";
    local string protoTypeName = "";
    local string methodName = "";
    
    

    return result;
}

string TemplateRead_TypeList(DexTypeList &typeList)
{
    local string result = "", temp = "";
    //local int i = 0;
    //local int len = typeList.size;
    //while(i < len)
    //{
        //SPrintf(temp, "%d,", typeList.list[i].typeIdx);
        //typeList.list[i].typeIdx;
        //dexTypeId[typeList.list[i].typeIdx];
        //result += TemplateRead_TypeId(dexTypeId[typeList.list[i].typeIdx]);
        
        //SPrintf(temp, "index=%d,", i);
        //result += temp;
       // i++;
    //}
    //SPrintf(result, "size=%d", typeList.size);
    return result;
}
//-------------------------->>>   start running   <<<--------------------------
Dump_DexHeader(0);
Dump_MapList(dexHdr.mapOff);
Dump_StringItems(dexHdr.stringIdsOff);
Dump_TypeItems(dexHdr.typeIdsOff);
Dump_ProtoItems(dexHdr.protoIdsOff);
Dump_FieldItems(dexHdr.fieldIdsOff);
Dump_MethodItems(dexHdr.methodIdsOff);
Dump_ClassDef(dexHdr.classDefsOff);

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (12)
雪    币: 466
活跃值: (3527)
能力值: ( LV5,RANK:69 )
在线值:
发帖
回帖
粉丝
小菜鸟一 2016-3-24 08:55
2
0
感谢   测试成功
雪    币: 341
活跃值: (133)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 2 2016-3-24 11:08
3
0
厉害 谢谢分享出来
雪    币: 33
活跃值: (244)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
fishleong 2016-3-24 22:34
4
0
这个模板不错。。。。。
雪    币: 211
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
binlanone 2016-3-25 08:46
5
0
mark
雪    币: 122
活跃值: (1460)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
koflfy 1 2016-3-25 09:34
6
0
mark一下,有空再看
雪    币: 3003
活跃值: (464)
能力值: ( LV15,RANK:1395 )
在线值:
发帖
回帖
粉丝
lacoucou 12 2016-3-26 22:10
7
0
官方支持论坛似乎也有下载。。。
http://www.sweetscape.com/010editor/repository/templates/

http://www.sweetscape.com/010editor/repository/templates/file_info.php?file=DEX.bt&type=0&sort=
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
studymu 2016-3-28 10:56
8
0
mark一下,下班了再看了。
雪    币: 191
活跃值: (195)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
大王叫我挖坟 3 2016-5-20 22:27
9
0
谢谢分享
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yodamaster 2016-7-24 04:18
10
0
感谢分享, 模版很好用。
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hacktmz 2016-8-2 14:00
11
0
mark
雪    币: 34
活跃值: (662)
能力值: ( LV3,RANK:24 )
在线值:
发帖
回帖
粉丝
WeiFire 2017-4-26 01:03
12
0
很强啊,官方的脚本不好用,这个可以
雪    币: 541
活跃值: (618)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
_ZeroOne 2020-6-26 16:26
13
0
感谢
游客
登录 | 注册 方可回帖
返回