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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2695|回复: 1
收起左侧

[Android 原创] dex文件格式------proto_id_item、field_id_item、method_id_item解析

[复制链接]
紫诺不离 发表于 2020-6-24 19:28

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

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

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

上一篇文章解析了type_ids,今天来解析dex中的proto_id_item、field_id_item、method_id_item,为什么这三个放在一起呢?因为有了前面的基础,这三个就没有一点难度了,老规矩,先来看官方文档的介绍。

proto_id_item

shorty_idx  uint    此原型的简短式描述符字符串的 string_ids 列表中的索引。该字符串必须符合上文定义的 ShortyDescriptor 的语法,而且必须与该项的返回类型和参数相对应。
return_type_idx uint    此原型的返回类型的 type_ids 列表中的索引
parameters_off  uint    从文件开头到此原型的参数类型列表的偏移量;如果此原型没有参数,则该值为 0。该偏移量(如果为非零值)应该位于 data 区段,且其中的数据应采用下文中“"type_list"”指定的格式。此外,不得对列表中的类型 void 进行任何引用。

定义结构体

typedef struct _IMAGE_PROTO_ID_ITEM
{
    DWORD shorty_idx;      
    DWORD   return_type_idx;
    DWORD   parameters_off; 

}IMAGE_PROTO_ID_ITEM, * PIMAGE_PROTO_ID_ITEM;

field_id_item

class_idx   ushort  此字段的定义符的 type_ids 列表中的索引。此项必须是“类”类型,而不能是“数组”或“基元”类型。
type_idx    ushort  此字段的类型的 type_ids 列表中的索引
name_idx    uint    此字段的名称的 string_ids 列表中的索引。该字符串必须符合上文定义的 MemberName 的语法。

定义结构体

typedef struct _IMAGE_FIELD_ID_ITEM
{
    WORD class_idx; 
    WORD type_idx;  
    DWORD name_idx;
}IMAGE_FIELD_ID_ITEM, * PIMAGE_FIELD_ID_ITEM;

method_id_item

class_idx   ushort  此方法的定义符的 type_ids 列表中的索引。此项必须是“类”或“数组”类型,而不能是“基元”类型。
proto_idx   ushort  此方法的原型的 proto_ids 列表中的索引
name_idx    uint    此方法的名称的 string_ids 列表中的索引。该字符串必须符合上文定义的 MemberName 的语法。

定义结构体

typedef struct _IMAGE_METHOD_ID_ITEM
{
    WORD class_idx;
    WORD proto_idx;
    DWORD name_idx;
}IMAGE_METHOD_ID_ITEM, * PIMAGE_METHOD_ID_ITEM;

浅析:

看到上面的type_ids索引、string_ids索引有没有觉得很眼熟?没错,就是前几天的解析函数,只需要把参数和索引传进去,就可以成功的获取到字符串了。同时,这两个列表也要写成函数的形式,因为解析class_ids的时候要用到。

virtualAddress_proto解析函数

//其他参数不在解释了,这里只解释一下char**,二级指针用于接收合成的新字符串
void getString(PIMAGE_DEX_HEADER IpParameter, PDWORD virtualAddress_string, PIMAGE_TYPE_ITEM virtualAddress_type, PIMAGE_PROTO_ID_ITEM virtualAddress_proto, char** m_str, DWORD index)
{
    char* str_id = getString(IpParameter, virtualAddress_string, (virtualAddress_proto + index)->shorty_idx);
    char* str_id2 = getString(IpParameter, virtualAddress_string, virtualAddress_type, (virtualAddress_proto + index)->return_type_idx);
    //这里要判断一下参数是否为0
    if ((virtualAddress_proto + index)->parameters_off)
    {
        PIMAGE_TYPE_LIST type_list = (PIMAGE_TYPE_LIST)((DWORD)IpParameter + (virtualAddress_proto + index)->parameters_off);
        PWORD list = &(type_list->list);
        LPSTR* str_list = (LPSTR*)malloc(sizeof(int) * type_list->size);
        memset(str_list, 0, sizeof(int) * type_list->size);
        DWORD index = 0;
        if (str_list)
        {
            for (size_t j = 0; j < type_list->size; j++)
            {
                str_list[j] = getString(IpParameter, virtualAddress_string, virtualAddress_type, *(list + j));
                index += strlen(str_list[j]);
            }
        }
        char* str = (char*)malloc(strlen(str_id) + strlen(str_id2) + index + 61);
        sprintf(str, "\t%s \t", str_id2);

        for (size_t i = 0; i < type_list->size; i++)
        {
            strcat(str, str_list[i]);

        }
        if (str_list)
        {
            free(str_list);
        }
        strcat(str, "\t");
        *m_str = str;
        return;
    }
    char* str = (char*)malloc(strlen(str_id) + strlen(str_id2) + 61);
    memset(str, 0, strlen(str_id) + strlen(str_id2) + 61);
    if (str)
    {
        sprintf(str, "\t%s \t ", str_id2);
        *m_str = str;
        return;
    }
    return;
}

field_id_item

void getString(PIMAGE_DEX_HEADER IpParameter, PDWORD virtualAddress_string, PIMAGE_TYPE_ITEM virtualAddress, PIMAGE_FIELD_ID_ITEM virtualAddress_field, char** m_str, DWORD index)
{
    char* str_id3 = getString(IpParameter, virtualAddress_string, (virtualAddress_field + index)->name_idx);
    char* str_id1 = getString(IpParameter, virtualAddress_string, virtualAddress, (virtualAddress_field+index)->class_idx);
    char* str_id2 = getString(IpParameter, virtualAddress_string, virtualAddress, (virtualAddress_field + index)->type_idx);

    char* str = (char*)malloc(strlen(str_id3) + strlen(str_id1) + strlen(str_id2) + 41);
    if (str)
    {

        sprintf(str, "字段定义\t%s\t 字段类型\t%s \t列表的名称\t%s \n", str_id1, str_id2,str_id3);
        *m_str = str;
        return;
    }
    return;
}

method_id_item

    getString(IpParameter, virtualAddress_string, virtualAddress, virtualAddress_proto, &str_id2, str_id3, strlen(str_id3), (virtualAddress_method + index)->proto_idx);

    char* str_id1 = getString(IpParameter, virtualAddress_string, virtualAddress, (virtualAddress_method + index)->class_idx);
    if (!str_id2)
    {
        return;
    }
    char* str = (char*)malloc(strlen(str_id3) + strlen(str_id1) + strlen(str_id2) + 41);

    if (str)
    {

        sprintf(str, "方法的定义\t%s\t 方法名称\t%s \t方法原型\t%s ", str_id1, str_id3, str_id2);
        *m_str = str;
        free(str_id2);
        return;
    }
    return;
}

由于代码过于简单,之前都介绍过了,就不在详细介绍了。

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +2 收起 理由
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
moranyuyan + 1 + 1 我很赞同!

查看全部评分

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

夜步城 发表于 2020-6-25 17:22
感谢资源,来学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-5-3 20:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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