view paraspace/dexfile.py @ 0:31050a971b52

Project ParaSpace
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 22 May 2011 00:11:57 +0800
parents
children 05346b632adb
line wrap: on
line source

class _DEX_header(object):
    magic = None                # 0x00, 8 bytes
    checksum = None             # 0x08, 4 bytes
    signature = None            # 0x0c, 20 bytes
    fileSize = None             # 0x20, 4 bytes
    headerSize = None           # 0x24
    endianTag = None            # 0x28
    linkSize = None             # 0x2c
    linkOff = None              # 0x30
    mapOff = None               # 0x34
    stringIdsSize = None        # 0x38
    stringIdsOff = None         # 0x3c
    typeIdsSize = None          # 0x40
    typeIdsOff = None           # 0x44
    protoIdsSize = None         # 0x48
    protoIdsOff = None          # 0x4c
    fieldIdsSize = None         # 0x50
    fieldIdsOff = None          # 0x54
    methodIdsSize = None        # 0x58
    methodIdsOff = None         # 0x5c
    classDefsSize = None        # 0x60
    classDefsOff = None         # 0x64
    dataSize = None             # 0x68
    dataOff = None              # 0x6c

    def parse(self, data):
        self.magic = data[:8]
        self.checksum = data[8: 0x0c]
        self.signature = data[0x0c: 0x20]
        
        idx = 0x20
        fields = 'fileSize headerSize endianTag linkSize linkOff mapOff ' \
            'stringIdsSize stringIdsOff typeIdsSize typeIdsOff ' \
            'protoIdsSize protoIdsOff fieldIdsSize fieldIdsOff ' \
            'methodIdsSize methodIdsOff classDefsSize classDefsOff ' \
            'dataSize dataOff'.split()
        for field in fields:
            d = data[idx: idx + 4]
            value = _to_uint(d)
            setattr(self, field, value)
            idx = idx + 4
            pass
        pass
    pass


def _to_uint(data):
    v = 0
    for c in data:
        v = (v << 8) + ord(c)
        pass
    return v


class _DEX_MapItem(object):
    type = None                 # 2 bytes
    unused = None               # 2 bytes
    size = None                 # 4 bytes
    offset = None               # 4 bytes

    data_size = 12

    def parse(self, data):
        self.type = _to_uint(data[:2])
        self.size = _to_uint(data[4:8])
        self.offset = _to_uint(data[8:12])
        pass
    pass

class _DEX_TypeId(object):
    descriptorIdx = None       # 4 bytes
    
    data_size = 4

    def parse(self, data):
        self.descriptorIdx = _to_uint(data[:4])
        pass
    pass


class _DEX_ProtoId(object):
    shortyIdx = None           # 4 bytes
    returnTypeIdx = None       # 4 bytes
    parametersOff = None       # 4 bytes
    
    data_size = 12

    def parse(self, data):
        self.shortyIdx = _to_uint(data[:4])
        self.returnTypeIdx = _to_uint(data[4:8])
        self.parametersOff = _to_uint(data[8:12])
        pass
    pass


class _DEX_FieldId(object):
    classIdx                    # 2 bytes
    typeIdx                     # 2 bytes
    nameIdx                     # 4 bytes
    
    data_size = 8

    def parse(self, data):
        self.classIdx = _to_uint(data[:2])
        self.typeIdx = _to_uint(data[2:4])
        self.nameIdx = _to_uint(data[4:8])
        pass
    pass


class _DEX_MethodId(object):
    classIdx                    # 2 bytes
    protoIdx                    # 2 bytes
    nameIdx                     # 4 bytes
    
    data_size = 8

    def parse(self, data):
        self.classIdx = _to_uint(data[:2])
        self.protoIdx = _to_uint(data[2:4])
        self.nameIdx = _to_uint(data[4:8])
        pass
    pass

class _DEX_ClassDef(object):
    classIdx = None             # 0x00
    accessFlags = None          # 0x04
    superclassIdx = None        # 0x08
    interfacesOff = None        # 0x0c
    sourceFileIdx = None        # 0x10
    annotationsOff = None       # 0x14
    classDataOff = None         # 0x18
    staticValuesOff = None      # 0x1c
    
    data_size = 0x20

    def parse(self, data):
        self.classIdx = _to_uint(data[:4])
        self.accessFlags = _to_uint(data[4:8])
        self.superclassIdx = _to_uint(data[8:0xc])
        self.interfacesOff = _to_uint(data[0xc:0x10])
        self.sourceFileIdx = _to_uint(data[0x10:0x14])
        self.annotationsOff = _to_uint(data[0x14:0x18])
        self.classDataOff = _to_uint(data[0x18:0x1c])
        self.staticValuesOff = _to_uint(data[0x1c:0x20])
        pass
    pass


class DEXFile(object):
    _data = None
    _header = None
    _strings = None
    
    def __init__(self):
        pass

    def open(self, filename):
        fo = file(filename)
        data = fo.read()

        self.parse(data)
        pass

    def parse(self, data):
        self._data = data
        header = _DEX_header()
        header.parse(data)
        self._header = header
        pass
    pass