annotate 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
rev   line source
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
1
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
2 def _relocatable_children(obj):
106
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
3 from paraspace.dex_deptracker import _dex_tree_get_child
100
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
4 from paraspace.dexfile import relocatable, array
106
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
5
100
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
6 if isinstance(obj, array):
106
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
7 rel_children = [('items.' + str(idx), value)
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
8 for idx, value in enumerate(obj.items)
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
9 if isinstance(value, relocatable)]
100
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
10 return rel_children
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
11
106
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
12 attrs = obj.children()
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
13 attr_value_pairs = [(attr, _dex_tree_get_child(obj, attr))
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
14 for attr in attrs]
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
15 rel_children = [(attr, value) for attr, value in attr_value_pairs
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
16 if isinstance(value, relocatable)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
17 return rel_children
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
18
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
19
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
20 ## \brief Travel relocatable descendants.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
21 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
22 # \param cloner is the function to return a clone.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
23 # \param adjuster is called to adjust the clone.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
24 # \param visit_log is a dictionary to keep clones.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
25 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
26 def _travel_desc_relocatable(obj, worker, visit_log):
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27 if id(obj) in visit_log:
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28 return visit_log[id(obj)]
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
29
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
30 result = worker(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
31 visit_log[id(obj)] = result
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
32
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
33 rel_children = _relocatable_children(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
34 for attr, value in rel_children:
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
35 _travel_desc_relocatable(value, worker, visit_log)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
36 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
37 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
38
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
39
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
40 ## \brief Return name string of a linked class definition item.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
41 def classdef_name(classdef):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
42 return classdef.classIdx.descriptorIdx.stringDataOff.data
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
43
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
44
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
45 ## \brief Return a map that map type of a object to the list of a DEXFile.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
46 def dex_type_2_array_attr_map():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
47 global dex_type_2_array_attr_map
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
48 from paraspace.dexfile import DEXFile, array
98
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
49 from paraspace.dex_deptracker import _marker
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
50
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
51 def skip_marker_type(clazz):
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
52 while isinstance(clazz, _marker):
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
53 clazz = clazz.back_type
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
54 pass
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
55 return clazz
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
56
100
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
57 attr_values = [(attr, skip_marker_type(getattr(DEXFile, attr)))
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
58 for attr in dir(DEXFile)]
100
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
59 array_attrs = [(skip_marker_type(value.child_type), attr)
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
60 for attr, value in attr_values
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
61 if isinstance(value, array)]
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
62 type_2_attr = dict(array_attrs)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
63
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
64 dex_type_2_array_attr_map = lambda: type_2_attr
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
65
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
66 return type_2_attr
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
67
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
68
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
69 _saved_dex_type_2_array_attr_map = dex_type_2_array_attr_map
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
70
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
71
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
72 ## \brief Append a object to appropriate list of a DEXFile object.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
73 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
74 # Skip the object if found no appropriate list.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
75 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
76 def dex_append_obj_list(dex, obj):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
77 from paraspace.dex_deptracker import _dex_tree_get_child
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
78 from paraspace.dex_deptracker import _dex_tree_set_child
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
79
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
80 type_2_attr = dex_type_2_array_attr_map()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
81 try:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
82 attr = type_2_attr[obj.__class__]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
83 except KeyError:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
84 return
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
85
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
86 array = getattr(dex, attr)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
87 array.items.append(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
89 count_name = array.count_name
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
90 if count_name:
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
91 count = _dex_tree_get_child(dex, count_name)
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
92 _dex_tree_set_child(dex, count_name, count + 1)
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
93 pass
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
94 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
95
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
96
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
97 ## \brief Clone a class definition item
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
98 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
99 # \param dex is the DEXFile that clazz is cloning for.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
100 # \param clazz is the class definition item that is cloning.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
101 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
102 def _clone_classdef(dex, clazz):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
103 from copy import copy
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
104 from paraspace.dexfile import _DEX_StringDataItem, _DEX_StringId
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
105 from paraspace.dexfile import _DEX_TypeId
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
106 from paraspace.dex_deptracker import _dex_tree_set_child
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
107 from paraspace.dex_deptracker import _dex_tree_get_child
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
108
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
109 visit_log = {}
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
110
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
111 def cloner(obj):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
112 clone = copy(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
113 return clone
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
114
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
115 def relink_dependencies(clone):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
116 rel_children = _relocatable_children(clone)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
117 for attr, value in rel_children:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
118 clone_value = visit_log[id(value)]
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
119 _dex_tree_set_child(clone, attr, clone_value)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
120 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
121 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
122
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
123 def merge_unique_strdata():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
124 strdatas = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
125 for obj_id, obj in visit_log.items()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
126 if isinstance(obj, _DEX_StringDataItem)]
99
3898711adb2c Make sure string data list is consistent.
Thinker K.F. Li <thinker@codemud.net>
parents: 98
diff changeset
127 dex_str_2_strdata = dict([(strdata.data.data, strdata)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
128 for strdata in dex.stringDataItems.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
129 for obj_id, strdata in strdatas:
99
3898711adb2c Make sure string data list is consistent.
Thinker K.F. Li <thinker@codemud.net>
parents: 98
diff changeset
130 if strdata.data.data in dex_str_2_strdata:
3898711adb2c Make sure string data list is consistent.
Thinker K.F. Li <thinker@codemud.net>
parents: 98
diff changeset
131 visit_log[obj_id] = dex_str_2_strdata[strdata.data.data]
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
132 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
133 dex_append_obj_list(dex, strdata)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
134 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
135 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
136 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
137
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
138 def merge_unique_strid():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
139 strids = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
140 for obj_id, obj in visit_log.items()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
141 if isinstance(obj, _DEX_StringId)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
142
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
143 for obj_id, strid in strids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
144 relink_dependencies(strid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
145 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
146
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
147 strdata_2_strid = dict([(strid.stringDataOff, strid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
148 for strid in dex.stringIds.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
149 for obj_id, strid in strids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
150 if strid.stringDataOff in strdata_2_strid:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
151 visit_log[obj_id] = strdata_2_strid[strid.stringDataOff]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
152 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
153 dex_append_obj_list(dex, strid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
154 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
155 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
156 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
157
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
158 def merge_unique_typeid():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
159 typeids = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
160 for obj_id, obj in visit_log.items()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
161 if isinstance(obj, _DEX_TypeId)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
162
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
163 for obj_id, typeid in typeids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
164 relink_dependencies(typeid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
165 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
166
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
167 strid_2_typeid = dict([(typeid.descriptorIdx, typeid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
168 for typeid in dex.typeIds.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
169 for obj_id, typeid in typeids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
170 if typeid.descriptorIdx in strid_2_typeid:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
171 visit_log[obj_id] = strid_2_typeid[typeid.descriptorIdx]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
172 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
173 dex_append_obj_list(dex, typeid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
174 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
175 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
176 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
177
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
178 def has_classdef(clazz):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
179 class_typeIds = set([classdef.classIdx
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
180 for classdef in dex.classDefs.items])
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
181 return clazz.classIdx in class_typeIds
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
182
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
183 _travel_desc_relocatable(clazz, cloner, visit_log)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
184
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
185 merge_unique_strdata()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
186 merge_unique_strid()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
187 merge_unique_typeid()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
188
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
189 for obj in visit_log.values():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
190 if isinstance(obj, (_DEX_StringDataItem,
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
191 _DEX_StringId,
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
192 _DEX_TypeId)):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
193 continue
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
194 relink_dependencies(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
195 dex_append_obj_list(dex, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
196 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
197
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
198 if has_classdef(clazz):
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
199 raise RuntimeError, \
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
200 'clone a class \'%s\'that is already in the DEXFile' % \
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
201 classdef_name(clazz)
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
202
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
203 clone = visit_log[id(clazz)]
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
204 return clone
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
205
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
206
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
207 ## \brief Clone a class definition and insert into a DEXFile.
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
208 #
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
209 # This function clone a class definition from a linked DEXFile and
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
210 # insert it into another one.
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
211 #
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
212 # \param dex is a DEXFile_linked to insert the clone.
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
213 # \param class_def is a class definition going to be cloned.
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
214 #
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
215 def dexfile_insert_class(dex, class_def):
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
216 clone = _clone_classdef(dex, class_def)
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
217 return clone
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
218
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
219
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
220 ## \brief Redirect types and methods for the code of given method.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
221 def method_redirect_types(dex, method, types_redir, methods_redir):
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
222 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
223 from paraspace.dalvik_opcodes import encode_opcode_vectors
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
224 from paraspace.dexfile import DEXFile_linked
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
225
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
226 if not method.codeOffRef.is_true:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
227 return
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
228
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
229 code = method.codeOffRef.value
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
230 insns_blk = code.insns.data
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
231 op_vectors = decode_insn_blk(insns_blk)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
232
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
233 def redirect(opcode, args):
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
234 if opcode == all_opcodes.OP_NEW_INSTANCE:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
235 typeidx = args[1]
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
236 if typeidx in types_redir:
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
237 to_type = types_redir[typeidx]
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
238 return opcode, (args[0], to_type)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
239 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
240 elif opcode == all_opcodes.OP_INVOKE_DIRECT:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
241 methodidx = args[2]
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
242 if methodidx not in methods_redir:
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
243 return opcode, args
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
244
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
245 return opcode, (args[0], args[1], methods_redir[methodidx],
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
246 args[3], args[4], args[5], args[6])
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
247 methodid = dex.find_methodid_idx(methodidx)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
248 method_typeid = methodid.classIdx
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
249 method_typeidx = dex.get_idx_typeid(method_typeid)
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
250 if method_typeidx not in types_redir:
106
7821c6e89622 dexfile_redirect_types() is almost ready.
Thinker K.F. Li <thinker@codemud.net>
parents: 105
diff changeset
251 method_typeid = dex.find_typeid_idx(method_typeidx - 1)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
252 return opcode, args
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
253
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
254 new_method_typeidx = types_redir[method_typeidx]
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
255 new_method_typeid = dex.find_typeid_idx(new_method_typeidx)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
256 classdef = dex.find_class_typeid(new_method_typeid)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
257 method_name = DEXFile_linked.get_methodid_name(methodid)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
258 method_proto = methodid.protoIdx
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
259
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
260 try:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
261 new_method = dex.find_method_name_proto(method_name,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
262 method_proto,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
263 classdef)
107
4b3573d039af Fix bug of DEXFile_linked.find_method_name_proto().
Thinker K.F. Li <thinker@codemud.net>
parents: 106
diff changeset
264 except ValueError:
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
265 return opcode, args
107
4b3573d039af Fix bug of DEXFile_linked.find_method_name_proto().
Thinker K.F. Li <thinker@codemud.net>
parents: 106
diff changeset
266 new_method_idx = dex.get_idx_method(new_method)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
267 return opcode, (args[0], args[1], new_method_idx,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
268 args[3], args[4], args[5], args[6])
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
269 return opcode, args
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
270
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
271 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors]
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
272 new_insns_blk = encode_opcode_vectors(new_op_vectors)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
273
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
274 code.insns.data = new_insns_blk
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
275 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
276
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
277
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
278 ## \brief Make a map for methods from source type ID to ones from desinate.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
279 def make_redir_classes_methods_map(dex_src, typeid_src,
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
280 dex_dst, typeid_dst):
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
281 from paraspace.dexfile import DEXFile_linked
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
282
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
283 methods_src = [(idx, methodid)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
284 for idx, methodid in enumerate(dex_src.methodIds.items)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
285 if methodid.classIdx == typeid_src]
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
286
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
287 def make_map_methodid(methodid_src):
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
288 name = DEXFile_linked.get_methodid_name(methodid_src)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
289 proto = methodid_src.protoIdx
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
290 try:
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
291 methodid_dst = \
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
292 dex_dst.find_methodid_name_proto(name, proto, typeid_dst)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
293 except ValueError:
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
294 return -1
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
295 methodidx_dst = dex_dst.get_idx_methodid(methodid_dst)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
296 return methodidx_dst
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
297
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
298 methods_map = [(methodidx_src, make_map_methodid(methodid_src))
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
299 for methodidx_src, methodid_src in methods_src]
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
300 methods_map = [(methodidx_src, methodidx_dst)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
301 for methodidx_src, methodidx_dst in methods_map
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
302 if methodidx_dst != -1]
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
303 methods_map = dict(methods_map)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
304 return methods_map
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
305
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
306
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
307 ## \brief Redirect types and methods mentioned in the code of a class.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
308 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
309 # For code of given class definition, Every mentions of types and
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
310 # methods are rewrote to types and methods according types_redir and
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
311 # methods_redir respectively.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
312 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
313 # \param dex is a DEXFile_linked.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
314 # \param classdef is a class definition.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
315 # \param types_redir is a map of types.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
316 # \param methods_redir is a map of methods.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
317 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
318 def class_redirect_types(dex, classdef, types_redir, methods_redir):
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
319 if not classdef.classDataOffRef.is_true:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
320 return
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
321
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
322 classdata = classdef.classDataOffRef.value
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
323 for method in classdata.directMethods.items:
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
324 method_redirect_types(dex, method, types_redir, methods_redir)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
325 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
326 for method in classdata.virtualMethods.items:
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
327 method_redirect_types(dex, method, types_redir, methods_redir)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
328 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
329 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
330
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
331
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
332 ## \brief Make a map to map methods from source types to destinate types.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
333 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
334 # This function create a map to map methods from source types to
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
335 # methods from destinate types in \ref types_redir.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
336 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
337 # \param dex is a DEXFile_linked that owns source and destinate types.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
338 # \param types_redir is a map of types for redirecting types.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
339 # \return a map of method indices.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
340 #
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
341 def _make_methods_redir_for_types_redir(dex, types_redir):
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
342 methods_map = {}
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
343 for typeidx_src, typeidx_dst in types_redir.items():
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
344 typeid_src = dex.find_typeid_idx(typeidx_src)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
345 typeid_dst = dex.find_typeid_idx(typeidx_dst)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
346 class_methods_map = make_redir_classes_methods_map(dex,
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
347 typeid_src,
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
348 dex,
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
349 typeid_dst)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
350 methods_map.update(class_methods_map)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
351 pass
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
352 return methods_map
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
353
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
354
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
355 ## \biref Redirect types of all code in given DEXFile_linked.
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
356 def dexfile_redirect_types(dex, types_redir, excludes=set([])):
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
357 methods_redir = _make_methods_redir_for_types_redir(dex, types_redir)
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
358
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
359 for classdef in dex.classDefs.items:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
360 typeid = classdef.classIdx
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
361 idx = dex.get_idx_typeid(typeid)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
362 if idx in excludes:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
363 continue
108
18be67af7f1e Use method redirection map for defining redirection
Thinker K.F. Li <thinker@codemud.net>
parents: 107
diff changeset
364 class_redirect_types(dex, classdef, types_redir, methods_redir)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
365 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
366 pass
109
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
367
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
368
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
369 ## \brief Collect all type indices mentioned in the code of given method.
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
370 #
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
371 # \param method is a \ref _DEX_Method.
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
372 #
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
373 def collect_typeidxs_in_method(dex, method):
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
374 from paraspace.dexfile import _DEX_Method, DEXFile_linked
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
375 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
376 from itertools import chain
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
377
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
378 assert isinstance(method, _DEX_Method)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
379
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
380 def get_typeidx_methodidx(methodidx):
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
381 methodid = dex.find_methodid_idx(methodidx)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
382 method_typeid = methodid.classIdx
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
383 method_typeidx = dex.get_idx_typeid(method_typeid)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
384 return method_typeidx
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
385
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
386 def collect_types_in_op_vector(op_vector):
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
387 code, args = op_vector
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
388
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
389 if code == all_opcodes.OP_NEW_INSTANCE:
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
390 return (args[1],)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
391
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
392 if code in (all_opcodes.OP_INVOKE_DIRECT,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
393 all_opcodes.OP_INVOKE_VIRTUAL,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
394 all_opcodes.OP_INVOKE_SUPER,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
395 all_opcodes.OP_INVOKE_STATIC,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
396 all_opcodes.OP_INVOKE_INTERFACE):
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
397 methodidx = args[2]
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
398 method_typeidx = get_typeidx_methodidx(methodidx)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
399 return (method_typeidx,)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
400
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
401 if code in (all_opcodes.OP_INVOKE_VIRTUAL_RANGE,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
402 all_opcodes.OP_INVOKE_DIRECT_RANGE,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
403 all_opcodes.OP_INVOKE_SUPER_RANGE,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
404 all_opcodes.OP_INVOKE_STATIC_RANGE,
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
405 all_opcodes.OP_INVOKE_INTERFACE_RANGE):
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
406 methodidx = args[1]
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
407 method_typeidx = get_typeidx_methodidx(methodidx)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
408 return (method_typeidx,)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
409
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
410 return ()
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
411
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
412 code_blk = DEXFile_linked.get_code_block_method(method)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
413 op_vectors = decode_insn_blk(code_blk)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
414 types_insns = [collect_types_in_op_vector(op_vector)
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
415 for op_vector in op_vectors]
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
416 typeidxs = list(chain(*types_insns))
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
417
835336632aba Add collect_typeidxs_in_method()
Thinker K.F. Li <thinker@codemud.net>
parents: 108
diff changeset
418 return typeidxs