# HG changeset patch # User Thinker K.F. Li # Date 1306202213 -28800 # Node ID b0766f1984bb3dc9a77ae1b42e0a2e023cd713aa # Parent a78db169b0c835a13d24c7d547f5bdfda283a85e parse annotationsDirectoryItem diff -r a78db169b0c8 -r b0766f1984bb paraspace/dexfile.py --- a/paraspace/dexfile.py Mon May 23 21:44:58 2011 +0800 +++ b/paraspace/dexfile.py Tue May 24 09:56:53 2011 +0800 @@ -58,7 +58,7 @@ self.off = off pass - def __call__(self, sz): + def __call__(self, sz=0): off = self.off self.off = off + sz return off @@ -550,8 +550,23 @@ pass +## \brief File offset to Annotation item. +# +# This type is not in libdex of Dalvik. We add this class to tracking +# information for layout algorithm. +# +class _DEX_AnnotationRefItem(object): + annotationOff = None # 4 bytes + + data_size = 4 + + def parse(self, data, off): + self.annotationOff = _to_uint(data[off:off + 4]) + pass + pass + class _DEX_AnnotationSetItem(object): - size = None # 4 bytes + # size = None # 4 bytes annotations = None # 4 * size bytes data_size = None @@ -559,11 +574,109 @@ def parse(self, data, off): moff = man_off(off) - self.size = _to_uint(data[moff(4):moff(0)]) - self.annotations = [_to_uint(data[moff(4):moff(0)]) - for i in range(self.size)] + size = _to_uint(data[moff(4):moff()]) + + def parse_annotation_ref(): + ref = _DEX_AnnotationRefItem() + ref.parse(data, moff()) + moff(ref.data_size) + return ref + + self.annotations = [parse_annotation_ref() + for i in range(size)] + + self.data_size = moff() - off + pass + pass + + +class _DEX_FieldAnnotationsItem(object): + fieldIdx = None # 4 bytes + annotationsOff = None # 4 bytes + + data_size = 8 + + def parse(self, data, off): + moff = man_off(off) + + self.fieldIdx = _to_uint(data[moff(4):moff()]) + self.annotationsOff = _to_uint(data[moff(4):moff()]) + pass + pass + + +class _DEX_MethodAnnotationsItem(object): + methodIdx = None # 4 bytes + annotationsOff = None # 4 bytes + + data_size = 8 + + def parse(self, data, off): + moff = man_off(off) + + self.methodIdx = _to_uint(data[moff(4):moff()]) + self.annotationsOff = _to_uint(data[moff(4):moff()]) + pass + pass + + +class _DEX_ParameterAnnotationsItem(object): + methodIdx = None # 4 bytes + annotationsOff = None # 4 bytes + + data_size = 8 - self.data_size = moff(0) - off + def parse(self, data, off): + moff = man_off(off) + + self.methodIdx = _to_uint(data[moff(4):moff()]) + self.annotationsOff = _to_uint(data[moff(4):moff()]) + pass + pass + + +class _DEX_AnnotationsDirectoryItem(object): + classAnnotationsOff = None # 4 bytes + fieldAnnotationsItems = None + methodAnnotationsItems = None + parameterAnnotationsItems = None + + data_size = None + + def parse(self, data, off): + moff = man_off(off) + + self.classAnnotationsOff = _to_uint(data[moff(4):moff()]) + fieldsSize = _to_uint(data[moff(4):moff()]) + methodsSize = _to_uint(data[moff(4):moff()]) + parametersSize = _to_uint(data[moff(4):moff()]) + + def parse_fieldAnnotationsItem(): + item = _DEX_FieldAnnotationsItem() + item.parse(data, moff()) + moff(item.data_size) + return item + + def parse_methodAnnotationsItem(): + item = _DEX_MethodAnnotationsItem() + item.parse(data, moff()) + moff(item.data_size) + return item + + def parse_parameterAnnotationsItem(): + item = _DEX_ParameterAnnotationsItem() + item.parse(data, moff()) + moff(item.data_size) + return item + + self.fieldAnnotationsItems = [parse_fieldAnnotationsItem() + for i in range(fieldsSize)] + self.methodAnnotationsItems = [parse_methodAnnotationsItem() + for i in range(methodsSize)] + self.parameterAnnotationsItems = [parse_parameterAnnotationsItem() + for i in range(parametersSize)] + + self.data_size = moff() - off pass pass @@ -582,6 +695,7 @@ _typeLists = None _codeItems = None _annotationSetItems = None + _annotationsDirectoryItems = None def __init__(self): pass @@ -821,7 +935,7 @@ def parse_annotationSetItem(): item = _DEX_AnnotationSetItem() - item.parse(data, moff(0)) + item.parse(data, moff()) moff(item.data_size) return item @@ -829,6 +943,24 @@ for i in range(annoset_map.size)] pass + def _parse_annotationsDirectoryItems(self): + data = self._data + + annodir_map = \ + self.find_map_item_name('kDexTypeAnnotationsDirectoryItem') + + moff = man_off(annodir_map.offset) + + def parse_annotationDirItem(): + item = _DEX_AnnotationsDirectoryItem() + item.parse(data, moff()) + moff(item.data_size) + return item + + self._annotationsDirectoryItems = [parse_annotationDirItem() + for i in range(annodir_map.size)] + pass + def parse(self, data): self._data = data header = _DEX_header() @@ -846,6 +978,7 @@ self._parse_typeLists() self._parse_codeItems() self._parse_annotationSetItems() + self._parse_annotationsDirectoryItems() pass pass @@ -909,6 +1042,11 @@ print print 'AnnotationSetItems size is %d bytes' % (bytes) + bytes = sum([annodir.data_size + for annodir in dex._annotationsDirectoryItems]) + print + print 'AnnotationsDirtoryItems size is %d bytes' % (bytes) + print print 'Data maps' maps = dex._maps