# HG changeset patch # User Thinker K.F. Li # Date 1313393139 -28800 # Node ID c4324c3461e8349ef6eb6076c23487beee7972ca # Parent 46e40afd45586028ae1616e05db20dad48f970ef Redirect string indices. - Change names of *redirect_types*() to *redirect_indices*(). - Redirect string indices in method_redirect_indices() too. diff -r 46e40afd4558 -r c4324c3461e8 paraspace/injection.py --- a/paraspace/injection.py Mon Aug 15 11:13:56 2011 +0800 +++ b/paraspace/injection.py Mon Aug 15 15:25:39 2011 +0800 @@ -387,8 +387,9 @@ return cloning_classdefs, cloning_typeids -## \brief Redirect types and methods for the code of given method. -def method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir): +## \brief Redirect types, methods and strings for the code of given method. +def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, + stridxs_redir): from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes from paraspace.dalvik_opcodes import encode_opcode_vectors from paraspace.dexfile import DEXFile_linked @@ -428,6 +429,12 @@ return opcode, args return opcode, (args[0], methods_redir[methodidx], args[2]) + elif opcode == all_opcodes.OP_CONST_STRING: + stridx = args[1] + if stridx not in stridxs_redir: + return opcode, args + + return opcode, (args[0], stridxs_redir[stridx]) return opcode, args new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] @@ -475,18 +482,22 @@ # \param dex is a DEXFile_linked. # \param classdef is a class definition. # \param typeidxs_redir is a map of types. +# \param stridxs_redir is a map of strings. # \param methods_redir is a map of methods. # -def class_redirect_types(dex, classdef, typeidxs_redir, methods_redir): +def class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, + stridxs_redir): if not classdef.classDataOffRef.is_true: return classdata = classdef.classDataOffRef.value for method in classdata.directMethods.items: - method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir) + method_redirect_indices(dex, method, typeidxs_redir, methods_redir, + stridxs_redir) pass for method in classdata.virtualMethods.items: - method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir) + method_redirect_indices(dex, method, typeidxs_redir, methods_redir, + stridxs_redir) pass pass @@ -515,29 +526,50 @@ return methods_map +## \brief Make a map to map string indices from source to destinate DEX. +# +# \param dex_src is soruce of the mapping. +# \param dex_dst is destination of the mapping. +# \param classdefs is _DEX_ClassDefs from dex_src. +# \return a mapping for string indices. +# +def make_stridxs_redir_map(dex_src, dex_dst): + stridxs_map = {} + for idx, strid in enumerate(dex_src.stringIds.items): + try: + tgt_idx = dex_dst.stringIds.items.index(strid) + except ValueError: + continue + stridxs_map[idx] = tgt_idx + pass + return stridxs_map + + ## \biref Redirect types of all code in given DEXFile_linked. -def dexfile_redirect_types(dex, typeidxs_redir, methods_redir, - excludes=set([])): +def dexfile_redirect_indices(dex, typeidxs_redir, methods_redir, stridxs_redir, + excludes=set([])): for classdef in dex.classDefs.items: typeid = classdef.classIdx idx = dex.get_idx_typeid(typeid) if idx in excludes: continue - class_redirect_types(dex, classdef, typeidxs_redir, methods_redir) + class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, + stridxs_redir) pass pass ## \brief Redirect types for code of types specified by given indices. -def dexfile_redirect_types_typeidxs(dex, typeidxs_redir, methodidxs_redir, - typeidxs): +def dexfile_redirect_indices_typeidxs(dex, typeidxs_redir, methodidxs_redir, + stridxs_redir, typeidxs): typeidxs = set(typeidxs) for classdef in dex.classDefs.items: typeid = classdef.classIdx idx = dex.get_idx_typeid(typeid) if idx not in typeidxs: continue - class_redirect_types(dex, classdef, typeidxs_redir, methodidxs_redir) + class_redirect_indices(dex, classdef, typeidxs_redir, + methodidxs_redir, stridxs_redir) pass pass @@ -649,10 +681,14 @@ relative_typeids) methodidxs_redir = \ make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) + + stridxs_redir = \ + make_stridxs_redir_map(dex_src, dex_dst) - dexfile_redirect_types_typeidxs(dex_dst, typeidxs_redir, - methodidxs_redir, - typeidxs_redir.values()) + dexfile_redirect_indices_typeidxs(dex_dst, typeidxs_redir, + methodidxs_redir, + stridxs_redir, + typeidxs_redir.values()) pass @@ -676,6 +712,31 @@ return injected_classdefs +## \brief Redirect all references of given class and its methods. +# +# Redirect all references of given class and its methods to target class. +# +def redirect_type(dex, src_classname, tgt_classname, exclude_classnames): + src_typeid = dex.find_typeid_name(src_classname) + src_typeidx = dex.get_idx_typeid(src_typeid) + tgt_typeid = dex.find_typeid_name(tgt_classname) + tgt_typeidx = dex.get_idx_typeid(tgt_typeid) + typeidxs_redir = {src_typeidx: tgt_typeidx} + + methodidxs_redir = \ + make_methodidxs_redir_map(dex, dex, typeidxs_redir) + + stridxs_redir = {} + + ex_typeids = [dex.find_typeid_name(name) + for name in exclude_classnames] + ex_typeidxs = [dex.get_idx_typeid(typeid) + for typeid in ex_typeids] + dexfile_redirect_indices(dex, typeidxs_redir, methodidxs_redir, + stridxs_redir, excludes=ex_typeidxs) + pass + + ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. # # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, @@ -687,20 +748,9 @@ inj_classdef = src_linked.find_class_name(inj_classname) injected_classdefs = inject_classdefs(dst_linked, src_linked, [inj_classdef]) - - redir_typeid = dst_linked.find_typeid_name(redir_classname) - redir_typeidx = dst_linked.get_idx_typeid(redir_typeid) - inj_typeid = dst_linked.find_typeid_name(inj_classname) - inj_typeidx = dst_linked.get_idx_typeid(inj_typeid) - typeidxs_redir = {redir_typeidx: inj_typeidx} - - methodidxs_redir = \ - make_methodidxs_redir_map(dst_linked, dst_linked, typeidxs_redir) - - injected_typeidxs = [dst_linked.get_idx_classdef(classdef) - for classdef in injected_classdefs] - dexfile_redirect_types(dst_linked, typeidxs_redir, methodidxs_redir, - excludes=injected_typeidxs) + excludes = [dst_linked.get_classdef_name(classdef) + for classdef in injected_classdefs] + redirect_type(dst_linked, redir_classname, inj_classname, excludes) pass @@ -711,13 +761,16 @@ # injection, this function create maps for remapping indices mentioned # in the code. # -def _make_idx_map(saved_typeids, saved_methodids, - new_typeids, new_methodids): +def _make_idx_map(saved_typeids, saved_methodids, saved_strids, + new_typeids, new_methodids, new_strids): methodidxs_map = dict([(idx, new_methodids.index(methodid)) for idx, methodid in enumerate(saved_methodids)]) typeidxs_map = dict([(idx, new_typeids.index(typeid)) for idx, typeid in enumerate(saved_typeids)]) - return typeidxs_map, methodidxs_map + stridxs_map = dict([(idx, new_strids.index(strid)) + for idx, strid in enumerate(saved_strids)]) + + return typeidxs_map, methodidxs_map, stridxs_map ## \brief Sort sorted arrays and remapping indices for code blocks. @@ -730,16 +783,19 @@ saved_typeids = list(dex_linked.typeIds.items) saved_methodids = list(dex_linked.methodIds.items) + saved_strids = list(dex_linked.stringIds.items) dex_sort_sorted_arrays(dex_linked) new_typeids = dex_linked.typeIds.items new_methodids = dex_linked.methodIds.items - typeidxs_map, methodidxs_map = \ - _make_idx_map(saved_typeids, saved_methodids, \ - new_typeids, new_methodids) + new_strids = dex_linked.stringIds.items + typeidxs_map, methodidxs_map, stridxs_map = \ + _make_idx_map(saved_typeids, saved_methodids, saved_strids, \ + new_typeids, new_methodids, new_strids) - dexfile_redirect_types(dex_linked, typeidxs_map, methodidxs_map) + dexfile_redirect_indices(dex_linked, typeidxs_map, methodidxs_map, + stridxs_map) pass diff -r 46e40afd4558 -r c4324c3461e8 paraspace/tests/injection_test.py --- a/paraspace/tests/injection_test.py Mon Aug 15 11:13:56 2011 +0800 +++ b/paraspace/tests/injection_test.py Mon Aug 15 15:25:39 2011 +0800 @@ -106,7 +106,7 @@ 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.injection import dexfile_redirect_indices from paraspace.injection import make_methodidxs_redir_map from paraspace import dalvik_opcodes @@ -160,8 +160,8 @@ methods_redir = make_methodidxs_redir_map(helloworld_linked, helloworld_linked, types_redir) - dexfile_redirect_types(helloworld_linked, types_redir, - methods_redir, excludes) + dexfile_redirect_indices(helloworld_linked, types_redir, + methods_redir, excludes) for code in helloworld_linked.codeItems.items: op_vectors = dalvik_opcodes.decode_insn_blk(code.insns.data) @@ -299,7 +299,7 @@ from paraspace.dex_deptracker import prepare_dep_decls from paraspace.injection import inject_classdefs from paraspace.injection import make_methodidxs_redir_map - from paraspace.injection import dexfile_redirect_types + from paraspace.injection import dexfile_redirect_indices from paraspace import dalvik_opcodes from paraspace.dexfile import DEXFile_linked @@ -366,8 +366,9 @@ make_methodidxs_redir_map(helloworld_linked, \ helloworld_linked, \ typeidxs_redir_map) - dexfile_redirect_types(helloworld_linked, typeidxs_redir_map, - methodidxs_redir_map, excludes=[fakefile_typeidx]) + dexfile_redirect_indices(helloworld_linked, typeidxs_redir_map, + methodidxs_redir_map, {}, + excludes=[fakefile_typeidx]) cloning_initdef = \ helloworld_linked.find_method_name_proto('', \