• 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

  • 相关阅读:
    nodejs内存控制
    nodejs的Buffer解析
    基于Yeoman实现自定义脚手架
    基于node实现一个简单的脚手架工具(node控制台交互项目)
    nodeJs入门的第一节课
    手动封装一个node命令集工具
    [转载] 如何掌握所有的程序语言 —— 王垠
    Kubernetes:服务与负载均衡
    Zabbix 6.0:原生高可用(HA)方案部署
    Kubernetes:健康检查
  • 原文地址:https://www.cnblogs.com/feiyunruyue/p/3119977.html
Copyright © 2020-2023  润新知