吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2651|回复: 2
收起左侧

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

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

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

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

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

上一篇文章解析了map_list,今天来解析dex中的字符串,老规矩,先来看官方文档的介绍。

header_item中对字符串描述的只有这三句

1、string_ids_size记录了字符串的数量

2、string_ids_off记录了字符串从文件开头到字符串标识的偏移量

3、该偏移量(如果为非零值)应该是到 string_ids 区段开头的偏移量。

那么string_ids是什么呢?

从dex完整格式中可以看到有这么一个结构
string_ids string_id_item[] 字符串标识符列表。这些是此文件使用的所有字符串的标识符,用于内部命名(例如类型描述符)或用作代码引用的常量对象。此列表必须使用 UTF-16 代码点值按字符串内容进行排序(不采用语言区域敏感方式),且不得包含任何重复条目。
看到这里就很明显了,string_ids是一个string_id_item格式的数组,string_ids_size记录了此数组的数量,string_ids_off记录了从文件开头到此数组的偏移量。

string_id_item格式

string_data_off //uint  从文件开头到此项的字符串数据的偏移量。该偏移量应该是到 data 区段中某个位置的偏移量,且其中的数据应采用下文中“string_data_item”指定的格式。 没有偏移量对齐要求。
string_id_item只是一个四字节的偏移量,没必要定义一个结构体。
接下来看看string_data_item格式:
utf16_size  uleb128//   此字符串的大小;以 UTF-16 代码单元(在许多系统中为“字符串长度”)为单位。也就是说,这是该字符串的解码长度(编码长度隐含在 0 字节的位置)。
data    ubyte[] //一系列 MUTF-8 代码单元(又称八位字节),后跟一个值为 0 的字节。请参阅上文中的“MUTF-8(修改后的 UTF-8)编码”,了解有关该数据格式的详情和讨论。
浅析
utf16_size记录了字符串的大小,格式是uleb128,uleb128是一个不固定的长度,c语言中并没有能表示这种变化长度的类型,(不知道uleb128是什么的,去官方文档或者我的第一篇文章看一下),再来看第二个data的格式是 ubyte[],并且后跟一个值为 0 的字节,而char*正好是以0来结尾的,而char*通过每个字节转换正好可以解析出utf16_size的值和占用的字节。

转换uleb128函数

//返回长度
WORD getLEB128Lenght(char* str)
{
    //初始化长度为1
    WORD index = 1;
  //如果值为0,返回长度
    if (*str)
    {
      // 如果值不为0,查看最高位是否为1
        while (*str++ & 0x80)
        {
        //长度++
            ++index;
        }
    }
    return index;
}

//返回值,此处比之前改进了一下,因为我发现进位时会因为宽度问题导致数值错误
WORD LEB128toInt(char* str)
{
    DWORD value = 0;
    WORD index = 0;
    if (*str)
    {
        do {
        //*str & 0X7F是吧最高位设置为0
            DWORD m = (*str & 0X7F) << (index * 7);
            value += m;
            ++index;

        } while (*str++ & 0x80);
    }
    return value;
}

解析字符串

//此处我选择写一个函数,因为后面用到的地方太多了。
//第一个参数是dex_header结构体  之前有说怎么获取,这里不提
//第二个参数是指向string_id_item地址的指针  文件开始的地址加上string_ids_off中的偏移
//第三个参数是找的是第几个string_data_item  取值范围1到string_ids_size直接
char* getString(PIMAGE_DEX_HEADER IpParameter , LPDWORD virtualAddress_string,DWORD index)
{
//通过取值得到地址的偏移 *(virtualAddress_string + index),再加上文件开始的地址,

    char* str = (char*)((DWORD)IpParameter + *(virtualAddress_string + index));
    //计算字符串长度所占的字节数
    DWORD n = getLEB128Lenght(str);
    //返回正确的字符串首地址
    return str + n;
}

c语言解析0结尾的字符串用%s,puts之类的都可以。

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
qtfreet00 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xiaoerer + 1 + 1 热心回复!

查看全部评分

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

xiaoerer 发表于 2020-6-22 21:56
下载链接呢。。
 楼主| 紫诺不离 发表于 2020-6-23 08:00
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 21:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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