Mercurial > paraspace
comparison paraspace/injection.py @ 145:c4324c3461e8
Redirect string indices.
- Change names of *redirect_types*() to *redirect_indices*().
- Redirect string indices in method_redirect_indices() too.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 15 Aug 2011 15:25:39 +0800 |
parents | 46e40afd4558 |
children | 032877e14560 |
comparison
equal
deleted
inserted
replaced
144:46e40afd4558 | 145:c4324c3461e8 |
---|---|
385 dexfile_insert_typeids(dex_dst, dex_src, inserting_typeids) | 385 dexfile_insert_typeids(dex_dst, dex_src, inserting_typeids) |
386 | 386 |
387 return cloning_classdefs, cloning_typeids | 387 return cloning_classdefs, cloning_typeids |
388 | 388 |
389 | 389 |
390 ## \brief Redirect types and methods for the code of given method. | 390 ## \brief Redirect types, methods and strings for the code of given method. |
391 def method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir): | 391 def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
392 stridxs_redir): | |
392 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes | 393 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes |
393 from paraspace.dalvik_opcodes import encode_opcode_vectors | 394 from paraspace.dalvik_opcodes import encode_opcode_vectors |
394 from paraspace.dexfile import DEXFile_linked | 395 from paraspace.dexfile import DEXFile_linked |
395 | 396 |
396 if not method.codeOffRef.is_true: | 397 if not method.codeOffRef.is_true: |
426 methodidx = args[1] | 427 methodidx = args[1] |
427 if methodidx not in methods_redir: | 428 if methodidx not in methods_redir: |
428 return opcode, args | 429 return opcode, args |
429 | 430 |
430 return opcode, (args[0], methods_redir[methodidx], args[2]) | 431 return opcode, (args[0], methods_redir[methodidx], args[2]) |
432 elif opcode == all_opcodes.OP_CONST_STRING: | |
433 stridx = args[1] | |
434 if stridx not in stridxs_redir: | |
435 return opcode, args | |
436 | |
437 return opcode, (args[0], stridxs_redir[stridx]) | |
431 return opcode, args | 438 return opcode, args |
432 | 439 |
433 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] | 440 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] |
434 new_insns_blk = encode_opcode_vectors(new_op_vectors) | 441 new_insns_blk = encode_opcode_vectors(new_op_vectors) |
435 | 442 |
473 # methods_redir respectively. | 480 # methods_redir respectively. |
474 # | 481 # |
475 # \param dex is a DEXFile_linked. | 482 # \param dex is a DEXFile_linked. |
476 # \param classdef is a class definition. | 483 # \param classdef is a class definition. |
477 # \param typeidxs_redir is a map of types. | 484 # \param typeidxs_redir is a map of types. |
485 # \param stridxs_redir is a map of strings. | |
478 # \param methods_redir is a map of methods. | 486 # \param methods_redir is a map of methods. |
479 # | 487 # |
480 def class_redirect_types(dex, classdef, typeidxs_redir, methods_redir): | 488 def class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, |
489 stridxs_redir): | |
481 if not classdef.classDataOffRef.is_true: | 490 if not classdef.classDataOffRef.is_true: |
482 return | 491 return |
483 | 492 |
484 classdata = classdef.classDataOffRef.value | 493 classdata = classdef.classDataOffRef.value |
485 for method in classdata.directMethods.items: | 494 for method in classdata.directMethods.items: |
486 method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir) | 495 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
496 stridxs_redir) | |
487 pass | 497 pass |
488 for method in classdata.virtualMethods.items: | 498 for method in classdata.virtualMethods.items: |
489 method_redirect_typeidxs(dex, method, typeidxs_redir, methods_redir) | 499 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
500 stridxs_redir) | |
490 pass | 501 pass |
491 pass | 502 pass |
492 | 503 |
493 | 504 |
494 ## \brief Make a map to map methods from source types to destinate types. | 505 ## \brief Make a map to map methods from source types to destinate types. |
513 methods_map.update(class_methods_map) | 524 methods_map.update(class_methods_map) |
514 pass | 525 pass |
515 return methods_map | 526 return methods_map |
516 | 527 |
517 | 528 |
529 ## \brief Make a map to map string indices from source to destinate DEX. | |
530 # | |
531 # \param dex_src is soruce of the mapping. | |
532 # \param dex_dst is destination of the mapping. | |
533 # \param classdefs is _DEX_ClassDefs from dex_src. | |
534 # \return a mapping for string indices. | |
535 # | |
536 def make_stridxs_redir_map(dex_src, dex_dst): | |
537 stridxs_map = {} | |
538 for idx, strid in enumerate(dex_src.stringIds.items): | |
539 try: | |
540 tgt_idx = dex_dst.stringIds.items.index(strid) | |
541 except ValueError: | |
542 continue | |
543 stridxs_map[idx] = tgt_idx | |
544 pass | |
545 return stridxs_map | |
546 | |
547 | |
518 ## \biref Redirect types of all code in given DEXFile_linked. | 548 ## \biref Redirect types of all code in given DEXFile_linked. |
519 def dexfile_redirect_types(dex, typeidxs_redir, methods_redir, | 549 def dexfile_redirect_indices(dex, typeidxs_redir, methods_redir, stridxs_redir, |
520 excludes=set([])): | 550 excludes=set([])): |
521 for classdef in dex.classDefs.items: | 551 for classdef in dex.classDefs.items: |
522 typeid = classdef.classIdx | 552 typeid = classdef.classIdx |
523 idx = dex.get_idx_typeid(typeid) | 553 idx = dex.get_idx_typeid(typeid) |
524 if idx in excludes: | 554 if idx in excludes: |
525 continue | 555 continue |
526 class_redirect_types(dex, classdef, typeidxs_redir, methods_redir) | 556 class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, |
557 stridxs_redir) | |
527 pass | 558 pass |
528 pass | 559 pass |
529 | 560 |
530 | 561 |
531 ## \brief Redirect types for code of types specified by given indices. | 562 ## \brief Redirect types for code of types specified by given indices. |
532 def dexfile_redirect_types_typeidxs(dex, typeidxs_redir, methodidxs_redir, | 563 def dexfile_redirect_indices_typeidxs(dex, typeidxs_redir, methodidxs_redir, |
533 typeidxs): | 564 stridxs_redir, typeidxs): |
534 typeidxs = set(typeidxs) | 565 typeidxs = set(typeidxs) |
535 for classdef in dex.classDefs.items: | 566 for classdef in dex.classDefs.items: |
536 typeid = classdef.classIdx | 567 typeid = classdef.classIdx |
537 idx = dex.get_idx_typeid(typeid) | 568 idx = dex.get_idx_typeid(typeid) |
538 if idx not in typeidxs: | 569 if idx not in typeidxs: |
539 continue | 570 continue |
540 class_redirect_types(dex, classdef, typeidxs_redir, methodidxs_redir) | 571 class_redirect_indices(dex, classdef, typeidxs_redir, |
572 methodidxs_redir, stridxs_redir) | |
541 pass | 573 pass |
542 pass | 574 pass |
543 | 575 |
544 | 576 |
545 ## \brief Collect all type indices mentioned in the code of given method. | 577 ## \brief Collect all type indices mentioned in the code of given method. |
647 make_typeidxs_map_after_injection(dex_dst, dex_src, \ | 679 make_typeidxs_map_after_injection(dex_dst, dex_src, \ |
648 relative_classdefs, \ | 680 relative_classdefs, \ |
649 relative_typeids) | 681 relative_typeids) |
650 methodidxs_redir = \ | 682 methodidxs_redir = \ |
651 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) | 683 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) |
652 | 684 |
653 dexfile_redirect_types_typeidxs(dex_dst, typeidxs_redir, | 685 stridxs_redir = \ |
654 methodidxs_redir, | 686 make_stridxs_redir_map(dex_src, dex_dst) |
655 typeidxs_redir.values()) | 687 |
688 dexfile_redirect_indices_typeidxs(dex_dst, typeidxs_redir, | |
689 methodidxs_redir, | |
690 stridxs_redir, | |
691 typeidxs_redir.values()) | |
656 pass | 692 pass |
657 | 693 |
658 | 694 |
659 ## \brief Inject classes and relative information to a DEX file. | 695 ## \brief Inject classes and relative information to a DEX file. |
660 # | 696 # |
672 | 708 |
673 injected_classdefs, injected_typeids = \ | 709 injected_classdefs, injected_typeids = \ |
674 dexfile_insert_classdefs_relative(dex_dst, dex_src, classdefs) | 710 dexfile_insert_classdefs_relative(dex_dst, dex_src, classdefs) |
675 redirect_injected_code(dex_dst, dex_src, classdefs) | 711 redirect_injected_code(dex_dst, dex_src, classdefs) |
676 return injected_classdefs | 712 return injected_classdefs |
713 | |
714 | |
715 ## \brief Redirect all references of given class and its methods. | |
716 # | |
717 # Redirect all references of given class and its methods to target class. | |
718 # | |
719 def redirect_type(dex, src_classname, tgt_classname, exclude_classnames): | |
720 src_typeid = dex.find_typeid_name(src_classname) | |
721 src_typeidx = dex.get_idx_typeid(src_typeid) | |
722 tgt_typeid = dex.find_typeid_name(tgt_classname) | |
723 tgt_typeidx = dex.get_idx_typeid(tgt_typeid) | |
724 typeidxs_redir = {src_typeidx: tgt_typeidx} | |
725 | |
726 methodidxs_redir = \ | |
727 make_methodidxs_redir_map(dex, dex, typeidxs_redir) | |
728 | |
729 stridxs_redir = {} | |
730 | |
731 ex_typeids = [dex.find_typeid_name(name) | |
732 for name in exclude_classnames] | |
733 ex_typeidxs = [dex.get_idx_typeid(typeid) | |
734 for typeid in ex_typeids] | |
735 dexfile_redirect_indices(dex, typeidxs_redir, methodidxs_redir, | |
736 stridxs_redir, excludes=ex_typeidxs) | |
737 pass | |
677 | 738 |
678 | 739 |
679 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. | 740 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. |
680 # | 741 # |
681 # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, | 742 # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, |
685 def inject_redir_no_restore(src_linked, inj_classname, | 746 def inject_redir_no_restore(src_linked, inj_classname, |
686 dst_linked, redir_classname, decls): | 747 dst_linked, redir_classname, decls): |
687 inj_classdef = src_linked.find_class_name(inj_classname) | 748 inj_classdef = src_linked.find_class_name(inj_classname) |
688 injected_classdefs = inject_classdefs(dst_linked, src_linked, | 749 injected_classdefs = inject_classdefs(dst_linked, src_linked, |
689 [inj_classdef]) | 750 [inj_classdef]) |
690 | 751 excludes = [dst_linked.get_classdef_name(classdef) |
691 redir_typeid = dst_linked.find_typeid_name(redir_classname) | 752 for classdef in injected_classdefs] |
692 redir_typeidx = dst_linked.get_idx_typeid(redir_typeid) | 753 redirect_type(dst_linked, redir_classname, inj_classname, excludes) |
693 inj_typeid = dst_linked.find_typeid_name(inj_classname) | |
694 inj_typeidx = dst_linked.get_idx_typeid(inj_typeid) | |
695 typeidxs_redir = {redir_typeidx: inj_typeidx} | |
696 | |
697 methodidxs_redir = \ | |
698 make_methodidxs_redir_map(dst_linked, dst_linked, typeidxs_redir) | |
699 | |
700 injected_typeidxs = [dst_linked.get_idx_classdef(classdef) | |
701 for classdef in injected_classdefs] | |
702 dexfile_redirect_types(dst_linked, typeidxs_redir, methodidxs_redir, | |
703 excludes=injected_typeidxs) | |
704 pass | 754 pass |
705 | 755 |
706 | 756 |
707 ## \brief Make indices map for typeid and methodid. | 757 ## \brief Make indices map for typeid and methodid. |
708 # | 758 # |
709 # It is used to create indices maps for typeid and methodid after | 759 # It is used to create indices maps for typeid and methodid after |
710 # changing order. For example, after sorting sorted array after an | 760 # changing order. For example, after sorting sorted array after an |
711 # injection, this function create maps for remapping indices mentioned | 761 # injection, this function create maps for remapping indices mentioned |
712 # in the code. | 762 # in the code. |
713 # | 763 # |
714 def _make_idx_map(saved_typeids, saved_methodids, | 764 def _make_idx_map(saved_typeids, saved_methodids, saved_strids, |
715 new_typeids, new_methodids): | 765 new_typeids, new_methodids, new_strids): |
716 methodidxs_map = dict([(idx, new_methodids.index(methodid)) | 766 methodidxs_map = dict([(idx, new_methodids.index(methodid)) |
717 for idx, methodid in enumerate(saved_methodids)]) | 767 for idx, methodid in enumerate(saved_methodids)]) |
718 typeidxs_map = dict([(idx, new_typeids.index(typeid)) | 768 typeidxs_map = dict([(idx, new_typeids.index(typeid)) |
719 for idx, typeid in enumerate(saved_typeids)]) | 769 for idx, typeid in enumerate(saved_typeids)]) |
720 return typeidxs_map, methodidxs_map | 770 stridxs_map = dict([(idx, new_strids.index(strid)) |
771 for idx, strid in enumerate(saved_strids)]) | |
772 | |
773 return typeidxs_map, methodidxs_map, stridxs_map | |
721 | 774 |
722 | 775 |
723 ## \brief Sort sorted arrays and remapping indices for code blocks. | 776 ## \brief Sort sorted arrays and remapping indices for code blocks. |
724 # | 777 # |
725 # Since sorting changes the order of sorted arrays, code blocks should | 778 # Since sorting changes the order of sorted arrays, code blocks should |
728 def dex_sort_sorted_arrays_consistent(dex_linked): | 781 def dex_sort_sorted_arrays_consistent(dex_linked): |
729 from paraspace.dex_deptracker import dex_sort_sorted_arrays | 782 from paraspace.dex_deptracker import dex_sort_sorted_arrays |
730 | 783 |
731 saved_typeids = list(dex_linked.typeIds.items) | 784 saved_typeids = list(dex_linked.typeIds.items) |
732 saved_methodids = list(dex_linked.methodIds.items) | 785 saved_methodids = list(dex_linked.methodIds.items) |
786 saved_strids = list(dex_linked.stringIds.items) | |
733 | 787 |
734 dex_sort_sorted_arrays(dex_linked) | 788 dex_sort_sorted_arrays(dex_linked) |
735 | 789 |
736 new_typeids = dex_linked.typeIds.items | 790 new_typeids = dex_linked.typeIds.items |
737 new_methodids = dex_linked.methodIds.items | 791 new_methodids = dex_linked.methodIds.items |
738 typeidxs_map, methodidxs_map = \ | 792 new_strids = dex_linked.stringIds.items |
739 _make_idx_map(saved_typeids, saved_methodids, \ | 793 typeidxs_map, methodidxs_map, stridxs_map = \ |
740 new_typeids, new_methodids) | 794 _make_idx_map(saved_typeids, saved_methodids, saved_strids, \ |
741 | 795 new_typeids, new_methodids, new_strids) |
742 dexfile_redirect_types(dex_linked, typeidxs_map, methodidxs_map) | 796 |
797 dexfile_redirect_indices(dex_linked, typeidxs_map, methodidxs_map, | |
798 stridxs_map) | |
743 pass | 799 pass |
744 | 800 |
745 | 801 |
746 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. | 802 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. |
747 # | 803 # |