Mercurial > paraspace
annotate paraspace/injection.py @ 104:61cef1662035
Redirect types
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Thu, 28 Jul 2011 00:06:54 +0800 |
parents | 355986e5cfbd |
children | f14c32108164 |
rev | line source |
---|---|
87 | 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 | 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 | 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 | 26 if id(obj) in visit_log: |
27 return visit_log[id(obj)] | |
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 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
68 ## \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
|
69 # |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
70 # 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
|
71 # |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
72 def dex_append_obj_list(dex, obj): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
73 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
|
74 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
|
75 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
76 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
|
77 try: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
78 attr = type_2_attr[obj.__class__] |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
79 except KeyError: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
80 return |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
81 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
82 array = getattr(dex, attr) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
83 array.items.append(obj) |
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 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
|
86 if count_name: |
1769e52bdd9d
Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents:
94
diff
changeset
|
87 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
|
88 _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
|
89 pass |
88
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
90 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
91 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
92 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
93 ## \brief Clone a class definition item |
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 # \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
|
96 # \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
|
97 # |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
98 def _clone_classdef(dex, clazz): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
99 from copy import copy |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
100 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
|
101 from paraspace.dexfile import _DEX_TypeId |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
102 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
103 visit_log = {} |
87 | 104 |
88
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
105 def cloner(obj): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
106 clone = copy(obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
107 return clone |
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 def relink_dependencies(clone): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
110 rel_children = _relocatable_children(clone) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
111 for attr, value in rel_children: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
112 clone_value = visit_log[id(value)] |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
113 setattr(clone, attr, clone_value) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
114 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
115 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
116 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
117 def merge_unique_strdata(): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
118 strdatas = [(obj_id, obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
119 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
|
120 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
|
121 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
|
122 for strdata in dex.stringDataItems.items]) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
123 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
|
124 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
|
125 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
|
126 else: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
127 dex_append_obj_list(dex, strdata) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
128 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
129 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
130 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
131 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
132 def merge_unique_strid(): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
133 strids = [(obj_id, obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
134 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
|
135 if isinstance(obj, _DEX_StringId)] |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
136 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
137 for obj_id, strid in strids: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
138 relink_dependencies(strid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
139 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
140 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
141 strdata_2_strid = dict([(strid.stringDataOff, strid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
142 for strid in dex.stringIds.items]) |
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 if strid.stringDataOff in strdata_2_strid: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
145 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
|
146 else: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
147 dex_append_obj_list(dex, strid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
148 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
149 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
150 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
151 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
152 def merge_unique_typeid(): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
153 typeids = [(obj_id, obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
154 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
|
155 if isinstance(obj, _DEX_TypeId)] |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
156 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
157 for obj_id, typeid in typeids: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
158 relink_dependencies(typeid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
159 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
160 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
161 strid_2_typeid = dict([(typeid.descriptorIdx, typeid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
162 for typeid in dex.typeIds.items]) |
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 if typeid.descriptorIdx in strid_2_typeid: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
165 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
|
166 else: |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
167 dex_append_obj_list(dex, typeid) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
168 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
169 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
170 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
171 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
172 def has_classdef(clazz): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
173 class_typeIds = set([classdef.classIdx |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
174 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
|
175 return clazz.classIdx in class_typeIds |
88
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
176 |
96
1769e52bdd9d
Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents:
94
diff
changeset
|
177 _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
|
178 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
179 merge_unique_strdata() |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
180 merge_unique_strid() |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
181 merge_unique_typeid() |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
182 |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
183 for obj in visit_log.values(): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
184 if isinstance(obj, (_DEX_StringDataItem, |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
185 _DEX_StringId, |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
186 _DEX_TypeId)): |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
187 continue |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
188 relink_dependencies(obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
189 dex_append_obj_list(dex, obj) |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
190 pass |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
191 |
96
1769e52bdd9d
Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents:
94
diff
changeset
|
192 if has_classdef(clazz): |
88
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
193 raise RuntimeError, \ |
bbe8d5cbe368
Clone objects with meta info
Thinker K.F. Li <thinker@codemud.net>
parents:
87
diff
changeset
|
194 '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
|
195 classdef_name(clazz) |
94
88645ab29aeb
dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents:
88
diff
changeset
|
196 |
96
1769e52bdd9d
Make dexfile_insert_class() pass the testcase
Thinker K.F. Li <thinker@codemud.net>
parents:
94
diff
changeset
|
197 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
|
198 return clone |
87 | 199 |
200 | |
94
88645ab29aeb
dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents:
88
diff
changeset
|
201 ## \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
|
202 # |
88645ab29aeb
dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents:
88
diff
changeset
|
203 # 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
|
204 # insert it into another one. |
88645ab29aeb
dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents:
88
diff
changeset
|
205 # |
88645ab29aeb
dexfile_insert_class() returns a clone object
Thinker K.F. Li <thinker@codemud.net>
parents:
88
diff
changeset
|
206 # \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
|
207 # \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
|
208 # |
87 | 209 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
|
210 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
|
211 return clone |
104 | 212 |
213 | |
214 def method_redirect_types(dex, method, redirect_map): | |
215 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes | |
216 from paraspace.dalvik_opcodes import encode_opcode_vectors | |
217 from paraspace.dexfile import DEXFile_linked | |
218 | |
219 if not method.codeOffRef.is_true: | |
220 return | |
221 | |
222 code = method.codeOffRef.value | |
223 insns_blk = code.insns.data | |
224 op_vectors = decode_insn_blk(insns_blk) | |
225 | |
226 def redirect(opcode, args): | |
227 if opcode == all_opcodes.OP_NEW_INSTANCE: | |
228 typeidx = args[1] | |
229 if typeidx in redirect_map: | |
230 to_type = redirect_map[typeidx] | |
231 return opcode, (args[0], to_type) | |
232 pass | |
233 elif opcode == all_opcodes.OP_INVOKE_DIRECT: | |
234 methodidx = args[2] | |
235 methodid = dex.find_methodid_idx(methodidx) | |
236 method_typeid = methodid.classIdx | |
237 method_typeidx = dex.get_idx_typeid(method_typeidx) | |
238 if method_typeidx not in redirect_map: | |
239 return opcode, args | |
240 | |
241 new_method_typeidx = redirect_map[method_typeidx] | |
242 new_method_typeid = dex.find_typeid_idx(new_method_typeidx) | |
243 classdef = dex.find_class_typeid(new_method_typeid) | |
244 method_name = DEXFile_linked.get_methodid_name(methodid) | |
245 method_proto = methodid.protoIdx | |
246 | |
247 try: | |
248 new_method = dex.find_method_name_proto(method_name, | |
249 method_proto, | |
250 classdef) | |
251 except: | |
252 return opcode, args | |
253 new_method_idx = dex.get_index_method(new_method) | |
254 return opcode, (args[0], args[1], new_method_idx, | |
255 args[3], args[4], args[5], args[6]) | |
256 return opcode, args | |
257 | |
258 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] | |
259 new_insns_blk = encode_opcode_vectors(new_op_vectors) | |
260 | |
261 code.insns.data = new_insns_blk | |
262 pass | |
263 | |
264 | |
265 def class_redirect_types(dex, classdef, redirect_map): | |
266 if not classdef.classDataOffRef.is_true: | |
267 return | |
268 | |
269 classdata = classdef.classDataOffRef.value | |
270 for method in classdata.directMethods.items: | |
271 method_redirect_types(dex, method, redirect_map) | |
272 pass | |
273 for method in classdata.virtualMethods.items: | |
274 method_redirect_types(dex, method, redirect_map) | |
275 pass | |
276 pass | |
277 | |
278 | |
279 def dexfile_redirect_types(dex, redirect_map, excludes=set([])): | |
280 for classdef in dex.classDefs.items: | |
281 typeid = classdef.classIdx | |
282 idx = dex.get_index_typeid(typeid) | |
283 if idx in excludes: | |
284 continue | |
285 class_redirect_types(dex, classdef, redirect_map) | |
286 pass | |
287 pass |