• DEX文件解析--4、dex类的类型解析


    一、前言

      前几篇系列文章链接:
        DEX文件解析---1、dex文件头解析
        DEX文件解析---2、Dex文件checksum(校验和)解析
        DEX文件解析--3、dex文件字符串解析


    二、DEX文件中的类的类型

        1、Dex文件中关于类的类型需要知道字符串是怎么解析的,如果不知道的,可以看一下我的上一篇文章。好了,切入正题,关于类的类型,就是一个对象的所属的类(大概这么理解吧。。。),例如在java中一个字符串,它的类型就是java/lang/String。在Dex文件头中,跟类的类型有关的一共有八个字节,分别是位于0x40处占四个字节表示类的类型的数量和位于0x44处占四个字节表示类的类型索引值的起始偏移地址,如下所示:

    3.png

        2、关于类的类型数量,没什么好说的,只需要注意它是以小端序存储的,读取的时候注意即可。对于类的类型偏移地址,找到偏移地址后,它是以四个字节为一组,对应了在解析出来的字符串数组中的索引值,例如下图中的第一组,它的数据是BE 04 00 00,我们读取出来就是0x04BE(同样采用的小端序存储),对应的类的类型就是字符串数组[0x04be]

    4.png


    三、解析脚本

     PS:我电脑上脚本运行环境python3.6

    运行效果:

    1.png

    2.png

    代码如下:

    import binascii
    import os
    import sys
    
    def getStringsCount(f):
        f.seek(0x38)
        stringsId = f.read(4)
        a = bytearray(stringsId)
        a.reverse()
        stringsId = bytes(a)
        stringsId = str(binascii.b2a_hex(stringsId),encoding='UTF-8')
        count = int(stringsId,16)
        return count
    
    def getStringByteArr(f,addr):
        byteArr = bytearray()
        f.seek(addr + 1)
        b = f.read(1)
        b = str(binascii.b2a_hex(b),encoding='UTF-8')
        b = int(b,16)
        index = 2
        while b != 0:
            byteArr.append(b)
            f.seek(addr + index)
            b = f.read(1)
            b = str(binascii.b2a_hex(b),encoding='UTF-8')
            b = int(b,16)
            index = index + 1
        return byteArr
    
    def BytesToString(byteArr):
        try:
            bs = bytes(byteArr)
            stringItem = str(bs,encoding='UTF-8')
            return stringItem
        except:
            pass
    
    def getAddress(addr):
        address = bytearray(addr)
        address.reverse()
        address = bytes(address)
        address = str(binascii.b2a_hex(address),encoding='UTF-8')
        address = int(address,16)
        return address
    
    def getStrings(f,stringAmount):
        stringsList = []
        f.seek(0x3c)
        stringOff = f.read(4)
        Off = getAddress(stringOff)
        f.seek(Off)
        for i in range(stringAmount):
            addr = f.read(4)
            address = getAddress(addr)
            byteArr = getStringByteArr(f,address)
            stringItem = BytesToString(byteArr)
            stringsList.append(stringItem)
            Off = Off + 4
            f.seek(Off)
        return stringsList
    
    def getTypeAmount(f):
        f.seek(0x40)
        stringsId = f.read(4)
        a = bytearray(stringsId)
        a.reverse()
        stringsId = bytes(a)
        stringsId = str(binascii.b2a_hex(stringsId),encoding='UTF-8')
        count = int(stringsId,16)
        return count
    
    def getTypeItem(f,count,strLists):
        f.seek(0x44)
        type_ids_off = f.read(4)
        a = bytearray(type_ids_off)
        a.reverse()
        type_ids_off = bytes(a)
        type_ids_off = binascii.b2a_hex(type_ids_off)
        type_ids_off = str(type_ids_off,encoding='utf-8')
        type_off = int(type_ids_off,16)
        f.seek(type_off)
        print('[+] type count ==> ',end='')
        print(count)
        for i in range(count):
            typeIndex = f.read(4)
            b = bytearray(typeIndex)
            b.reverse()
            typeIndex = bytes(b)
            typeIndex = binascii.b2a_hex(typeIndex)
            typeIndex = int(str(typeIndex,encoding='UTF-8'),16)
            print('[*] typeItem ==> ',end='')
            print(strLists[typeIndex])
            type_off = type_off + 0x04
            f.seek(type_off)
    
    if __name__ == '__main__':
        filename = str(os.path.join(sys.path[0])) + '\1.dex'
        f = open(filename,'rb',True)
        stringsCount = getStringsCount(f)
        strList = getStrings(f,stringsCount)
        typeCount = getTypeAmount(f)
        getTypeItem(f,typeCount,strList)
        f.close()
    

    四、样本以及代码下载链接

      百度网盘:https://pan.baidu.com/s/1Z1nn8hroxX-2jGaKvhmIZQ;提取码:1eao

  • 相关阅读:
    Linux下Apache服务器并发优化
    centos 7 mount win共享文件夹 开机自动挂载
    自学 phpredis 的心路历程
    VM虚拟机下centos7 无法上网的问题解决办法
    php headers_sent 函数的作用
    is_file 与 file_exists 的区别
    php 面向对象 中的self
    php 去除所有空格 包括中文空格圆角空格
    滑动窗口滚动条触发事件
    PHP中file_exists与is_file、is_dir的区别,以及执行效率的比较 转自#冰雪傲骨#
  • 原文地址:https://www.cnblogs.com/aWxvdmVseXc0/p/12661142.html
Copyright © 2020-2023  润新知