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文件的强度都比较弱。
相关文章推荐
- HDU1998奇数阶魔方(连续摆数法(也称暹罗法)构造)
- Java经典设计模式之五大创建型模式(附实例和详解)
- Spring MVC 的配置安装
- post和get 传值区别
- BZOJ 1005 明明的烦恼 Prufer序列+组合数学+高精度
- Mysql 文件配置(my.ini)
- QCreator 设置包含目录和库目录
- SQL语言的一些归纳总结
- ubuntu14.04 输入法配置
- bluez 协议栈实现3 应用层的协议栈实现分析之dbus
- 迷宫问题Maze (BFS) 广度优先遍历 C语言
- struts2指定多个配置文件
- 案例分析1-1410501134
- 斜杠/和反斜杠\ 的区别
- 深入理解Runloop
- Http协议详解
- Mac 更新到10.11.3cocoapods的安装及使用问题
- tomcat7开启SSI功能
- Ubuntu下使用SVN
- C#索引器1 数字作为索引号