Dex文件结构
目录
转自:https://zhuanlan.zhihu.com/p/49090249
我们都知道Android程序的Java代码在编译之后存储在dex文件之中,但是不知道大家有没有想过一个问题,在我们进行Java层的逆向时,其中的Smali代码从何而来?要想真正的解释清楚这个问题我们就不得不去学习一下dex的文件结构。不光如此,很多的加固思路都是围绕着文件的格式以及加载的过程做文章的。可见逆向工程的本质就是走进底层,不要只局限在应用层。我们只要尽可能的了解本质,就会有更多改变事物的可能。
在我们学习dex文件格式之前安利一下010editor这款工具,不光能以十六进制查看文件,官方还提供了很多文件的模板,可以帮助我们分析文件的结构。下面我们就配合这个工具,来给大家介绍dex文件结构,我们随便找一个dex文件将其拖入010editor中,并运行脚本。
Dex整体结构
Dex文件的整体结构如下,文件头指定了一些属性,索引区记录着一些偏移和索引,数据区用于存放真正所需要的数据。

Dex header
在我们点击dex_header后,它的区域就会被显示出来。


对应结构体的解释如下图

因为采用小端序的排序方式,我们也能明白读数的方法。就是对于一个变量里的数据,整体是从右到左将字节排序,但是在每个字节中是从左到右。
例如:
文件中78 56 34 12
实际上12 34 56 78
总结一下,dex header部分就是指明了一些基本的校验、大小属性,还有期待结构体的大小和偏移,具有目录一样的作用。接下来我们依次介绍一下各个偏移。
MapList
dalvik虚拟机对dex文件进行解析,最终将其映射成这个数据结构。

StringID
这部分存放着所用到的字符串偏移,来被其他结构体调用。偏移指向着真正的字符串数据,一般采用MUTF-8编码,字符串格式为uleb128编码字符个数+字符串+00结尾。uleb128简单来说是一种变长的数据类型,一般长度为1-5个字节,每个字节有7个有效位,而最高位负责判断是否使用下一个字节,如果为1则使用,如果为0则不使用。

在工具中可以看到每个指向对应的字符串。

TypeID
数据类型部分

工具中可以看到具体的类型,就是些数据类型之类的。

ProtoID
关于方法的声明


FieldID
存储关于字段的信息


MethodID
存储关于方法的信息


ClassDef
存储关于类的信息,这部分很复杂也很关键,我们的smali代码就存储在这里。

看完结构的介绍我们知道了指令集存储在DexCode中,但是怎么去分析这部分的内容呢?我们在jeb中打开一个程序,这是一个方法。左边是他的指令集,存储在DexCode这个结构中,右边是它反编译的smali语法,我们来尝试分析一下。

因为指令以两个字节为单位,所以有四条指令,分别为:
70 10
09 00
00 00
0e 00
通过查表我们知道70的opcode为invoke-direct,格式为35c。

我们再去查指令格式表,左边是它的指令格式,右边是它的表达方式。知道了它的指令格式,同时要使用三个单位的指令,因为数据以小端序排序我们重排下序。

10 70 00 09 00 00
B|A op CCCC G|F|E|D
可以看到B=1,我们采用[B=1] op {vD}, kind@CCCC的表达方式。
CCCC=9,G=F=E=D=0,得出寄存器为0号寄存,引用了Method列表中索引值为9的数据。
我们在010editor中看一下。

结合smali语法,结果为invoke-direct {p0} Landroid/app/Activity;-><init>V
而0e 00指令通过查表为,return-void

结果是不是和JEB解析的一样。

所以有的时候可以从dex文件下手去修改程序,比起每次apktool回编译失败让人原地爆炸,从dex文件修改的话只需要修复一下dex文件改一下验证即可。
本期内容就到这里啦~以上内容均可在 方包博客「http://fang1688.cn」 网站直接搜索名称访问哦。欢迎感兴趣的小伙伴试试,如果本文对您有帮助,也请帮忙点个 赞 + 在看 啦!❤️
欢迎大家加入方包的「优派编程」学习圈子,和多名小伙伴们一起交流学习,向方包 1 对 1 提问、跟着方包做项目、领取大量编程资源等。Q群「763256989」欢迎想一起学习进步的小伙伴~
另外方包最近开发了一款工具类的小程序「方包工具箱」,功能包括:抖音、小红书、快手去水印,天气预报,小说在线免费阅读(内含上万部热门小说),历史今天,生成图片二维码,图片识别文字,ai伪原创文章,数字摇号抽奖,文字转语音MP3功能...
定期分享 it编程干货