diff paraspace/tests/injection_test.py @ 105:f14c32108164

Test dexfile_redirect_types
author Thinker K.F. Li <thinker@codemud.net>
date Thu, 28 Jul 2011 13:25:55 +0800
parents 355986e5cfbd
children 7821c6e89622
line wrap: on
line diff
--- a/paraspace/tests/injection_test.py	Thu Jul 28 00:06:54 2011 +0800
+++ b/paraspace/tests/injection_test.py	Thu Jul 28 13:25:55 2011 +0800
@@ -5,6 +5,7 @@
     global dexfile
     import imp, sys
     from paraspace import dex_deptracker
+    from paraspace import injection
     
     try:
         new_dexfile = imp.load_compiled('dexfile', dexfile.__file__)
@@ -14,6 +15,9 @@
     dex_deptracker.dexfile = new_dexfile
     dexfile = new_dexfile
     dex_deptracker._nest_types = (dexfile.array, dexfile.cond, dexfile.switch)
+
+    injection.dex_type_2_array_attr_map = \
+        injection._saved_dex_type_2_array_attr_map
     
     sys.modules['paraspace.dexfile'] = new_dexfile
     pass
@@ -98,3 +102,78 @@
     assert codeitems_map.size == saved_codeitems_sz + 1
     pass
 
+
+def redirect_types_test():
+    from paraspace.dex_deptracker import prepare_dep_decls
+    from paraspace.injection import dexfile_insert_class
+    from paraspace.injection import dexfile_redirect_types
+    from paraspace import dalvik_opcodes
+    
+    _install_dexfile_4_deptracker()
+    
+    all_dep_decls = prepare_dep_decls()
+    
+    srcdir = os.path.dirname(__file__)
+    srcroot = os.path.join(srcdir, '..', '..')
+    
+    helloworld_fn = os.path.join(srcroot, 'data', 'helloworld.dex')
+    helloworld_dex = dexfile.DEXFile.open(helloworld_fn)
+
+    classdef_map = _find_map(helloworld_dex, 0x0006)
+    saved_classdef_map_sz = classdef_map.size
+    saved_methodids_sz = len(helloworld_dex.methodIds.items)
+    
+    codeitems_map = _find_map(helloworld_dex, 0x2001)
+    saved_codeitems_sz = codeitems_map.size
+
+    helloworld_linked = \
+        dexfile.DEXFile_linked.build_dependencies(helloworld_dex,
+                                                  all_dep_decls)
+
+    fakefile_fn = os.path.join(srcroot, 'data', 'fakefile.dex')
+    fakefile_dex = dexfile.DEXFile.open(fakefile_fn)
+    fakefile_linked = \
+        dexfile.DEXFile_linked. \
+        build_dependencies(fakefile_dex, all_dep_decls)
+    
+    print helloworld_linked.codeItems.items
+    fakefile_def = \
+        fakefile_linked.find_class_name('Lcom/codemud/fakefile/fakefile;')
+    clone = dexfile_insert_class(helloworld_linked, fakefile_def)
+
+    File_typeid = helloworld_linked.find_typeid_name('Ljava/io/File;')
+    assert File_typeid
+    File_typeidx = helloworld_linked.get_idx_typeid(File_typeid)
+
+    clone_typeidx = helloworld_linked.get_idx_typeid(clone.classIdx)
+
+    redirect_map = {File_typeidx: clone_typeidx}
+    excludes = set([clone_typeidx])
+    
+    fakefile_data = clone.classDataOffRef.value
+    fakefile_methods = fakefile_data.directMethods.items
+    fakefile_codes = [method.codeOffRef.value for method in fakefile_methods]
+    print clone.classDataOffRef.value, fakefile_def.classDataOffRef.value
+    print fakefile_def.classDataOffRef.value.directMethods.items
+    print fakefile_methods
+    print [method.codeOffRef.value for method in fakefile_def.classDataOffRef.value.directMethods.items]
+    print fakefile_codes
+    
+    dexfile_redirect_types(helloworld_linked, redirect_map, excludes)
+
+    print helloworld_linked.codeItems.items
+    for code in helloworld_linked.codeItems.items:
+        print code
+        op_vectors = dalvik_opcodes.decode_insn_blk(code.insns.data)
+        for opcode, args in op_vectors:
+            if opcode == dalvik_opcodes.all_opcodes.OP_NEW_INSTANCE:
+                assert args[1] != File_typeidx
+                pass
+            elif opcode == dalvik_opcodes.all_opcodes.OP_INVOKE_DIRECT:
+                methodid = helloworld_linked.find_methodid_idx(args[2])
+                assert methodid.classIdx != File_typeid or \
+                    code in fakefile_codes
+                pass
+            pass
+        pass
+    pass