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 #