您的位置:首页 > 其它

Dex文件格式

2016-03-08 11:29 120 查看


Dex文件格式

Google虽然借鉴了Java的上层设计,但是虚拟机使用的是自己设计的Dalvik,Dalvik虚拟机读取、解释的文件是DEX文件。虽然在Android 4.0开始,开始引入类似C#的二次编译技术(Android自称ART),Android 5.0已经完全放弃Dalvik虚拟机(所以源码里已经没有Dalvik设计文档了),但是,二次编译技术是安装apk时候的事,我们用Java语言所写的代码,还是要经过.java->.class->.dex->.apk的过程,认识Dex文件格式,还是有助于反汇编成Smali语言,有助于逆向。


dex生成流程

以下Makefile脚本展示了dex文件生成流程:

MODULE_NAME
:= Hello
START_CLASS
:= Hellk
DX
:= ${SDK_PATH}\sdk\build-tools\19.1.0\dx.bat
INSTALL_PATH
:=
/data/local/tmp
#用dalvikvm虚拟机解释运行dex文件,需要指定启动类
run:
adb
push ${MODULE_NAME}.dex ${INSTALL_PATH}
adb
shell dalvikvm -
cp
${INSTALL_PATH}/${MODULE_NAME}.dex
${START_CLASS}
dx:
${MODULE_NAME}.dex ${MODULE_NAME}.class
#通过.class生成dx
${MODULE_NAME}.dex:
${MODULE_NAME}.class
${DX}
--dex --output=${MODULE_NAME}.dex ${MODULE_NAME}.class
 
javac:
${MODULE_NAME}.class
#dx所支持的.class版本一般不是最新的
${MODULE_NAME}.class:
javac
-
source
1.6
-target 1.6 ${MODULE_NAME}.java


学习Dex文件的工具

推荐使用010 Editor软件,它自带模板插件功能,并且已经有他人制作好的针对Dex文件的模版。可以高亮显示各字段,解析各字段,还附带各字段的注释。对照着Dalvik自带的文档看十六进制,事半功倍


Dex文件组成

按顺序解析dex文件,有以下几个部分:

struct header_item dex_header

struct string_id_list dex_string_ids

struct type_id_list dex_type_ids

struct proto_id_list dex_proto_ids

struct field_id_list dex_field_ids

struct method_id_list dex_method_ids

struct class_def_item_list dex_class_defs

struct map_list_type dex_map_list

其中两头两尾的header_item与map_list是两张“总表”,包含着其它的表的偏移信息等,两者信息有重叠(冗余)。

各个表的功能及要求:

string_id_item[]: 文件中要用到的所有字符串,按UTF-16编码有序排列。

type_id_item[]: 文件中要用到的所有类型信息,但里面并不直接记录着字符串,而是string_id_item[]中的数组下标,且按string_id_item中的数组下标有序排列。

proto_id_item[]: 文件中要用到的所有方法原型,相当于所有函数指针的类型信息,也是有序排列的,主序是返回类型,次序是参数类型。

field_id_item[]: 文件中要用到的所有成员(含静态与普通),按类的类型、成员名、成员类型优先级递减有序排列。

method_id_item[]: 文件中要用到的所有方法(含静态与普通), 按类的类型、方法名、方法原型优先级递减有序排列。

class_def_item[]: 类的信息在此表中,从此表中,可以解析出内部类、静态与普通成员/方法、Dalvik字符码的位置等与类有关的具体信息,都在此表中


文件头中的校验

在文件头中,以下几项比较关键,影响到dex文件能否被dalvikvm正常执行:

uint checksum: 文件0x8偏移处,通过alder32算法,针对文件0xC至文件尾得到的的校验值。

SHA1 signature[20]: 文件0xC偏移处,通过SHA1算法,镇上 对文件0x20至文件尾得到的HASH值。

uint file_size: 文件0x20偏移处,记录文件长度

对Dex文件进行修改后,要依次更新file_size, signature[20], checksum三个字段,Dex才能正常运行。


dex的一些加固思路


大小尾标签

在header_item中有一个uint endian_tag字段,记录了常量0x12345678,dalvikvm在运行Dex文件时,会通过检查这个字段,来决定是以小尾还是大尾方式来解释dex文件(中的相关变量)。由于ARM与x86芯片都是小尾方式,现有的反汇编引擎都不会考虑这个字段(默认小尾),因此,若我们人为修改这个字段为大尾,并将dex文件中相关数据都反过来,可以对抗当前的各种反汇编引擎。


字符串混淆

因为dex文件的信息都很集中,所以将string_id_item[]中的字符串替换为无意义的字符串,整个文件中相关要用到的地方也同步更新了,可用此来混淆。有时候防守方做得太恶心了(如两个函数名:”oooo0o”与”o0oooo”),可以用比较弱的混淆器对抗下(abc一类的名称比数圈圈好)。


实践方案

以上的实验还只是针对dex的标识符的加固,不涉及代码。实际操作中,可以:

得到正常的dex

修改dex中的各表项,使阅读困难

用baksmali,反汇编成smali语法

针对smali文件,进行代码混淆

重新编译smali文件,得到加固后的dex文件

不过,不管怎样混淆,dalvikvm毕竟是开源的,dex文件的强度都比较弱。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: