dex文件格式

一、dex文件中的数据结构

类型有三个:u1 u2 u4 u8  sleb128 uleb128 uleb128p1 七个类型 如图:

u1-u8好理解,就是1到8个字节的无符号整数,而后面的sleb128 uleb128 uleb128p1是dex文件中特有的LEB128数据类型,leb128表示可变长度1-5个字节所有字节组合在一起为32位数据,每个字节的有效位数只有七位,留一个最高位做标识,表示是否有下一位(为1),没有下一位(为0),leb128最多有5个字节,如果读到最后一个字节的标识位仍为1.则会返回dex文件无效,Dalvik虚拟机验证dex时会失败返回,LEB128数据类型如下图:

 在android系统源码有leb128的实现,读取无符号leb128(uleb128)代码如下:

ptr是一个指针,指向数据的第一个字节,当第一个字节大于0x7f(b1111111)就代表有后一个字节,将第一个字节(result)和第二个字节(cur=ptr++)组合result&0x7f | ((cur&0x7f)<<7) 意思是:取第二个字节的后七位,然后左移7位再和第一个字节或,就将两个字节组合在一起,然后判断第二个字节的最高位(标识)为1则继续判断下一字节,组合三个字节,以此类推。

有符号的LEB128(sleb128)和无符号大体一样,只是多了对无符号LEB128最后一个字节最高有效位进行了符号扩展,代码如下:

对于每个字节最高位为0的(字节大小小于0x7f)的说明没有下一字节,直接进行符号位扩展,如果最高位为1,则进行字节组合之后,到最后一个字节然后进行符号扩展,关于符号扩展,补充一下(扫盲)

符号位拓展就是: 将数据的最高位(这里是指32位的最高位)设置成数据的符号位,这里符号位拓展用了(result<<25)>>25,25可变,由于数据有效位7位,第一个字节拓展就要向左移25(32-7)位,将最高符号位设为数据的最高位,然后再右移相同位数数据复原,但是32位最高位已被拓展成数据的符号位了,这里不影响是因为数据有效位7位,32位的最高位也是标识位,所以再向右移复原的时候标识位不会随着复原,即完成了最高位符号位的拓展。

示例:

  1. 无符号扩展:直接将扩展后的数据的高(32-n)位置为0。
  2. 符号扩展:将扩展后的数据的高(32-n)位置为立即数的最高位。

 

16位立即数0x80000x1000
符号扩展0xFFFF80000x00001000
无符号扩展0x000080000x00001000

两个例子:

 

二、dex文件整体结构 

dex真题结构比较简单有多个结构体组成,一个dex文件由7个部分组成,如图:

其中DexHeader指定了dex文件的一些属性,并记录了其他六个部分数据结构在dex文件中的物理偏移,string_ids到class_def可理解为索引结构区,真实的数据存放在data数据区,link_data为静态链接数据区。

DexHeader结构体为:

对比结构体看16禁止文件,一一对应:

中间未标注出来的是string_ids到class_def的个数和文件偏移,其中endianTag意思是:指定了dex运行环境的cpu字节序,与设值ENDIAN_CONSTANT等于0x12345678,表示默认采用Little-Endian字节序。

三、dex文件结构分析

dex文件头有一个mapOff指明了DexMapList在dex文件中的偏移,声明如下:

size表示有多少个DexMapItem,其结构如下:

type字段是一个枚举常量,size表示特定类型的个数,offset为文件起始偏移以Hello.java->Hello.class->Hello.dex为例:

由上面可知mapOff的位置在0x024c位置:

整理出的DexMapItem表如下:

类型个数偏移
kDexTypeHeaderItem0x10x0
kDexTypeStringIdItem0xe0x70
kDexTypeTypeIdItem0x70xa8
kDexTypeProtoIdItem0x30xc4
kDexTypeFieldIdItem0x10xe8
kDexTypeMethodIdItem0x40xf0
...
...
...
...
...
...
.省略.省略.省略

上图和表格一一对应 

上图是stringIdItem在0x70偏移处 的0xe个DexStringId对象,红线圈的是第一个字符串结构,蓝线的是第二个、黄线的是第三个以此类推,下面是kDexTypeTypeIdItem了,它对应DexHeader中的typeIdsSize与typeIdsOff字段,指向的结构体为:

descriptorIdx指向DexStringId列表的索引(就是上一个stringiditem),对应的字符串代表了具体类的类型,根据DexMapItem表,知typeTypeIdItem偏移0xa8处有0x7个DexTypeId结构,也就是说有7个字符串的索引,分别对应13个字符串的第0x2、0x3、0x4、0x5、0x6、0x7、0x9个,类型索引从大到小分别为0x0、1、2、3、4、5、6。

其他的一样以此类推,有时间补充

四、odex文件格式

1、如何生成odex文件

pass

2、odex文件整体结构

pass

3、odex文件结构分析

pass

占个位先。。。

五、android应用另类破解方法

通常我们破解简单的app都是通过反编译apk之后修改smail代码,然后重新打包,过程非常慢,还有一种另类的方法,我们都知道程序代码都是存储在dex文件中的,修改dex文件,重新签名就可以达到破解程序的目的,

例子程序:firstapp

步骤:1.用打开zip软件,打开apk文件,将classes.dex文件拉出来,用ida打开找到关键要修改的地方,记下地址

2.用16进制编辑器打开dex文件,找到对应地址,将 if-eqz改为if-nez对应的指令38改为39,保存

只改dex还不行因为安装时dexopt优化会对dexheader中的checksum标识进行合法性检查,不通过会导致安装失败,所以我们要修复dex的checksum值,为了方便可以用工具DexFixer,吾爱工具包里有,也可以在网上下载,图就不放了,直接将修改过的dex文件拖进去就行了。

3.最后重新签名,签名工具很多,同样这里用的是吾爱工具包里的APK上上签工具

4.安装测试

暂时告一段落。。。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值