changeset 140:d4e794249b0f

Fixing back to back association and encoding issue
author Thinker K.F. Li <thinker@codemud.net>
date Thu, 11 Aug 2011 09:20:46 +0800
parents 0704e23009e4
children 90690a001172
files paraspace/dex_deptracker.py paraspace/dexfile.py paraspace/tests/injection_test.py
diffstat 3 files changed, 78 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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 ' \
--- 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)