# HG changeset patch # User Thinker K.F. Li # Date 1311830755 -28800 # Node ID f14c32108164e0bb44adb03e9b7de712676dbee5 # Parent 61cef1662035433a6fee16a8b32ce9b1cca46ead Test dexfile_redirect_types diff -r 61cef1662035 -r f14c32108164 paraspace/injection.py --- a/paraspace/injection.py Thu Jul 28 00:06:54 2011 +0800 +++ b/paraspace/injection.py Thu Jul 28 13:25:55 2011 +0800 @@ -65,6 +65,9 @@ return type_2_attr +_saved_dex_type_2_array_attr_map = dex_type_2_array_attr_map + + ## \brief Append a object to appropriate list of a DEXFile object. # # Skip the object if found no appropriate list. @@ -99,6 +102,8 @@ from copy import copy from paraspace.dexfile import _DEX_StringDataItem, _DEX_StringId from paraspace.dexfile import _DEX_TypeId + from paraspace.dex_deptracker import _dex_tree_set_child + from paraspace.dex_deptracker import _dex_tree_get_child visit_log = {} @@ -108,9 +113,11 @@ def relink_dependencies(clone): rel_children = _relocatable_children(clone) + print clone for attr, value in rel_children: clone_value = visit_log[id(value)] - setattr(clone, attr, clone_value) + print attr, _dex_tree_get_child(clone, attr), clone_value + _dex_tree_set_child(clone, attr, clone_value) pass pass @@ -180,6 +187,7 @@ merge_unique_strid() merge_unique_typeid() + print visit_log for obj in visit_log.values(): if isinstance(obj, (_DEX_StringDataItem, _DEX_StringId, @@ -234,7 +242,7 @@ methodidx = args[2] methodid = dex.find_methodid_idx(methodidx) method_typeid = methodid.classIdx - method_typeidx = dex.get_idx_typeid(method_typeidx) + method_typeidx = dex.get_idx_typeid(method_typeid) if method_typeidx not in redirect_map: return opcode, args @@ -279,7 +287,7 @@ def dexfile_redirect_types(dex, redirect_map, excludes=set([])): for classdef in dex.classDefs.items: typeid = classdef.classIdx - idx = dex.get_index_typeid(typeid) + idx = dex.get_idx_typeid(typeid) if idx in excludes: continue class_redirect_types(dex, classdef, redirect_map) diff -r 61cef1662035 -r f14c32108164 paraspace/tests/injection_test.py --- 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