# HG changeset patch # User Thinker K.F. Li # Date 1305994317 -28800 # Node ID 31050a971b52d4e95adc79b15bdecfabb5b61363 Project ParaSpace diff -r 000000000000 -r 31050a971b52 paraspace/dexfile.py --- /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