# HG changeset patch # User Thinker K.F. Li # Date 1313025646 -28800 # Node ID d4e794249b0f91c32bc351f7eee1448620426113 # Parent 0704e23009e4a84ec0ac80a13599787a174f75ec Fixing back to back association and encoding issue diff -r 0704e23009e4 -r d4e794249b0f paraspace/dex_deptracker.py --- a/paraspace/dex_deptracker.py Wed Aug 10 20:05:14 2011 +0800 +++ b/paraspace/dex_deptracker.py Thu Aug 11 09:20:46 2011 +0800 @@ -944,10 +944,10 @@ return name_path moff = man_off(0) - queue = [(dexroot, 'DEXFile', None)] + queue = [(dexroot, 'DEXFile', None, None)] while queue: - obj, name_path, parent = queue.pop() + obj, name_path, parent, grand = queue.pop() obj_clazz, parent_clazz = _resolve_name_path(name_path) if isinstance(obj_clazz, dexfile.depend): @@ -969,7 +969,7 @@ pass if isinstance(obj, (tuple, list)): - attrs = [(elt, make_path(elt, name_path, str(idx)), obj) + attrs = [(elt, make_path(elt, name_path, str(idx)), obj, parent) for idx, elt in enumerate(obj)] attrs.reverse() queue = queue + attrs @@ -991,7 +991,7 @@ children = obj.children() attr_n_names = [(_dex_tree_get_child(obj, child_name), child_name) for child_name in children] - attrs = [(attr, make_path(attr, name_path, attr_name), obj) + attrs = [(attr, make_path(attr, name_path, attr_name), obj, parent) for attr, attr_name in attr_n_names] attrs.reverse() queue = queue + attrs diff -r 0704e23009e4 -r d4e794249b0f paraspace/dexfile.py --- a/paraspace/dexfile.py Wed Aug 10 20:05:14 2011 +0800 +++ b/paraspace/dexfile.py Thu Aug 11 09:20:46 2011 +0800 @@ -437,7 +437,16 @@ ## \brief Associate elements from left list to elements from right list # - def build_associations(self, left, right): + def build_associations(self, parent): + from paraspace.dex_deptracker import _dex_tree_get_child + from paraspace.dex_deptracker import _dex_tree_set_child + from paraspace.dex_deptracker import _split_name_path_clazz_attr + + left_attr = _split_name_path_clazz_attr(self.left) + right_attr = _split_name_path_clazz_attr(self.right) + left = _dex_tree_get_child(parent, left_attr) + right = _dex_tree_get_child(parent, right_attr) + assert len(left) == len(right) for le, re in map(None, left, right): self._update_refs(le, re) @@ -446,6 +455,42 @@ pass +## \brief Back to back association. +# +# For any two consequence elements in an array that applied this association, +# later element will depend on earlier one and/or in reversed. +# This type declares the association. +# +class back2back(_objs_asso): + def __init__(self, left, left_ref, right_ref): + if not isinstance(left, array): + raise TypeError, 'back_type must be an array' + self.left = left + self.right = left + self.left_ref = left_ref + self.right_ref = right_ref + pass + + def build_associations(self, parent): + from paraspace.dex_deptracker import _dex_tree_get_child + from paraspace.dex_deptracker import _dex_tree_set_child + from paraspace.dex_deptracker import _split_name_path_clazz_attr + + dummy, attr = _split_name_path_clazz_attr(self.left) + target_array = _dex_tree_get_child(parent, attr) + if not isinstance(target_array, array): + raise TypeError, 'left of %x must be an array' % (repr(self)) + + left_ref_attr = _split_name_path_clazz_attr(self.left_ref) + right_ref_attr = _split_name_path_clazz_attr(self.right_ref) + for left, right in map(None, target_array[:-1], target_array[1:]): + _dex_tree_set_child(left, left_ref_attr, right) + _dex_tree_set_child(right, right_ref_attr, left) + pass + pass + pass + + class relocatable(_dex_type): data_size = None @@ -617,6 +662,10 @@ pass +class array_relative(array): + pass + + class composite(relocatable): child_names = None @@ -905,24 +954,6 @@ class depend_idx(depend): - def sizeof(self, v): - from paraspace.dex_deptracker import _resolve_name_path - from paraspace.dex_deptracker import _skip_marker_clazz - - depon_clazz, dummy = _resolve_name_path(self.depend_on) - depon_clazz = _skip_marker_clazz(depon_clazz) - do_child_clazz = depon_clazz.child_type # depon_clazz must be an array - - if type(do_child_clazz) == type and \ - isinstance(v, do_child_clazz): - v = v.data_idx - elif type(do_child_clazz) != type and \ - isinstance(v, do_child_clazz.__class__): - v = v.data_idx - pass - v = self.back_type.sizeof(v) - return v - def compute_size(self, child): pass @@ -933,6 +964,26 @@ pass +class depend_idx_rel(depend): + def __init__(self, relative_to, depend_on): + super(depend_idx_rel, self).__init__(depend_on) + self.relative_to = relative_to + pass + + def compute_size(self, child): + pass + + def sizeof(self, child): + from paraspace.dex_deptracker import _dex_tree_set_child + + relative = _dex_tree_get_child([child], self.relative_to) + + if isinstance(child, composite): + return self.back_type.sizeof(child.data_idx - relative.data_idx) + return self.back_type.sizeof(child - relative) + pass + + class _DEX_header(composite): magic = rawstr(8) checksum = uint32 @@ -1190,10 +1241,10 @@ class _DEX_ClassData(composite): header = _DEX_ClassDataHeader - staticFields = array('header.staticFieldsSize', _DEX_Field) - instanceFields = array('header.instanceFieldsSize', _DEX_Field) - directMethods = array('header.directMethodsSize', _DEX_Method) - virtualMethods = array('header.virtualMethodsSize', _DEX_Method) + staticFields = array_relative('header.staticFieldsSize', _DEX_Field) + instanceFields = array_relative('header.instanceFieldsSize', _DEX_Field) + directMethods = array_relative('header.directMethodsSize', _DEX_Method) + virtualMethods = array_relative('header.virtualMethodsSize', _DEX_Method) child_names = \ 'header ' \ diff -r 0704e23009e4 -r d4e794249b0f paraspace/tests/injection_test.py --- a/paraspace/tests/injection_test.py Wed Aug 10 20:05:14 2011 +0800 +++ b/paraspace/tests/injection_test.py Thu Aug 11 09:20:46 2011 +0800 @@ -641,7 +641,6 @@ hello_linked.find_methodids_typeid(helloworld_typeid) for methodid in helloworld_methodids: methodname = hello_linked.get_methodid_name(methodid) - print 'TEST', methodname if methodname == 'onClick': methodidx = hello_linked.get_idx_methodid(methodid) method = hello_linked.find_method_idx(methodidx) @@ -654,7 +653,6 @@ elif methodname == 'write_file': assert methodid in hello_linked.methodIds.items methodidx = hello_linked.get_idx_methodid(methodid) - print 'TEST', dexfile.DEXFile_linked.get_typeid_name(methodid.classIdx) method = hello_linked.find_method_idx(methodidx) blk = dexfile.DEXFile_linked.get_code_block_method(method) opvectors = decode_insn_blk(blk)