吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2854|回复: 6
收起左侧

[Android 原创] dex文件格式------map_list解析

[复制链接]
紫诺不离 发表于 2020-6-21 14:45

授人与鱼不如授人与渔,作为初学者,最重要的是学会查看官方文档,自主学习。

首先放上google官方文档对dex解释的链接,里面相当详细的介绍了dex的格式的组成。

https://source.android.google.cn/devices/tech/dalvik/dex-format#header-item

上一篇文章解析了header_item,今天来解析map_list,老规矩,先查看map_list定义格式

size    uint          列表的大小(以条目数表示)
list    map_item[size]  列表的元素

map_item格式

type    ushort  项的类型;见下表
unused  ushort  (未使用)
size    uint    在指定偏移量处找到的项数量
offset  uint    从文件开头到相关项的偏移量

类型格式

header_item TYPE_HEADER_ITEM    0x0000  0x70
string_id_item  TYPE_STRING_ID_ITEM 0x0001  0x04
type_id_item    TYPE_TYPE_ID_ITEM   0x0002  0x04
proto_id_item   TYPE_PROTO_ID_ITEM  0x0003  0x0c
field_id_item   TYPE_FIELD_ID_ITEM  0x0004  0x08
method_id_item  TYPE_METHOD_ID_ITEM 0x0005  0x08
class_def_item  TYPE_CLASS_DEF_ITEM 0x0006  0x20
call_site_id_item   TYPE_CALL_SITE_ID_ITEM  0x0007  0x04
method_handle_item  TYPE_METHOD_HANDLE_ITEM 0x0008  0x08
map_list    TYPE_MAP_LIST   0x1000  4 + (item.size * 12)
type_list   TYPE_TYPE_LIST  0x1001  4 + (item.size * 2)
annotation_set_ref_list TYPE_ANNOTATION_SET_REF_LIST    0x1002  4 + (item.size * 4)
annotation_set_item TYPE_ANNOTATION_SET_ITEM    0x1003  4 + (item.size * 4)
class_data_item TYPE_CLASS_DATA_ITEM    0x2000  隐式;必须解析
code_item   TYPE_CODE_ITEM  0x2001  隐式;必须解析
string_data_item    TYPE_STRING_DATA_ITEM   0x2002  隐式;必须解析
debug_info_item TYPE_DEBUG_INFO_ITEM    0x2003  隐式;必须解析
annotation_item TYPE_ANNOTATION_ITEM    0x2004  隐式;必须解析
encoded_array_item  TYPE_ENCODED_ARRAY_ITEM 0x2005  隐式;必须解析
annotations_directory_item  TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006  隐式;必须解析
hiddenapi_class_data_item   TYPE_HIDDENAPI_CLASS_DATA_ITEM  0xF000  隐式;必须解析

有了格式,接下来定义我们需要的结构体

herder_item

#define IMAGE_SIZEOF_DEX_FILE 8
#define IMAGE_SIZEOF_DEX_SIGNATURE 20
typedef struct  _IMAGE_DEX_HEADER
{
    BYTE magic[IMAGE_SIZEOF_DEX_FILE];  。
    DWORD checksum; 
    BYTE signature[IMAGE_SIZEOF_DEX_SIGNATURE]; 
    DWORD file_size;    
    DWORD header_size;  
    DWORD endian_tag;   
    DWORD link_size;    
    DWORD link_off; 
    DWORD map_off;  
    DWORD string_ids_size;  
    DWORD string_ids_off;   
    DWORD type_ids_size;    
    DWORD type_ids_off;
    DWORD proto_ids_size;   
    DWORD proto_ids_off;    
    DWORD field_ids_size;   
    DWORD field_ids_off;
    DWORD method_ids_size;  
    DWORD method_ids_off;   
    DWORD class_defs_size;  
    DWORD class_defs_off;
    DWORD data_size;        
    DWORD data_off;  
}IMAGE_DEX_HEADER, * PIMAGE_DEX_HEADER;

map_item

typedef struct _IMAGE_MAP_ITEM
{
    WORD type;  
    WORD    unused;
    DWORD   size;   
    DWORD   offset; 
}IMAGE_MAP_ITEM, * PIMAGE_MAP_ITEM;

读取结构体

DWORD my_ReadFile(CString IpzFile)
{
    FILE* pFile = NULL;
    DWORD fileSize = 0;
    LPVOID pTempFileBuffer = NULL;
    /* 打开文件*/
    pFile = fopen(IpzFile, "rb");
    if (!pFile)
    {
        MessageBox(0, TEXT("打开文件失败"), TEXT("信息"), 0);
        return fileSize;
    }
    /*跳转到文件尾 
    //因为map_list数据在较后面一部分,所以需要读取全部的数据
    */
    fseek(pFile, 0, SEEK_END);
    /*
    得到文件的大小
    */
    fileSize = ftell(pFile);

    if (fileSize == -1)
    {

        fclose(pFile);
        return fileSize;
    }
    /*跳转到文件头部*/
    rewind(pFile);
    //分配空间
    pTempFileBuffer = (LPVOID)malloc(fileSize);
    if (!pTempFileBuffer)
    {
        //失败关闭并返回
        fclose(pFile);
        return fileSize;
    }
    size_t n = fread(pTempFileBuffer, fileSize, 1, pFile);
    if (!n)
    {
        fclose(pFile);
        free(pTempFileBuffer);
        return 0;
    }
    fclose(pFile);
    //强转类型
    PIMAGE_DEX_HEADER dex_header=(PIMAGE_DEX_HEADER)pTempFileBuffer;
    //dex_header->map_off通过结构体指针获取到map_list的偏移位置,根据上面的map_list结构可以知道,前面的四个字节是列表的大小,所以转换成LPWORD类型的指针,(DWORD)pTempFileBuffer代表文件开始的位置
    LPDWORD map_size=(LPDWORD)((DWORD)pTempFileBuffer + dex_header->map_off)
    //(map_size+1) DWORD类型的指针加1代表地址值加4,刚好是map_item结构体数组的位置
    PIMAGE_MAP_ITEM virtualAddress_map= (PIMAGE_MAP_ITEM)(map_size+1);
    //通过循环可以获取到每一个map_item的值
    for (size_t i = 0; i < *map_size; i++)
    {
    DWORD   type=(virtualAddress_map+i)->type;   
    DWORD   size=(virtualAddress_map+i)->size; 
    DWORD   offset=(virtualAddress_map+i)->offset;
    }
    return ;
}

根据type的值转换相对应的类型

定义数组

extern LPSTR mType_Text[21] = { "header_item","string_id_item","type_id_item","proto_id_item","field_id_item",
"method_id_item","class_def_item","call_site_id_item","method_handle_item","map_list","type_list",
"annotation_set_ref_list","annotation_set_item","class_data_item","code_item","string_data_item","debug_info_item",
"annotation_item","encoded_array_item","annotations_directory_item" ,"hiddenapi_class_data_item" };

转换函数

char* getMapType(DWORD index)
{
    char* str = NULL;
    switch ( index)
    {
    case 0x0000:
        str = mType_Text[0];
        break;
    case 0x0001:
        str = mType_Text[1];
        break;
    case 0x0002:
        str = mType_Text[2];
        break;
    case 0x0003:
        str = mType_Text[3];
        break;
    case 0x0004:
        str = mType_Text[4];
        break;
    case 0x0005:
        str = mType_Text[5];
        break;
    case 0x0006:
        str = mType_Text[6];
        break;
    case 0x0007:
        str = mType_Text[7];
        break;
    case 0x0008:
        str = mType_Text[8];
        break;
    case 0x1000:
        str = mType_Text[9];
        break;
    case 0x1001:
        str = mType_Text[10];
        break;
    case 0x1002:
        str = mType_Text[11];
        break;
    case 0x1003:
        str = mType_Text[12];
        break;
    case 0x2000:
        str = mType_Text[13];
        break;
    case 0x2001:
        str = mType_Text[14];
        break;
    case 0x2002:
        str = mType_Text[15];
        break;
    case 0x2003:
        str = mType_Text[16];
        break;
    case 0x2004:
        str = mType_Text[17];
        break;
    case 0x2005:
        str = mType_Text[18];
        break;
    case 0x2006:
        str = mType_Text[19];
        break;
    default:
        str = mType_Text[20];
        break;
    }
    return str;
}

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +2 收起 理由
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
温柔的一哥 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

温柔的一哥 发表于 2020-6-21 16:45
楼主辛苦了。发帖不易。支持一下!
cptw 发表于 2020-6-21 22:05
人小鬼大666 发表于 2020-6-21 22:39
tbloy 发表于 2020-6-22 00:23
很详细的教程,支持。
qll24680 发表于 2020-6-23 04:29
很详细  谢谢分享
xzh 发表于 2020-7-6 14:08
辛苦了,很详细的教程
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-19 13:10

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表