Dex文件分析,从magic到data的全字段,逐字节分析!小白也能懂

news/2024/11/7 19:33:46/

文章目录

  • 1、class和dex文件的宏观区别
  • 2、dex文件和class字节码的基本区别
  • 3、dex文件实例分析
    • 3.1配置dx环境变量
    • 3.2Java源文件
    • 3.3 编译成class二进制码
    • 3.4 将二进制class文件优化成dex文件
  • 4、分析dex文件
    • 4.1头文件 header
      • 4.1.1 解析头文件
    • 4.2 索引区的分析
      • 4.2.1 索引区的分析介绍
      • 4.2.2 实例分析

前言:上一次分析了class字节码的文件,然后继续看书的过程中。需要自己制作分析一个dex的工具。制作工具之前,首先是得明白原理,然后再如说是没问题的,今天就此记录我的分析理解。如有不足之处希望大家指出!

1、class和dex文件的宏观区别

dex文件是从class字节码文件中优化出来的产物,class字节码是对于java虚拟机来说的。则dex文件则是对前者优化之后提供给android(安卓davlik虚拟机,应该是安卓4.4版本之前)来说。

2、dex文件和class字节码的基本区别

通过上面的说明,大致我们能明白,dex是建立在class基础之上优化过来的。那两者的区别有哪些呢?

区别class字节码dex文件
endian(字符序)低位在右边,高位在左低位在左,高位在后
文件区分不同常量池/data头文件/索引区/数据区
LEB128在int基础之上变种的数据类型,高位第7位数(索引为0)据表示是否结束,如果为1则表示后面还有字节。如果第7位表示0,则终止。当第二个或者第三个字节有存在的时候,第二个字节的第0索引,对应的是第一个字节的第七位!每个字节的第七位是判断位

3、dex文件实例分析

3.1配置dx环境变量

我相信能看到这里的人,java环境已经是配置好了的。

找到<SDK_HOME>/build-tools/<VERSION>

这里是你会看到一个dx.bat的批处理脚本。
打开我的电脑,环境变量中,找到环境变量中的path,将全路径放进入。
此时,按住win+r输入cmd,打出dx --version

dx --version
dx version 1.16

3.2Java源文件

package com.company.jvm;
public class Sample {public String m1;public String m2;public Object [] arr;public static void main(String[] args) {Sample sample = new Sample();sample.m1="22";sample.arr=new Object[12];System.out.println(sample.m1);}
}

3.3 编译成class二进制码

javac Sample

3.4 将二进制class文件优化成dex文件

	dx --dex --output=Sample.dex com/comany/jvm/Sample.class

输入上面的指令之后,有可能会报错,出现的问题为:

class name (com/company/jvm/Sample) does not match path (Sample.class)
...while parsing Sample.class

大致意思就说,找不到路径。此时我们需要到包名的根目录下,进入cmd。

4、分析dex文件

上面已经说过,dex文件基本可以分为三个区域:1、头文件 2、索引区 3、数据区

4.1头文件 header

类型字节长度说明
magicU8标识类型,列入class的文件是cafebabe,dex则是dex\n035\0
checksumU4(除 magic 和此字段之外的所有内容)的 adler32 校验和
signaturebyte[20]文件剩余内容(除 magic、checksum 和此字段之外的所有内容)的 SHA-1 签名(哈希);用于对文件进行唯一标识
file_sizeU4整个文件(包括标头)的大小,以字节为单位
header_sizeU4默认为0x70头文件(整个区段)的大小,以字节为单位。此项允许至少一定程度的向后/向前兼容性,而不会使格式失效。
endian_tagU4默认为低字符序,取值为0x12345678。如果是big endian则为0x78654321,说明进行过字节交换,这里具体可以查看android关于endian tag的说明
link_sizeU4链接区段的大小;如果此文件未进行静态链接,则该值为 0
link_offU4从文件开头到链接区段的偏移量,如果 link_size == 0,则该值为 0。该偏移量(如果为非零值)应该是到
map_offU4从文件开头到映射项的偏移量。该偏移量(必须为非零值)应该是到 data 区段的偏移量,而数据应采用下文中“map_list”指定的格式。

4.1.1 解析头文件

对应偏移位长度字符节说明
magic0x0000U864 65 78 0a 30 33 35 00长度为8的byte数组,转换成字符之后就是dex 035
checkSum0x0008U485 71 f0 2c其adler32校验和结果就是2CF07185的结果【高位字符序
signature0x000Cbyte[20]~0x10其结果是sha-1的加密,我这里的结果为:6003000070000000785634120000000000000000
file_size0x20U460 03 00 00计算得出为 864,说明当前有864个byte
header_size0x24U470 00 00 00一般情况下都为0x70
endian_tag0x28U478 56 34 12这里说明是已经是进行过交换处理
link_size0x2cU400 00 00 00说明没有静态链接,数量为0【何为静态链接,后面的文章应该会梳理。今天的内容不在此】
link_off0x30U400 00 00 00偏移量为0
map_off0x34U4C0 02 00 00数据位置偏移为704

4.2 索引区的分析

4.2.1 索引区的分析介绍

类型字节长度说明
string_ids_sizeU4字符串的数量
string_ids_offU4从文件开头到标识符的偏移量
type_ids_sizeU4类型标识符列表数量,最多为 65535
type_ids_offU4从文件开头到类型标识符列表的偏移量;如果 type_ids_size == 0(不可否认是一种奇怪的极端情况),则该值为 0。该偏移量(如果为非零值)应该是到 type_ids 区段开头的偏移量。
proto_ids_sizeU4原型标识符列表中的元素数量,最多为 65535
proto_ids_offU4原型从文件开头到标识符的偏移量
field_ids_sizeU4字段数量
field_ids_offU4从文件开头到字段标识符列表的偏移量
method_ids_sizeU4方法标识符列表中的元素数量
method_ids_offU4从文件开头到方法标识符列表的偏移量
class_defs_sizeU4类定义列表中的元素数量
class_defs_offU4方从文件开头到类定义列表的偏移量
data_sizeU4data 区段的大小(以字节为单位)。该数值必须是 sizeof(uint) 的偶数倍
method_ids_offU4从文件开头到 data 区段开头的偏移量

4.2.2 实例分析

类型偏移位字节码说明
string_ids_size0x3812 00 00 00说明存在18个字符串
string_ids_off0x3c70 00 00 00从文件开头到标识符的偏移量为112
type_ids_size0x4008 00 00 00类型标识符列表数量为:8
type_ids_off0x44b8 00 00 00从文件开头到类型标识符列表的偏移量为:0xb8
proto_ids_size0x4803 00 00 00原型标识符列表中的元素数量为:3
proto_ids_off0x4cd8 00 00 00原型从文件开头到标识符的偏移量为:0xd8
field_ids_size0x5004 00 00 00字段数量为4
field_ids_off0x54fc 00 00 00从文件开头到字段标识符列表的偏移量为0x54
method_ids_size0x5804 00 00 00方法标识符列表中的元素数量为:4
method_ids_off0x5c1c 01 00 00从文件开头到方法标识符列表的偏移量为:0x011c
class_defs_size0x6001 00 00 00类定义列表中的元素数量为:1
class_defs_off0x643c 01 00 00方从文件开头到类定义列表的偏移量0x013c
data_size0x70c2 01 00 00data 区段的大小(以字节为单位)。该数值必须是 sizeof(uint) 的偶数倍,为:450
data_off0x74c601 00 00从文件开头到 data 区段开头的偏移量为0x01c6

~后文待续,坐了一个多小时了,休息会儿


http://www.ppmy.cn/news/297178.html

相关文章

六步快速搭建个人网站

目录 第一步、选择搭建平台WordPress 第二步、选域名 1&#xff09;域名在哪买&#xff1f; 2&#xff09;域名怎么选&#xff1f; 3&#xff09;以阿里云为例&#xff0c;讲解怎么买域名 第三步、选择服务器 第四步、申请主机、安装WordPress 第五步、选择WordPress模…

C语言---自定义类型:结构体,枚举,联合

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;凡人修C传 &#x1f4ac;总结&#xff1a;希望你看完之后&…

分布式项目15 用户注册,单点登陆dubbo来实现

分析&#xff1a;当用户填写完成注册信息之后,将请求发送给前台服务器.之后前台消费者利用dubbo框架实现RPC调用。之后将用户信息传递给jt-sso服务提供者.之后完成数据的入库操作。 01.页面url分析 02.查看页面JS $.ajax({ type : "POST", url : "/user/doRe…

电脑重装系统后无法开机是什么原因导致的

电脑重装系统是一种常见的解决问题和提升性能的方法&#xff0c;但有时候重装系统后可能会遇到无法开机的问题。本文将介绍一些常见原因和解决方法&#xff0c;帮助您解决电脑重装系统后无法开机的困扰。 工具/原料&#xff1a; 系统版本&#xff1a;windows7系统 品牌型号&…

机器学习-12 卷积神经网络简介

卷积神经网络 引言深度学习发展历程深度应用领域深度学习vs传统机器学习深度神经网络vs浅层神经网络深度学习概述 卷积神经网络CNNBP神经网络CNN概述卷积神经网络大致结构卷积神经网络大致过程 局部连接权值共享非线性映射ReLU&#xff08;Rectified Linear Units&#xff09;池…

你的Postman为什么连不了数据库?

postman本身没有数据库连接功能&#xff0c;所以用到了node.js中的xmysql实现Rest API的生成&#xff0c;利用postman进行请求&#xff0c;获取需要的数据&#xff0c;来做数据准备或断言 1.安装 安装node.js&#xff1a;要求版本大于等于7.6 首先保证你的环境上有node.js&a…

DOTA数据集

https://captain-whu.github.io/DOTA/dataset.html https://github.com/search?qfaster_rcnn_for_DOTA 转载于:https://www.cnblogs.com/ivyharding/p/11155676.html

DOTA自走棋攻略

DOTA自走棋攻略 文章目录 DOTA自走棋攻略一、选择与走向-----全场节奏、圣物和嫖牌决定阵容走向二、前期运营三、牧师机制四、对手机制五、站位细节阵容 一、选择与走向-----全场节奏、圣物和嫖牌决定阵容走向 野怪 前3波小野怪 10波石头人 15波野狼 高人口阵容&#xff1a; …