diff paraspace/injection.py @ 109:835336632aba

Add collect_typeidxs_in_method()
author Thinker K.F. Li <thinker@codemud.net>
date Mon, 01 Aug 2011 14:37:04 +0800
parents 18be67af7f1e
children 6380730a80b4
line wrap: on
line diff
--- a/paraspace/injection.py	Mon Aug 01 12:27:28 2011 +0800
+++ b/paraspace/injection.py	Mon Aug 01 14:37:04 2011 +0800
@@ -364,3 +364,55 @@
         class_redirect_types(dex, classdef, types_redir, methods_redir)
         pass
     pass
+
+
+## \brief Collect all type indices mentioned in the code of given method.
+#
+# \param method is a \ref _DEX_Method.
+#
+def collect_typeidxs_in_method(dex, method):
+    from paraspace.dexfile import _DEX_Method, DEXFile_linked
+    from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes
+    from itertools import chain
+    
+    assert isinstance(method, _DEX_Method)
+
+    def get_typeidx_methodidx(methodidx):
+        methodid = dex.find_methodid_idx(methodidx)
+        method_typeid = methodid.classIdx
+        method_typeidx = dex.get_idx_typeid(method_typeid)
+        return method_typeidx
+
+    def collect_types_in_op_vector(op_vector):
+        code, args = op_vector
+        
+        if code == all_opcodes.OP_NEW_INSTANCE:
+            return (args[1],)
+        
+        if code in (all_opcodes.OP_INVOKE_DIRECT,
+                    all_opcodes.OP_INVOKE_VIRTUAL,
+                    all_opcodes.OP_INVOKE_SUPER,
+                    all_opcodes.OP_INVOKE_STATIC,
+                    all_opcodes.OP_INVOKE_INTERFACE):
+            methodidx = args[2]
+            method_typeidx = get_typeidx_methodidx(methodidx)
+            return (method_typeidx,)
+
+        if code in (all_opcodes.OP_INVOKE_VIRTUAL_RANGE,
+                    all_opcodes.OP_INVOKE_DIRECT_RANGE,
+                    all_opcodes.OP_INVOKE_SUPER_RANGE,
+                    all_opcodes.OP_INVOKE_STATIC_RANGE,
+                    all_opcodes.OP_INVOKE_INTERFACE_RANGE):
+            methodidx = args[1]
+            method_typeidx = get_typeidx_methodidx(methodidx)
+            return (method_typeidx,)
+        
+        return ()
+
+    code_blk = DEXFile_linked.get_code_block_method(method)
+    op_vectors = decode_insn_blk(code_blk)
+    types_insns = [collect_types_in_op_vector(op_vector)
+                   for op_vector in op_vectors]
+    typeidxs = list(chain(*types_insns))
+    
+    return typeidxs