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.
 #