Mercurial > paraspace
comparison paraspace/injection.py @ 111:3820379b34e8
Add dexfile_insert_class_relative()
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 01 Aug 2011 22:23:55 +0800 |
parents | 6380730a80b4 |
children | 650dcb9c01ee |
comparison
equal
deleted
inserted
replaced
110:6380730a80b4 | 111:3820379b34e8 |
---|---|
92 _dex_tree_set_child(dex, count_name, count + 1) | 92 _dex_tree_set_child(dex, count_name, count + 1) |
93 pass | 93 pass |
94 pass | 94 pass |
95 | 95 |
96 | 96 |
97 ## \brief Clone a class definition item | 97 ## \brief Clone a composite object. |
98 # | 98 # |
99 # \param dex is the DEXFile that clazz is cloning for. | 99 # \param dex is the DEXFile that the composite object is cloning for. |
100 # \param clazz is the class definition item that is cloning. | 100 # \param comobj is composite object that is cloning. |
101 # | 101 # |
102 def _clone_classdef(dex, clazz): | 102 def _clone_composite(dex, comobj): |
103 from copy import copy | 103 from copy import copy |
104 from paraspace.dexfile import _DEX_StringDataItem, _DEX_StringId | 104 from paraspace.dexfile import _DEX_StringDataItem, _DEX_StringId |
105 from paraspace.dexfile import _DEX_TypeId | 105 from paraspace.dexfile import _DEX_TypeId |
106 from paraspace.dex_deptracker import _dex_tree_set_child | 106 from paraspace.dex_deptracker import _dex_tree_set_child |
107 from paraspace.dex_deptracker import _dex_tree_get_child | 107 from paraspace.dex_deptracker import _dex_tree_get_child |
173 dex_append_obj_list(dex, typeid) | 173 dex_append_obj_list(dex, typeid) |
174 pass | 174 pass |
175 pass | 175 pass |
176 pass | 176 pass |
177 | 177 |
178 def has_classdef(clazz): | 178 _travel_desc_relocatable(comobj, cloner, visit_log) |
179 class_typeIds = set([classdef.classIdx | |
180 for classdef in dex.classDefs.items]) | |
181 return clazz.classIdx in class_typeIds | |
182 | |
183 _travel_desc_relocatable(clazz, cloner, visit_log) | |
184 | 179 |
185 merge_unique_strdata() | 180 merge_unique_strdata() |
186 merge_unique_strid() | 181 merge_unique_strid() |
187 merge_unique_typeid() | 182 merge_unique_typeid() |
188 | 183 |
193 continue | 188 continue |
194 relink_dependencies(obj) | 189 relink_dependencies(obj) |
195 dex_append_obj_list(dex, obj) | 190 dex_append_obj_list(dex, obj) |
196 pass | 191 pass |
197 | 192 |
193 clone = visit_log[id(comobj)] | |
194 return clone | |
195 | |
196 | |
197 ## \brief Clone a class definition item | |
198 # | |
199 # \param dex is the DEXFile that clazz is cloning for. | |
200 # \param clazz is the class definition item that is cloning. | |
201 # \return the cloning _DEX_ClassDef. | |
202 # | |
203 def _clone_classdef(dex, clazz): | |
204 from paraspace.dexfile import DEXFile_linked, _DEX_ClassDef | |
205 | |
206 def has_classdef(clazz): | |
207 classname = DEXFile_linked.get_classdef_name(clazz) | |
208 try: | |
209 dex.find_class_name(classname) | |
210 except ValueError: | |
211 return False | |
212 return True | |
213 | |
214 assert isinstance(clazz, _DEX_ClassDef) | |
215 | |
198 if has_classdef(clazz): | 216 if has_classdef(clazz): |
199 raise RuntimeError, \ | 217 raise RuntimeError, \ |
200 'clone a class \'%s\'that is already in the DEXFile' % \ | 218 'clone a class \'%s\'that is already in the DEXFile' % \ |
201 classdef_name(clazz) | 219 classdef_name(clazz) |
202 | 220 |
203 clone = visit_log[id(clazz)] | 221 clone = _clone_composite(dex, clazz) |
204 return clone | 222 return clone |
205 | 223 |
206 | 224 |
207 ## \brief Clone a class definition and insert into a DEXFile. | 225 ## \brief Clone a class definition and insert into a DEXFile. |
208 # | 226 # |
210 # insert it into another one. | 228 # insert it into another one. |
211 # | 229 # |
212 # \param dex is a DEXFile_linked to insert the clone. | 230 # \param dex is a DEXFile_linked to insert the clone. |
213 # \param class_def is a class definition going to be cloned. | 231 # \param class_def is a class definition going to be cloned. |
214 # | 232 # |
215 def dexfile_insert_class(dex, class_def): | 233 def dexfile_insert_class(dex, classdef): |
216 clone = _clone_classdef(dex, class_def) | 234 clone = _clone_classdef(dex, classdef) |
217 return clone | 235 return clone |
236 | |
237 | |
238 ## \brief Collect info of classes mentioned by the code of given class. | |
239 def _find_class_relative(dex, classdef): | |
240 def classify_typeids_defined(dex, typeids): | |
241 classdefs = [] | |
242 undef_typeids = [] | |
243 for typeid in typeids: | |
244 try: | |
245 classdef = dex.find_class_typeid(typeid) | |
246 except ValueError: | |
247 undef_typeids.append(typeid) | |
248 else: | |
249 classdefs.append(classdef) | |
250 pass | |
251 pass | |
252 return classdefs, undef_typeids | |
253 | |
254 typeidxs = collect_typeidxs_mentioned_by_class(dex, classdef) | |
255 typeids = [dex.find_typeid_idx(typeidx) | |
256 for typeidx in typeidxs] | |
257 | |
258 classdefs, typeids = classify_typeids_defined(dex, typeids) | |
259 | |
260 return classdefs, typeids | |
261 | |
262 | |
263 def dexfile_insert_classdefs(dex_dst, dex_src, classdefs): | |
264 for classdef in classdefs: | |
265 dexfile_insert_class(dex_dst, classdef) | |
266 pass | |
267 pass | |
268 | |
269 | |
270 ## \brief Clone and insert a _DEX_TypeId to another DEXFile_linked. | |
271 # | |
272 # \param dex_dst is a DEXFile_linked where the cloning one is inserted. | |
273 # \param dex_src is a DEXFile_linked where the cloned one is from. | |
274 # \param typeid is a _DEX_TypeId that is cloned. | |
275 # \return the cloning _DEX_TypeId. | |
276 # | |
277 def dexfile_insert_typeid(dex_dst, dex_src, typeid): | |
278 from paraspace.dexfile import _DEX_TypeId, DEXFile_linked | |
279 | |
280 assert isinstance(typeid, _DEX_TypeId) | |
281 | |
282 cloning = _clone_composite(dex_dst, typeid) | |
283 | |
284 methodids = dex_src.find_methodids_typeid(dex_src, typeid) | |
285 for methodid in methodids: | |
286 _clone_composite(dex_dst, methodid) | |
287 pass | |
288 | |
289 return cloning | |
290 | |
291 | |
292 ## \brief Clone and insert a list of _DEX_TypeId objects to a DEXFile_linked. | |
293 def dexfile_insert_typeids(dex_dst, dex_src, typeids): | |
294 for typeid in typeids: | |
295 dexfile_insert_typeid(dex_dst, dex_src, typeid) | |
296 pass | |
297 pass | |
298 | |
299 | |
300 ## \brief Collects relative type IDs and classes definition for given class. | |
301 def collect_classdef_relative(dex, classdef): | |
302 rel_classdefs = set([classdef]) | |
303 rel_typeids = set() | |
304 | |
305 classdef_queue = [classdef] | |
306 while classdef_queue: | |
307 cur_classdef = classdef_queue.pop(0) | |
308 | |
309 classdefs, typeids = _find_class_relative(dex, classdef) | |
310 rel_typeids.update(typeids) | |
311 new_classdefs = list(set(classdefs) - rel_classdefs) | |
312 classdef_queue = classdef_queue + new_classdefs | |
313 rel_classdefs.update(new_classdefs) | |
314 pass | |
315 return rel_classdefs, rel_typeids | |
316 | |
317 | |
318 ## \brief Clone and insert given and relative classes into another DEXFile. | |
319 # | |
320 # \param dex_dst is a DEXFile_linked where the class will be inserted. | |
321 # \param dex_src is a DEXFile_linked where the cloned class is from. | |
322 # \param classdef is a _DEX_ClassDef that will be cloned. | |
323 # | |
324 def dexfile_insert_class_relative(dex_dst, dex_src, classdef): | |
325 from paraspace.dexfile import DEXFile_linked | |
326 | |
327 def classdef_not_in_dst(classdef): | |
328 classname = DEXFile_linked.get_classdef_name(classdef) | |
329 try: | |
330 dex_dst.find_class_name(classname) | |
331 except ValueError: | |
332 return True | |
333 return False | |
334 | |
335 def typeid_not_in_dst(typeid): | |
336 typename = DEXFile_linked.get_typeid_name(typeid) | |
337 try: | |
338 dex_dst.find_typeid_name(typename) | |
339 except ValueError: | |
340 return True | |
341 return False | |
342 | |
343 relative_classdefs, relative_typeids = \ | |
344 collect_classdef_relative(dex_src, classdef) | |
345 | |
346 inserting_classdefs = filter(classdef_not_in_dst, relative_classdefs) | |
347 inserting_typeids = filter(typeid_not_in_dst, relative_typeids) | |
348 | |
349 dexfile_insert_classdefs(dex_dst, dex_src, inserting_classdefs) | |
350 dexfile_insert_typeids(dex_dst, dex_src, inserting_typeids) | |
351 | |
352 classname = DEXFile_linked.get_classdef_name(classdef) | |
353 cloning = dex_dst.find_class_name(classname) | |
354 | |
355 return cloning | |
218 | 356 |
219 | 357 |
220 ## \brief Redirect types and methods for the code of given method. | 358 ## \brief Redirect types and methods for the code of given method. |
221 def method_redirect_types(dex, method, types_redir, methods_redir): | 359 def method_redirect_types(dex, method, types_redir, methods_redir): |
222 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes | 360 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes |