Mercurial > paraspace
comparison paraspace/injection.py @ 150:1eb1b2ca5de4
Use classdef_rel_set to carry relative information.
- Use an object to carry information of relative objects is more
extensible than a tuple.
- We can add more information without affecting others.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 16 Aug 2011 14:53:41 +0800 |
parents | d4533a59c694 |
children | 91fabeaffce8 |
comparison
equal
deleted
inserted
replaced
149:d4533a59c694 | 150:1eb1b2ca5de4 |
---|---|
264 # \param class_def is a class definition going to be cloned. | 264 # \param class_def is a class definition going to be cloned. |
265 # | 265 # |
266 def dexfile_insert_class(dex, classdef): | 266 def dexfile_insert_class(dex, classdef): |
267 clone = _clone_classdef(dex, classdef) | 267 clone = _clone_classdef(dex, classdef) |
268 return clone | 268 return clone |
269 | |
270 | |
271 ## \biref Relative object set for a _DEX_ClassData. | |
272 class classdef_rel_set(object): | |
273 classdefs = None | |
274 typeids = None | |
275 strids = None | |
276 | |
277 def __init__(self, classdefs, typeids, strids): | |
278 self.classdefs = set(classdefs) | |
279 self.typeids = set(typeids) | |
280 self.strids = set(strids) | |
281 pass | |
282 | |
283 @staticmethod | |
284 def dup(src): | |
285 return relative_obj_set(src.classdefs, src.typeids, src.strids) | |
286 | |
287 def update(self, new_data): | |
288 self.classdefs.update(new_data.classdefs) | |
289 self.typeids.update(new_data.typeids) | |
290 self.strids.update(new_data.strids) | |
291 pass | |
292 pass | |
269 | 293 |
270 | 294 |
271 ## \brief Collect info of classes mentioned by the code of given class. | 295 ## \brief Collect info of classes mentioned by the code of given class. |
272 def _find_class_relative(dex, classdef): | 296 def _find_class_relative(dex, classdef): |
273 def classify_typeids_defined(dex, typeids): | 297 def classify_typeids_defined(dex, typeids): |
290 for typeidx in typeidxs] | 314 for typeidx in typeidxs] |
291 strids = [dex.find_strid_idx(idx) for idx in stridxs] | 315 strids = [dex.find_strid_idx(idx) for idx in stridxs] |
292 | 316 |
293 classdefs, typeids = classify_typeids_defined(dex, typeids) | 317 classdefs, typeids = classify_typeids_defined(dex, typeids) |
294 | 318 |
295 return classdefs, typeids, strids | 319 rel_set = classdef_rel_set(classdefs, typeids, strids) |
320 return rel_set | |
296 | 321 |
297 | 322 |
298 def dexfile_insert_classdefs(dex_dst, dex_src, classdefs): | 323 def dexfile_insert_classdefs(dex_dst, dex_src, classdefs): |
299 clones = [dexfile_insert_class(dex_dst, classdef) | 324 clones = [dexfile_insert_class(dex_dst, classdef) |
300 for classdef in classdefs] | 325 for classdef in classdefs] |
367 return clones | 392 return clones |
368 | 393 |
369 | 394 |
370 ## \brief Collects relative type IDs and classes definition for given class. | 395 ## \brief Collects relative type IDs and classes definition for given class. |
371 def collect_classdefs_relative(dex, classdefs): | 396 def collect_classdefs_relative(dex, classdefs): |
372 rel_classdefs = set(classdefs) | 397 rel_set = classdef_rel_set(classdefs, [], []) |
373 rel_typeids = set() | |
374 rel_strids = set() | |
375 | 398 |
376 classdef_queue = list(classdefs) | 399 classdef_queue = list(classdefs) |
377 while classdef_queue: | 400 while classdef_queue: |
378 cur_classdef = classdef_queue.pop(0) | 401 cur_classdef = classdef_queue.pop(0) |
379 | 402 |
380 classdefs, typeids, strids = _find_class_relative(dex, cur_classdef) | 403 new_rel_set = _find_class_relative(dex, cur_classdef) |
381 rel_typeids.update(typeids) | 404 rel_set.update(new_rel_set) |
382 new_classdefs = list(set(classdefs) - rel_classdefs) | 405 new_classdefs = new_rel_set.classdefs - rel_set.classdefs |
383 classdef_queue = classdef_queue + new_classdefs | 406 classdef_queue = classdef_queue + list(new_classdefs) |
384 rel_classdefs.update(new_classdefs) | 407 pass |
385 rel_strids.update(strids) | 408 return rel_set |
386 pass | |
387 return rel_classdefs, rel_typeids, rel_strids | |
388 | 409 |
389 | 410 |
390 ## \brief Clone and insert given and relative classes into another DEXFile. | 411 ## \brief Clone and insert given and relative classes into another DEXFile. |
391 # | 412 # |
392 # \param dex_dst is a DEXFile_linked where the class will be inserted. | 413 # \param dex_dst is a DEXFile_linked where the class will be inserted. |
403 dex_dst.find_class_name(classname) | 424 dex_dst.find_class_name(classname) |
404 except ValueError: | 425 except ValueError: |
405 return True | 426 return True |
406 return False | 427 return False |
407 | 428 |
408 relative_classdefs, relative_typeids, relative_strids = \ | 429 rel_set = collect_classdefs_relative(dex_src, classdefs) |
409 collect_classdefs_relative(dex_src, classdefs) | 430 |
410 | 431 for classdef in rel_set.classdefs: |
411 for classdef in relative_classdefs: | |
412 if classdef_not_in_dst(classdef): | 432 if classdef_not_in_dst(classdef): |
413 continue | 433 continue |
414 raise ValueError, '%s is already in DEX %s: can not insert it' % \ | 434 raise ValueError, '%s is already in DEX %s: can not insert it' % \ |
415 (repr(classdef), repr(dex_dst)) | 435 (repr(classdef), repr(dex_dst)) |
416 | 436 |
417 cloning_classdefs = \ | 437 cloning_classdefs = \ |
418 dexfile_insert_classdefs(dex_dst, dex_src, relative_classdefs) | 438 dexfile_insert_classdefs(dex_dst, dex_src, rel_set.classdefs) |
419 cloning_typeids = \ | 439 cloning_typeids = \ |
420 dexfile_insert_or_merge_typeids(dex_dst, dex_src, relative_typeids) | 440 dexfile_insert_or_merge_typeids(dex_dst, dex_src, rel_set.typeids) |
421 cloning_strids = \ | 441 cloning_strids = \ |
422 dexfile_insert_stringids(dex_dst, dex_src, relative_strids) | 442 dexfile_insert_stringids(dex_dst, dex_src, rel_set.strids) |
423 | 443 |
424 return cloning_classdefs, cloning_typeids, cloning_strids | 444 cloning = classdef_rel_set(cloning_classdefs, cloning_typeids, |
445 cloning_strids) | |
446 return cloning | |
425 | 447 |
426 | 448 |
427 ## \brief Redirect types, methods and strings for the code of given method. | 449 ## \brief Redirect types, methods and strings for the code of given method. |
428 def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, | 450 def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
429 stridxs_redir): | 451 stridxs_redir): |
722 return typeidxs_map | 744 return typeidxs_map |
723 | 745 |
724 | 746 |
725 ## \brief Redirect code for methods of injected classes. | 747 ## \brief Redirect code for methods of injected classes. |
726 def redirect_injected_code(dex_dst, dex_src, classdefs): | 748 def redirect_injected_code(dex_dst, dex_src, classdefs): |
727 relative_classdefs, relative_typeids, relative_strids = \ | 749 rel_set = collect_classdefs_relative(dex_src, classdefs) |
728 collect_classdefs_relative(dex_src, classdefs) | |
729 | 750 |
730 typeidxs_redir = \ | 751 typeidxs_redir = \ |
731 make_typeidxs_map_after_injection(dex_dst, dex_src, \ | 752 make_typeidxs_map_after_injection(dex_dst, dex_src, \ |
732 relative_classdefs, \ | 753 rel_set.classdefs, \ |
733 relative_typeids) | 754 rel_set.typeids) |
734 methodidxs_redir = \ | 755 methodidxs_redir = \ |
735 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) | 756 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) |
736 | 757 |
737 stridxs_redir = \ | 758 stridxs_redir = \ |
738 make_stridxs_redir_map(dex_src, dex_dst) | 759 make_stridxs_redir_map(dex_src, dex_dst) |
756 | 777 |
757 assert isinstance(classdefs, (list, tuple)) | 778 assert isinstance(classdefs, (list, tuple)) |
758 assert isinstance(dex_dst, DEXFile_linked) | 779 assert isinstance(dex_dst, DEXFile_linked) |
759 assert isinstance(dex_src, DEXFile_linked) | 780 assert isinstance(dex_src, DEXFile_linked) |
760 | 781 |
761 injected_classdefs, injected_typeids, injected_strids = \ | 782 rel_set = dexfile_insert_classdefs_relative(dex_dst, dex_src, classdefs) |
762 dexfile_insert_classdefs_relative(dex_dst, dex_src, classdefs) | |
763 redirect_injected_code(dex_dst, dex_src, classdefs) | 783 redirect_injected_code(dex_dst, dex_src, classdefs) |
764 return injected_classdefs | 784 return list(rel_set.classdefs) |
765 | 785 |
766 | 786 |
767 ## \brief Redirect all references of given class and its methods. | 787 ## \brief Redirect all references of given class and its methods. |
768 # | 788 # |
769 # Redirect all references of given class and its methods to target class. | 789 # Redirect all references of given class and its methods to target class. |