Mercurial > paraspace
changeset 119:4f508f84c8a1
Add inject_redir.py example
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Fri, 05 Aug 2011 14:39:32 +0800 |
parents | 7b537e0d8e7a |
children | c7a5de2d2334 |
files | examples/inject_redir.py paraspace/dexfile.py paraspace/injection.py |
diffstat | 3 files changed, 76 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/inject_redir.py Fri Aug 05 14:39:32 2011 +0800 @@ -0,0 +1,61 @@ +## \file +# +# This is an example of inject a class from source to destinate DEX, and +# rewrite all references of a specified class with the injected one and its +# methods. All calls of specified class will be redirected to the +# injected class. +# +from paraspace.dexfile import DEXFile, DEXFile_linked +from paraspace.dex_deptracker import prepare_dep_decls +from paraspace.dex_deptracker import restore_dependencies +from paraspace.injection import inject_classdefs, make_methodidxs_redir_map +from paraspace.injection import dexfile_redirect_types +import sys + +if len(sys.argv) != 6: + print >> sys.stderr, \ + 'usage: %s <src dex> <inject class> ' \ + '<dst dex> <redirect class> <output>' % \ + (sys.argv[0]) + sys.exit(1) + pass + +src_dexname = sys.argv[1] +inj_classname = sys.argv[2] +dst_dexname = sys.argv[3] +redir_classname = sys.argv[4] +output_name = sys.argv[5] + +decls = prepare_dep_decls() + +src_dex = DEXFile.open(src_dexname) +src_linked = DEXFile_linked.build_dependencies(src_dex, decls) + +dst_dex = DEXFile.open(dst_dexname) +dst_linked = DEXFile_linked.build_dependencies(dst_dex, decls) + +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) + +restore_dependencies(dst_linked, decls) +dst_linked.make_checksum() + +restore_raw = dst_linked.to_str() + +ofile = open(output_name, 'w') +ofile.write(restore_raw) +ofile.close()
--- a/paraspace/dexfile.py Thu Aug 04 21:57:22 2011 +0800 +++ b/paraspace/dexfile.py Fri Aug 05 14:39:32 2011 +0800 @@ -464,7 +464,7 @@ pass @staticmethod - def to_str(): + def to_str(child): return '' def get_value(self, parents): @@ -1682,6 +1682,11 @@ pass ## \brief Factory function to return a DEXFile_linked of given DEXFile. + # + # \param dex is a DEXFile instance. + # \param dep_decls is a dictionary returned by prepare_dep_decls(). + # \return a DEXFile_linked. + # @staticmethod def build_dependencies(dex, dep_decls): from paraspace.dex_deptracker import build_dependencies @@ -1719,6 +1724,13 @@ return typeid pass pass + + ## \brief Get index of given _DEX_ClassDef. + def get_idx_classdef(self, classdef): + from paraspace.dexfile import _DEX_ClassDef + assert isinstance(classdef, _DEX_ClassDef) + typeidx = self.get_idx_typeid(classdef.classIdx) + return typeidx ## \brief Return type ID item with given index. def find_typeid_idx(self, idx):
--- a/paraspace/injection.py Thu Aug 04 21:57:22 2011 +0800 +++ b/paraspace/injection.py Fri Aug 05 14:39:32 2011 +0800 @@ -467,7 +467,8 @@ # This function create a map to map methods from source types to # methods from destinate types in \ref typeidxs_redir. # -# \param dex is a DEXFile_linked that owns source and destinate types. +# \param dex_src is a DEXFile_linked that owns source types. +# \param dex_dst is a DEXFile_linked that owns destinate types. # \param typeidxs_redir is a map of type indices for redirecting types. # \return a map of method indices. #