IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Dex文件中MUTF-8字符串内容提取C语言实现 -> 正文阅读

[C++知识库]Dex文件中MUTF-8字符串内容提取C语言实现

1:MUTF-8字符串

MUTF-8意为Modified UTF-8,修改过的UTF-8编码

MUTF-8的特点:
1:使用1-3字节编码长度
2:对于大于16位Unicode编码使用3字节编码
3:对于U+0x0000,采用2字节编码
4:采用类似C语言的 ‘\0’ 作为字符串结束标志(小重点)

高级小重点:MUTF-8字符串头部存放uleb128编码表示的字符个数

2:uleb128编码:

由1-5字节组成,所有字节组合在一起表示一个32位的数,每一个字节的最高位表示uleb128是否在本字节停止,按位组合有效位拿到的结果也就是在uleb128之后的真正的字符串的长度。

其中,每当一个低字节的最高位为零,那么,就表示这个uleb128数仍未结束,最高判定到第四字节,如果仍旧大于0x7f,那么就直接和第五字节一起运算。

高级小重点:根据uleb128拿到所表示int值

int result = *(start++);
	if (result > 0x7f) {
		count++;
		int cur = *(start++);
		result = (result & 0x7f) | ((cur & 0x7f) << 7);
		if (cur > 0x7f) {
			count++;
			cur = *(start++);
			result |= ((cur & 0x7f) << 14);
			if (cur > 0x7f) {
				count++;
				cur = *(start++);
				result |= ((cur & 0x7f) << 21);
				if (cur > 0x7f) {
					cur = *(start++);
					count++;
					result |= (cur << 28);
				}
			}
		}
	}

start为指向uleb128起始位置的指针

count的意义在于记录这个uleb128数到底占了多少字节,以便加上字符串的字节数,提取下一个uleb128表示的字符串

3:提取出真实的字符串

注:由于编码的问题,我们不能通过前方计算出的uleb128真实int值就作为后边字符串的字节数,例如:02 e4 bd a0 e5 a5 bd 00,第一个字节小于0x7f,也就是uleb128数为2,两个字符,表示汉字的“你好”,可是他们有6个字节,所以我们通过判断 ‘\0’ 的方式决定字符串长度

那有人就要问了,那这个uleb128有啥用呢?
可能 是节省空间 吧,俺也想问,可能是俺太菜了

好了,接下来就可以提取字符串了,接上边计算uleb128真实值的程序

小贴士:start指针已经到了真实字符串的初始位置,只需拿到长度,然后copy一下子,完事

char* tmp = start;
	while ((*start) != '\0') {
		start++;
		lengthOfString++;
	}
	str = malloc(lengthOfString + 1);
	memset(str, 0, lengthOfString + 1);
	memcpy(str, tmp, lengthOfString);

好啦,这样就基本完工啦,最后构造一个结构体对象出来,保存一下这个MUTF-8字符串的所有细节,就可以返回啦,如下

struct uleb128 a = { count,result,lengthOfString ,str };
return a;

count就是上方计算出的uleb前缀真实字节长度,result为uleb表示的字符个数,接着是字符串长度,字符串真实内容

4:MUTF-8字符串提取终章

这是我对这个字符串详细信息的定义,结合上方返回值一起食用

struct uleb128 {
	int lengthOfHead;//前缀数leb128占几个字节
	int resultOfleb;//前缀数转为int到底是几
	int lengthOfString;//字符串长度,字节为单位
	char* content;//字符串指针,malloc拿到空间
};

附注:跳过uleb128直接提取有效字符串

你可能发现了,uleb128这部分好像并没有太大用处,我本身是为了提取出所有内容的,那,额,好的,那就,拿到uleb128起始地址直接提取真实字符串的方法,代码如下,原理同上,跳过uleb128部分

while (*(start++) > 0x7f);
	char* tmp = start;
	while ((*start) != '\0') {
		start++;
		lengthOfString++;
	}
	str = malloc(lengthOfString + 1);
	memset(str, 0, lengthOfString + 1);
	memcpy(str, tmp, lengthOfString);
	struct uleb128 a = { count,result,lengthOfString ,str };
	return a;

5:完整代码

struct MUTF-8 {
	int lengthOfHead;//前缀数leb128占几个字节
	int resultOfleb;//前缀数到底是几,转为int
	int lengthOfString;//字符串长度
	char* content;//字符串指针,malloc拿到空间
};
struct MUTF-8 Uleb128(char* start) {
	int count = 1;
	int lengthOfString = 0;
	char* str = NULL;
	int result = *(start++);
	if (result > 0x7f) {
		count++;
		int cur = *(start++);
		result = (result & 0x7f) | ((cur & 0x7f) << 7);
		if (cur > 0x7f) {
			count++;
			cur = *(start++);
			result |= ((cur & 0x7f) << 14);
			if (cur > 0x7f) {
				count++;
				cur = *(start++);
				result |= ((cur & 0x7f) << 21);
				if (cur > 0x7f) {
					cur = *(start++);
					count++;
					result |= (cur << 28);
				}
			}
		}
	}
	char* tmp = start;
	while ((*start) != '\0') {
		start++;
		lengthOfString++;
	}
	str = malloc(lengthOfString + 1);
	memset(str, 0, lengthOfString + 1);
	memcpy(str, tmp, lengthOfString);
	struct MUTF-8 a = { count,result,lengthOfString ,str };
	return a;
}
char* Uleb128Skip(char* start) {
	int lengthOfString = 0;
	char* str = NULL;
	while (*(start++) > 0x7f);
	char* tmp = start;
	while ((*start) != '\0') {
		start++;
		lengthOfString++;
	}
	str = malloc(lengthOfString + 1);
	memset(str, 0, lengthOfString + 1);
	memcpy(str, tmp, lengthOfString);
	return str;
}

结束啦,感谢浏览,如有错误,欢迎指导

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-01 17:31:50  更:2021-12-01 17:32:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:37:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码