dex文件入门(二)

proto_ids_size/offset

        proto指方法的原型,此处的原型指的是只有返回类型与参数类型(链接)。偏移offset后,存储的结构体如下:

struct proto_id_item
{
uint shorty_idx;
uint return_type_idx;
uint parameters_off;
}
        从上面可以看出,每一个proto_id_item占12个字节。

        shorty_idx与前面的type一样,指的是string_item中的下标,由该下标可得一个字符串,这个字符串就是方法的原型。此时要注意:L代表的是引用数据类型,并不是某个基础数据类型。

        return_type_idx指的是前面的type的下标(因为有多个type,这些type构成一个数组,而该下标就是用来获取这个type的),指方法返回值类型

        parameters_offset:指方法的参数的偏移量。每一个参数的结构体如下:

struct type_list
{
uint size;
ushort type_idx[size];
}

        从中可以看出,参数的字节数是不固定的,但第一个字节永远是用来标识参数的个数的。后面的字节中,每两个字节表示该参数对应的type下标,根据type下标就可以得到参数的字符串描述了如果参数的个数为奇数个,那么最后两个字节补0,使字节数为4的整数倍。

        注意:如果parameters_offset为0,则表示该方法木有参数。并且,原型中,第一个表示返回值类型。

示例:有一dex文件,其header部分如下:

根据其offset,得到其部分proto_id_item如下:


        每一个proto_id_item占12个字节,取其第五个(即0x1298)做为分析。

        首先看其原型。1298中存储的值是0x93,即string_item中下标为93的string,这个位置对应的字符串偏移量为0x9be0,值为IILL。如下:


        再看其返回值。129c中存储的值是0x1,即type数组中下标为1的type。这个位置对应的string下标为8b,再查找得string的偏移量为0x9b74,值为I。

        最后看其偏移量为0x8bd8。如下:


        从中可以看出,一共有3个参数(0x8bd8指定),第一个参数为type[0x1],第二个参数为type[0x27],第三个为type[0x6e]。

        在分析返回值的时候,知道type[1]对应的string为I。而type[27]对应的是string[0xdf],再对应的string偏移量为0xA2c7,此处值为”Lcom/android/tools/fd/runtime/ApplicationPatch;“,是一个引用数据类型。type[0x6e]对应的是string[0x012d],对应的string偏移量为ad4e,此处值为”Ljava/lang/String;“,也是一个引用数据类型。

小结

        分析了string,type,proto三个值。总结一下:

        1,string是最方便的,查找到偏移量,根据字节大小,读取相应的字节即可。

        2,对于type,首先要找到该type对应的string下标,根据string下标,得到这个string的偏移量,再得到type的描述信息。

        3,proto。得到偏移量。再得到相应的原型对应的string下标,进而得到string的偏移量,最后才得到原型对应的字符串。得到偏移量后,也就得到了返回值对应的type下标,根据type的算法又得到返回值对应的字符串。得到偏移量后,得到参数offset,进而知道有多少个参数,每一个参数对应的type下标,最后才得到每一个参数对应的字符串。

        4,在header中,size与offset都是四个字节表示的。表示string,type,proto的偏移量时也是四个字节。由string偏移量得到string的值时,具体几个字节由第一个字节决定。

        5,proto的params_offset具体的字节数是不固定的,由方法中参数个数决定。不够补0,凑够4的整数倍。

        6,所有涉及到类型的,都是type的下标,所以涉及到string的都是string的下标。

field_ids_size/offset

        字段的个数与偏移量。结构体为

struct filed_id_item
{
ushort class_idx;
ushort type_idx;
uint name_idx;
}
        第一个字段表示fiele所属的类的类型,第二个表示field本身的类型,第三个表示field的名字。除了最后一个代表着string的下标外,其余两个都是type的下标。

        具体获取过程与上面一样,根据type的下标获取该type在string中的下标,从而得到字符串的偏移量,再得到string本身。

method_ids_size/offset

其对应的数据结构为:

struct filed_id_item
{
ushort class_idx;
ushort proto_idx;
uint name_idx;
}
        第一个为该方法所属的class的类型,它的值是type的index。第二个为方法的原型,是proto的一个index。第三个为方法名,为string的一个index。

        首先通过class_index得到方法所属的类,再通过proto_idx得到方法的框架(含返回值类型,参数列表),最后通过name_idx得到方法名。这样就凑齐方法了。

class_def_size/offset

        描述了class的定义。它存储的item的结构体如下:

struct class_def_item
{
uint class_idx;
uint access_flags;
uint superclass_idx;
uint interfaces_off;

uint source_file_idx;
uint annotations_off;
uint class_data_off;
uint static_value_off;
}
        class_idx描述了类的类型,是type的index。

        access_flags描述了类的访问类型。如public static final等。
        superclass_idx:描述了父类,是type的index。

        interface_off:接口。它指向的是接口的偏移量,被指向的为type_list(因为一个类可能用多个接口,所以是list),每一个是一个type的下标。若没有接口,则为0。

        source_file_idx:源文件对应的string的index。

        annotations_off:注释的偏移量。对应的结构为annotations_direcotry_item,如果没有此项内容,则值为0。

        class_data_off:该class使用到的数据的偏移量,对应的结构为class_data_item,若没有此内容,则值为0。

        static_value_off:值为一个偏移量,对应的结构为encoded_array_item。若没有,则值为0。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值