APK的Dex文件结构和它的方法数统计分析

本文介绍了Android的Dex文件结构,作为Class文件的优化版,Dex文件减少了内存占用。内容包括Dex文件的头部信息、proto_ids、methods_ids等字段,并通过dexdump工具分析Dex。此外,文章还详细解析了如何统计Dex文件的方法数,重点讲述了dex-method-counts工具的工作原理,包括解析Dex文件、构建类信息的多叉树结构等步骤。
摘要由CSDN通过智能技术生成

dex文件结构简介

Android平台中没有直接使用Class文件格式,因为早期的Anrdroid手机内存,存储都比较小,而Class文件显然有很多可以优化的地方,比如每个Class文件都有一个常量池,里边存储了一些字符串。一串内容完全相同的字符串很有可能在不同的Class文件的常量池中存在,这就是一个可以优化的地方。当然,Dex文件结构和Class文件结构差异的地方还很多,但是从携带的信息上来看,Dex和Class文件是一致的。所以,你了解了Class文件(作为Java VM官方Spec的标准),Dex文件结构只不过是一个变种罢了(从学习到什么程度为止的问题来看,如果不是要自己来解析Dex文件,或者反编译/修改dex文件,我觉得大致了解下Dex文件结构的情况就可以了)。图1所示为Dex文件结构的概貌:
这里写图片描述

有一点需要说明:传统Class文件是一个Java源码文件会生成一个.Class文件,而Android是把所有Class文件进行合并,优化,然后生成一个最终的class.dex,如此,多个Class文件里如果有重复的字符串,当把它们都放到一个dex文件的时候,只要一份就可以了嘛。

dex头部信息中的magic取值为“dex\n035\0”

proto_ids:描述函数原型信息,包括返回值,参数信息。比如“test:()V”

methods_ids:函数信息,包括所属类及对应的proto信息。比如

“Lcom.test.TestMain. test:()V”,.前面是类信息,后面属于proto信息

可以通过dexdump工具来分析Dex,dexdump.exe位于Andorid SDK的build-tools下,

首先看下dexdump的命令行参数:

dexdump: [-c] [-d] [-f] [-h] [-i] [-l layout] [-m] [-t tempfile] 
dexfile…

-c : verify checksum and exit 
-d : disassemble code sections 
-f : display summary information from file header 
-h : display file header details 
-i : ignore checksum failures 
-l : output layout, either ‘plain’ or ‘xml’ 
-m : dump register maps (and nothing else) 
-t : temp file name (defaults to /sdcard/dex-temp-*)

使用-h命令输出的dex文件的Header结构如下图所示:

这里写图片描述

那么如何统计dex文件的方法数呢,目前经常用来进行方法数统计的是dex-method-counts

现在分析dex-method-counts的源码:

首先解析输入参数,这里获取到了输入参数为dex或者APK文件
开启循环解析每一个APK或者dex
  • 如果是APK文件则作为zip打开,将APK中的所有class*.dex作为RandomAccessFile读取出来,并放在List 中,如果是.dex文件,则作为RandomAccessFile读取出来,并放在List 中
  • 开启循环解析每一个RandomAccessFile
    • 将Dex文件使用DexData数据结构进行解析,主要解析方法在DexData类的load方法中
    • load方法包含以下几个方法:
parseHeaderItem();
loadStrings();
loadTypeIds();
loadProtoIds();
loadFieldIds();
loadMethodIds();
loadClassDefs();
markInternalClasses();

parseHeaderItem

解析dex的头部信息,创建了一个HeaderItem静态内部类,该类是按照Dex的Header中的信息创建的:

  /**
     * Holds the contents of a header_item.
     */
    static class HeaderItem {
        public int fileSize;
        public int headerSize;
        public int endianTag;
        public int stringIdsSize, stringIdsOff;
        public int typeIdsSize, typeIdsOff;
        public int protoIdsSize, protoIdsOff;
        public int fieldIdsSize, fieldIdsOff;
        public int methodIdsSize, methodIdsOff;
        public int classDef
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值