annotate paraspace/injection.py @ 105:f14c32108164

Test dexfile_redirect_types
author Thinker K.F. Li <thinker@codemud.net>
date Thu, 28 Jul 2011 13:25:55 +0800
parents 61cef1662035
children 7821c6e89622
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):
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
3 from paraspace.dexfile import relocatable, 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
4
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
5 if isinstance(obj, 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
6 if not obj.items:
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
7 return []
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
8 rel_children = [(repr(idx), elt)
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
9 for idx, elt in enumerate(obj.items)
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 if isinstance(elt, relocatable)]
355986e5cfbd Make surce methods of injected class are also being and bug fixed.
Thinker K.F. Li <thinker@codemud.net>
parents: 99
diff changeset
11 return rel_children
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
12
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
13 attr_value_pairs = [(attr, getattr(obj, attr)) for attr in dir(obj)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
14 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
15 if isinstance(value, relocatable)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
16 return rel_children
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
17
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
18
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
19 ## \brief Travel relocatable descendants.
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
20 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
21 # \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
22 # \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
23 # \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
24 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
25 def _travel_desc_relocatable(obj, worker, visit_log):
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
26 if id(obj) in visit_log:
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27 return visit_log[id(obj)]
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
29 result = worker(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
30 visit_log[id(obj)] = result
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
31
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
32 rel_children = _relocatable_children(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
33 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
34 _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
35 pass
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
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 ## \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
40 def classdef_name(classdef):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
41 return classdef.classIdx.descriptorIdx.stringDataOff.data
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
42
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 ## \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
45 def dex_type_2_array_attr_map():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
46 global dex_type_2_array_attr_map
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
47 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
48 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
49
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
50 def skip_marker_type(clazz):
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
51 while isinstance(clazz, _marker):
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
52 clazz = clazz.back_type
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
53 pass
c0c127c7b37e Check and fix issues of map sizes
Thinker K.F. Li <thinker@codemud.net>
parents: 96
diff changeset
54 return clazz
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
55
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
56 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
57 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
58 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
59 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
60 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
61 type_2_attr = dict(array_attrs)
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
62
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
63 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
64
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
65 return type_2_attr
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
66
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
67
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
68 _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
69
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
70
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
71 ## \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
72 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
73 # 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
74 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
75 def dex_append_obj_list(dex, obj):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
76 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
77 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
78
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
79 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
80 try:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
81 attr = type_2_attr[obj.__class__]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
82 except KeyError:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
83 return
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
84
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
85 array = getattr(dex, attr)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
86 array.items.append(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
87
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
88 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
89 if count_name:
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
90 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
91 _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
92 pass
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
93 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
94
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 ## \brief Clone a class definition item
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
97 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
98 # \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
99 # \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
100 #
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
101 def _clone_classdef(dex, clazz):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
102 from copy import copy
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
103 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
104 from paraspace.dexfile import _DEX_TypeId
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
105 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
106 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
107
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
108 visit_log = {}
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
109
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
110 def cloner(obj):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
111 clone = copy(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
112 return clone
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
113
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
114 def relink_dependencies(clone):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
115 rel_children = _relocatable_children(clone)
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
116 print clone
88
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 print attr, _dex_tree_get_child(clone, attr), clone_value
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
120 _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
121 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
122 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
123
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
124 def merge_unique_strdata():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
125 strdatas = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
126 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
127 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
128 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
129 for strdata in dex.stringDataItems.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
130 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
131 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
132 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
133 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
134 dex_append_obj_list(dex, strdata)
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 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
138
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
139 def merge_unique_strid():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
140 strids = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
141 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
142 if isinstance(obj, _DEX_StringId)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
143
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
144 for obj_id, strid in strids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
145 relink_dependencies(strid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
146 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
147
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
148 strdata_2_strid = dict([(strid.stringDataOff, strid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
149 for strid in dex.stringIds.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
150 for obj_id, strid in strids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
151 if strid.stringDataOff in strdata_2_strid:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
152 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
153 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
154 dex_append_obj_list(dex, strid)
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 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
158
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
159 def merge_unique_typeid():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
160 typeids = [(obj_id, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
161 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
162 if isinstance(obj, _DEX_TypeId)]
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
163
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
164 for obj_id, typeid in typeids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
165 relink_dependencies(typeid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
166 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
167
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
168 strid_2_typeid = dict([(typeid.descriptorIdx, typeid)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
169 for typeid in dex.typeIds.items])
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
170 for obj_id, typeid in typeids:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
171 if typeid.descriptorIdx in strid_2_typeid:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
172 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
173 else:
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
174 dex_append_obj_list(dex, typeid)
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 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
178
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
179 def has_classdef(clazz):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
180 class_typeIds = set([classdef.classIdx
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
181 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
182 return clazz.classIdx in class_typeIds
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
183
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
184 _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
185
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
186 merge_unique_strdata()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
187 merge_unique_strid()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
188 merge_unique_typeid()
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
189
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
190 print visit_log
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
191 for obj in visit_log.values():
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
192 if isinstance(obj, (_DEX_StringDataItem,
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
193 _DEX_StringId,
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
194 _DEX_TypeId)):
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
195 continue
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
196 relink_dependencies(obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
197 dex_append_obj_list(dex, obj)
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
198 pass
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
199
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
200 if has_classdef(clazz):
88
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
201 raise RuntimeError, \
bbe8d5cbe368 Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents: 87
diff changeset
202 '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
203 classdef_name(clazz)
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
204
96
1769e52bdd9d Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents: 94
diff changeset
205 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
206 return clone
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
207
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
208
94
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
209 ## \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
210 #
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
211 # 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
212 # insert it into another one.
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
213 #
88645ab29aeb dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents: 88
diff changeset
214 # \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
215 # \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
216 #
87
cd1ee85853f4 Add injection.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
217 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
218 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
219 return clone
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
220
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
221
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
222 def method_redirect_types(dex, method, redirect_map):
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
223 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
224 from paraspace.dalvik_opcodes import encode_opcode_vectors
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
225 from paraspace.dexfile import DEXFile_linked
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
226
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
227 if not method.codeOffRef.is_true:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
228 return
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
229
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
230 code = method.codeOffRef.value
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
231 insns_blk = code.insns.data
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
232 op_vectors = decode_insn_blk(insns_blk)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
233
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
234 def redirect(opcode, args):
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
235 if opcode == all_opcodes.OP_NEW_INSTANCE:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
236 typeidx = args[1]
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
237 if typeidx in redirect_map:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
238 to_type = redirect_map[typeidx]
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
239 return opcode, (args[0], to_type)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
240 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
241 elif opcode == all_opcodes.OP_INVOKE_DIRECT:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
242 methodidx = args[2]
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
243 methodid = dex.find_methodid_idx(methodidx)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
244 method_typeid = methodid.classIdx
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
245 method_typeidx = dex.get_idx_typeid(method_typeid)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
246 if method_typeidx not in redirect_map:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
247 return opcode, args
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
248
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
249 new_method_typeidx = redirect_map[method_typeidx]
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
250 new_method_typeid = dex.find_typeid_idx(new_method_typeidx)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
251 classdef = dex.find_class_typeid(new_method_typeid)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
252 method_name = DEXFile_linked.get_methodid_name(methodid)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
253 method_proto = methodid.protoIdx
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
254
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
255 try:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
256 new_method = dex.find_method_name_proto(method_name,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
257 method_proto,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
258 classdef)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
259 except:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
260 return opcode, args
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
261 new_method_idx = dex.get_index_method(new_method)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
262 return opcode, (args[0], args[1], new_method_idx,
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
263 args[3], args[4], args[5], args[6])
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
264 return opcode, args
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
265
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
266 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
267 new_insns_blk = encode_opcode_vectors(new_op_vectors)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
268
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
269 code.insns.data = new_insns_blk
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
270 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
271
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
272
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
273 def class_redirect_types(dex, classdef, redirect_map):
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
274 if not classdef.classDataOffRef.is_true:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
275 return
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 classdata = classdef.classDataOffRef.value
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
278 for method in classdata.directMethods.items:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
279 method_redirect_types(dex, method, redirect_map)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
280 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
281 for method in classdata.virtualMethods.items:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
282 method_redirect_types(dex, method, redirect_map)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
283 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
284 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
285
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
286
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
287 def dexfile_redirect_types(dex, redirect_map, excludes=set([])):
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
288 for classdef in dex.classDefs.items:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
289 typeid = classdef.classIdx
105
f14c32108164 Test dexfile_redirect_types
Thinker K.F. Li <thinker@codemud.net>
parents: 104
diff changeset
290 idx = dex.get_idx_typeid(typeid)
104
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
291 if idx in excludes:
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
292 continue
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
293 class_redirect_types(dex, classdef, redirect_map)
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
294 pass
61cef1662035 Redirect types
Thinker K.F. Li <thinker@codemud.net>
parents: 100
diff changeset
295 pass