Android反编译实战(3)

所有内容仅供学习


这一节简单看一下dex文件的结构和smali语法。具体格式请参考谷歌官网

 dex 文件结构如下图:

dexHeader定义如下:

 1 /*
 2  * Direct-mapped "header_item" struct.
 3  */
 4 struct DexHeader {
 5     u1  magic[8];           /* includes version number */
 6     u4  checksum;           /* adler32 checksum */
 7     u1  signature[kSHA1DigestLen]; /* SHA-1 hash */
 8     u4  fileSize;           /* length of entire file */
 9     u4  headerSize;         /* offset to start of next section */
10     u4  endianTag;
11     u4  linkSize;
12     u4  linkOff;
13     u4  mapOff;
14     u4  stringIdsSize;
15     u4  stringIdsOff;
16     u4  typeIdsSize;
17     u4  typeIdsOff;
18     u4  protoIdsSize;
19     u4  protoIdsOff;
20     u4  fieldIdsSize;
21     u4  fieldIdsOff;
22     u4  methodIdsSize;
23     u4  methodIdsOff;
24     u4  classDefsSize;
25     u4  classDefsOff;
26     u4  dataSize;
27     u4  dataOff;
28 };

为了便于理解,我们自己搞个简单的例子来学习一下。

 

 1 public class Hell{
 2     private static final String HELL = "bupt";
 3 
 4     public void sayNothing(String str1){
 5         
 6     }
 7 
 8     public static void main(String[] args){
 9     
10     }
11 }
javac Hell.java
dx --dex --output=Hell.dex Hell.class

dx工具将class文件转为dex文件,打开Hell.dex

magic ---- "64 65 78 0a 30 33 35 00", 代表"dex\n035\0"
checksum --- "8e 53 bd 27", 采用alder32算法
signature --- "35 32 b2 ……d1 50 e8", 采用SHA-1算法
fileSize --- "c0 02 00 00", 0x02c0,十进制为2*256 + 12*16 = 704个字节
headerSize --- "70 00 00 00", Dex头部大小固定,为112个字节
endianTag --- "78 56 34 12", 大小端标志,默认为小端
linkSize --- "00 00 00 00", 表示是静态连接
linkOff --- "00 00 00 00", linkSize 为0, linkOff也为0
mapOff --- "
14 02 00 00", Dalvik虚拟机解析dex文件,最终将其映射成DexMapList数据结构。mapOff指明了DexMapList的偏移位置
stringIdsSize --- "0c 00 00 00", 字符串个数,12个
stringIdsOff --- "70 00 00 00", DexHeader之后紧跟string_ids
……

我们以string_ids为例,找到这12个字符串。0x70处地址为"6e 01 00 00",第一个string数据在0x16e处:

 

06 3c 69 6e 69 74 3e 00

 

第一个string长度为6,使用python转为ASCII为"<init>"

binascii.a2b_hex('3c696e69743e')

 

第二个string长度为4,"HELL", 第三个"Hell.java",其他的类似。

==============

 我们查看当当读书的classes.dex文件,截图如下: 

 

“64 65 78 0a 30 33 35 00”,代表“dex\n035\0”,紧接着4个字节“03 e9 ae 3d”代表利用Adler32算法算出的校验和,从0x0~0x10f共20个字节是采用SHA-1计算出的签名。 

“4c 11 31 00” 4个字节代表整个classes.dex文件的大小,利用windows自带的计算器计算一下16进制“31114c”转为10进制为“3215692”字节,右键-》属性,我们发现大小就是3.06MB。 

 

接下来4字节为DexHeader大小0x70(112)个字节,目前是固定的。“78 56 34 12”代表大小端标志,后面8个字节都为0表明为静态链接。 

“ac 10 31 00”为map_off值 

“7e 58 00 00”为字符串个数,转为10进制为22654个。 

接下来又是0x70,dexheader的大小,说明“string_ids”从0x70处开始,即“fa 73 25 00 ……”,根据这两个值,算出string_ids从0x70开始,在(0x70 + 0x587e * 4)= 0x16267处终止?? 

由“fa 73 25 00”知,第一个String Data 在0x2573fa处,貌似不对啊,0x2573fa处的值为00 啊?????是我算错了,还是混淆后就这样? 实在搞不懂。

 

附上下载android dalvik源码方法:

    git clone http://android.googlesource.com/platform/dalvik

posted on 2013-06-06 16:11  feiyunruyue  阅读(356)  评论(0编辑  收藏  举报

导航