[原创]android中Dex文件结构详解
写太多文字我想大家看着也烦,我写着也累。
dex是什么? 简单说就是优化后的android版.exe。每个apk安装包里都有。
相对于PC上的java虚拟机能运行.class;android上的Davlik虚拟机能运行.dex。
为何要研究dex格式?因为dex里面包含了所有app代码,利用反编译工具可以获取java源码。理解并修改dex文件,就能更好的apk破解和防破解。
[图片:TB2Ys2SeFXXXXXNXXXXXXXXXXXX_!!62073991.png]
几个注意点:
1. SHA-1签名字段中SHA是个啥?
SHA(Secure Hash Algorithm, 安全散列算法)是美国国家安全局设计,美国国家标准与技术研究院发布的一系列密码散列函数。SHA-1看起来和MD5算法很像,也许是Ron Rivest在SHA-1的设计中起了一定的作用。SHA-1的内部比MD5更强,其摘要比MD5的16字节长4个字节,这个算法成功经受了密码分析专家 的攻击,也因而受到密码学界的广泛推崇。这个算法在目前网络上的签名,BT软件里就有大量使用,比如在BT里要计算是否同一个种子时,就是利用文件的签名 来判断的。同一份8G的电影从几千BT用户那里下载,也不会出现错误的数据,导致电影不播放。
2.map基址干啥地?
map中描述包括了在dex文件里可能出现的所有类型。
map数据排列结构定义如下:
typedef struct DexMapList {
u4 size; /* #of entries inlist */
DexMapItem list[1]; /* entries */
}DexMapList;
每一个map项的结构定义如下:
typedef struct DexMapItem {
u2 type; /* type code (seekDexType* above) */
u2 unused;
u4 size; /* count of items ofthe indicated type */
u4 offset; /* file offset tothe start of data */
}DexMapItem;
DexMapItem结构定义如下:
enum{
kDexTypeHeaderItem = 0x0000, //头文件
kDexTypeStringIdItem = 0x0001,
kDexTypeTypeIdItem = 0x0002,
kDexTypeProtoIdItem = 0x0003,
kDexTypeFieldIdItem = 0x0004,
kDexTypeMethodIdItem = 0x0005, //方法
kDexTypeClassDefItem = 0x0006, //类
kDexTypeMapList = 0x1000, //Map
kDexTypeTypeList = 0x1001,
kDexTypeAnnotationSetRefList = 0x1002,
kDexTypeAnnotationSetItem = 0x1003,
kDexTypeClassDataItem = 0x2000,
kDexTypeCodeItem = 0x2001,
kDexTypeStringDataItem = 0x2002, //字符
kDexTypeDebugInfoItem = 0x2003,
kDexTypeAnnotationItem = 0x2004,
kDexTypeEncodedArrayItem = 0x2005,
kDexTypeAnnotationsDirectoryItem = 0x2006,
};
通过DexMapItem定义可以发现:这个定义的像类、字符串、方法等资源和dex文件头里定义的类型有很多是一样的。其实这个map的数据,就是头里类型的重复,完全是为了检验作用而存在的。当Android系统加载dex文件时,如果比较文件头类型个数与 map里类型不一致时,就会停止使用这个dex文件
3.dex文件有个天大的好处:它可以直接用DexClassLoader类加载,这叫动态加载。于是我们只要在dex上加壳,在程序运行时脱壳,就可以规避静态反编译的风险。
因为是新手贴,这里只做到抛砖引玉,画图方便大家记忆并给出了几个关键性技术术语。技术拓展,还请自行在百度上顺藤摸瓜,按图索骥。
