changeset 0:31050a971b52

Project ParaSpace
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 22 May 2011 00:11:57 +0800
parents
children 05346b632adb
files paraspace/dexfile.py
diffstat 1 files changed, 171 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paraspace/dexfile.py	Sun May 22 00:11:57 2011 +0800
@@ -0,0 +1,171 @@
+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