Mercurial > paraspace
comparison paraspace/injection.py @ 152:bc213cb88636
Inject and redirect fields
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 16 Aug 2011 18:10:11 +0800 |
parents | 91fabeaffce8 |
children | c659b8c7d6cb |
comparison
equal
deleted
inserted
replaced
151:91fabeaffce8 | 152:bc213cb88636 |
---|---|
271 ## \biref Relative object set for a _DEX_ClassData. | 271 ## \biref Relative object set for a _DEX_ClassData. |
272 class classdef_rel_set(object): | 272 class classdef_rel_set(object): |
273 classdefs = None | 273 classdefs = None |
274 typeids = None | 274 typeids = None |
275 strids = None | 275 strids = None |
276 | 276 fieldids = None |
277 def __init__(self, classdefs, typeids, strids): | 277 |
278 def __init__(self, classdefs, typeids, strids, fieldids): | |
278 self.classdefs = set(classdefs) | 279 self.classdefs = set(classdefs) |
279 self.typeids = set(typeids) | 280 self.typeids = set(typeids) |
280 self.strids = set(strids) | 281 self.strids = set(strids) |
282 self.fieldids = set(fieldids) | |
281 pass | 283 pass |
282 | 284 |
283 @staticmethod | 285 @staticmethod |
284 def dup(src): | 286 def dup(src): |
285 return relative_obj_set(src.classdefs, src.typeids, src.strids) | 287 return relative_obj_set(src.classdefs, src.typeids, |
288 src.strids, str.fieldids) | |
286 | 289 |
287 def update(self, new_data): | 290 def update(self, new_data): |
288 self.classdefs.update(new_data.classdefs) | 291 self.classdefs.update(new_data.classdefs) |
289 self.typeids.update(new_data.typeids) | 292 self.typeids.update(new_data.typeids) |
290 self.strids.update(new_data.strids) | 293 self.strids.update(new_data.strids) |
294 self.fieldids.update(new_data.fieldids) | |
291 pass | 295 pass |
292 pass | 296 pass |
293 | 297 |
294 | 298 |
295 ## \brief Collect all type and string indices mentioned in the method code. | 299 ## \brief Collect all type and string indices mentioned in the method code. |
296 # | 300 # |
297 # \param method is a \ref _DEX_Method. | 301 # \param method is a \ref _DEX_Method. |
298 # \return a list of type indices mentioned in the code. | 302 # \return a list of type indices mentioned in the code. |
299 # | 303 # |
300 def collect_typeidxs_stridxs_in_method(dex, method): | 304 def collect_typeidxs_stridxs_fieldidxs_in_method(dex, method): |
301 from paraspace.dexfile import _DEX_Method, DEXFile_linked | 305 from paraspace.dexfile import _DEX_Method, DEXFile_linked |
302 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes | 306 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes |
303 from itertools import chain | 307 from paraspace.dalvik_opcodes import all_opcodes |
304 | 308 |
305 assert isinstance(method, _DEX_Method) | 309 assert isinstance(method, _DEX_Method) |
306 | 310 |
307 def get_typeidx_methodidx(methodidx): | 311 def get_typeidx_methodidx(methodidx): |
308 methodid = dex.find_methodid_idx(methodidx) | 312 methodid = dex.find_methodid_idx(methodidx) |
342 stridx = args[1] | 346 stridx = args[1] |
343 return stridx | 347 return stridx |
344 | 348 |
345 return None | 349 return None |
346 | 350 |
351 field_opcodes = set([all_opcodes.OP_IGET, | |
352 all_opcodes.OP_IGET_WIDE, | |
353 all_opcodes.OP_IGET_OBJECT, | |
354 all_opcodes.OP_IGET_BOOLEAN, | |
355 all_opcodes.OP_IGET_BYTE, | |
356 all_opcodes.OP_IGET_CHAR, | |
357 all_opcodes.OP_IGET_SHORT, | |
358 all_opcodes.OP_IPUT, | |
359 all_opcodes.OP_IPUT_WIDE, | |
360 all_opcodes.OP_IPUT_OBJECT, | |
361 all_opcodes.OP_IPUT_BOOLEAN, | |
362 all_opcodes.OP_IPUT_BYTE, | |
363 all_opcodes.OP_IPUT_CHAR, | |
364 all_opcodes.OP_IPUT_SHORT, | |
365 all_opcodes.OP_SGET, | |
366 all_opcodes.OP_SGET_WIDE, | |
367 all_opcodes.OP_SGET_OBJECT, | |
368 all_opcodes.OP_SGET_BOOLEAN, | |
369 all_opcodes.OP_SGET_BYTE, | |
370 all_opcodes.OP_SGET_CHAR, | |
371 all_opcodes.OP_SGET_SHORT, | |
372 all_opcodes.OP_SPUT, | |
373 all_opcodes.OP_SPUT_WIDE, | |
374 all_opcodes.OP_SPUT_OBJECT, | |
375 all_opcodes.OP_SPUT_BOOLEAN, | |
376 all_opcodes.OP_SPUT_BYTE, | |
377 all_opcodes.OP_SPUT_CHAR, | |
378 all_opcodes.OP_SPUT_SHORT]) | |
379 def collect_fields_in_op_vector(op_vector): | |
380 code, args = op_vector | |
381 if code in field_opcodes: | |
382 fieldidx = args[2] | |
383 return fieldidx | |
384 pass | |
385 | |
347 code_blk = DEXFile_linked.get_code_block_method(method) | 386 code_blk = DEXFile_linked.get_code_block_method(method) |
348 op_vectors = decode_insn_blk(code_blk) | 387 op_vectors = decode_insn_blk(code_blk) |
349 types_insns = [collect_types_in_op_vector(op_vector) | 388 types_insns = [collect_types_in_op_vector(op_vector) |
350 for op_vector in op_vectors] | 389 for op_vector in op_vectors] |
351 typeidxs = [idx for idx in types_insns if idx is not None] | 390 typeidxs = [idx for idx in types_insns if idx is not None] |
352 | 391 |
353 strs_insns = [collect_strings_in_op_vector(op_vectors) | 392 strs_insns = [collect_strings_in_op_vector(op_vector) |
354 for op_vectors in op_vectors] | 393 for op_vector in op_vectors] |
355 stridxs = [idx for idx in strs_insns if idx is not None] | 394 stridxs = [idx for idx in strs_insns if idx is not None] |
356 | 395 |
357 return typeidxs, stridxs | 396 fields_insns = [collect_fields_in_op_vector(op_vector) |
397 for op_vector in op_vectors] | |
398 fieldidxs = [idx for idx in fields_insns if idx is not None] | |
399 | |
400 return typeidxs, stridxs, fieldidxs | |
358 | 401 |
359 | 402 |
360 ## \brief Collect all type and string indices mentioned by the class code. | 403 ## \brief Collect all type and string indices mentioned by the class code. |
361 def collect_typeidxs_stridxs_mentioned_by_class(dex, classdef): | 404 def collect_typeidxs_stridxs_fieldidxs_mentioned_by_class(dex, classdef): |
362 from paraspace.dexfile import DEXFile_linked | 405 from paraspace.dexfile import DEXFile_linked |
363 | 406 |
364 assert isinstance(dex, DEXFile_linked) | 407 assert isinstance(dex, DEXFile_linked) |
365 | 408 |
366 typeidxs = set() | 409 typeidxs = set() |
367 stridxs = set() | 410 stridxs = set() |
411 fieldidxs = set() | |
368 methods = DEXFile_linked.get_methods_classdef(classdef) | 412 methods = DEXFile_linked.get_methods_classdef(classdef) |
369 for method in methods: | 413 for method in methods: |
370 method_typeidxs, method_stridxs = \ | 414 method_typeidxs, method_stridxs, method_fieldidxs = \ |
371 collect_typeidxs_stridxs_in_method(dex, method) | 415 collect_typeidxs_stridxs_fieldidxs_in_method(dex, method) |
372 typeidxs.update(method_typeidxs) | 416 typeidxs.update(method_typeidxs) |
373 stridxs.update(method_stridxs) | 417 stridxs.update(method_stridxs) |
374 pass | 418 fieldidxs.update(method_fieldidxs) |
375 | 419 pass |
376 return list(typeidxs), list(stridxs) | 420 |
421 return list(typeidxs), list(stridxs), list(fieldidxs) | |
377 | 422 |
378 | 423 |
379 ## \brief Collect info of classes mentioned by the code of given class. | 424 ## \brief Collect info of classes mentioned by the code of given class. |
380 def _find_class_relative(dex, classdef): | 425 def _find_class_relative(dex, classdef): |
381 def classify_typeids_defined(dex, typeids): | 426 def classify_typeids_defined(dex, typeids): |
390 classdefs.append(classdef) | 435 classdefs.append(classdef) |
391 pass | 436 pass |
392 pass | 437 pass |
393 return classdefs, undef_typeids | 438 return classdefs, undef_typeids |
394 | 439 |
395 typeidxs, stridxs = \ | 440 typeidxs, stridxs, fieldidxs = \ |
396 collect_typeidxs_stridxs_mentioned_by_class(dex, classdef) | 441 collect_typeidxs_stridxs_fieldidxs_mentioned_by_class(dex, classdef) |
397 typeids = [dex.find_typeid_idx(typeidx) | 442 typeids = [dex.find_typeid_idx(typeidx) |
398 for typeidx in typeidxs] | 443 for typeidx in typeidxs] |
399 strids = [dex.find_strid_idx(idx) for idx in stridxs] | 444 strids = [dex.find_strid_idx(idx) for idx in stridxs] |
445 fieldids = [dex.find_fieldid_idx(idx) for idx in fieldidxs] | |
400 | 446 |
401 classdefs, typeids = classify_typeids_defined(dex, typeids) | 447 classdefs, typeids = classify_typeids_defined(dex, typeids) |
402 | 448 |
403 rel_set = classdef_rel_set(classdefs, typeids, strids) | 449 rel_set = classdef_rel_set(classdefs, typeids, strids, fieldids) |
404 return rel_set | 450 return rel_set |
405 | 451 |
406 | 452 |
407 def dexfile_insert_classdefs(dex_dst, dex_src, classdefs): | 453 def dexfile_insert_classdefs(dex_dst, dex_src, classdefs): |
408 clones = [dexfile_insert_class(dex_dst, classdef) | 454 clones = [dexfile_insert_class(dex_dst, classdef) |
418 | 464 |
419 ## \brief Insert _DEX_StringIds into another DEX. | 465 ## \brief Insert _DEX_StringIds into another DEX. |
420 def dexfile_insert_stringids(dex_dst, dex_src, strids): | 466 def dexfile_insert_stringids(dex_dst, dex_src, strids): |
421 clones = [dexfile_insert_stringid(dex_dst, dex_src, strid) | 467 clones = [dexfile_insert_stringid(dex_dst, dex_src, strid) |
422 for strid in strids] | 468 for strid in strids] |
469 return clones | |
470 | |
471 | |
472 ## \brief Insert _DEX_FieldId into another DEX. | |
473 def dexfile_insert_fieldid(dex_dst, dex_src, fieldid): | |
474 clone = _clone_composite(dex_dst, fieldid) | |
475 return clone | |
476 | |
477 | |
478 ## \brief Insert _DEX_FieldIds into another DEX. | |
479 def dexfile_insert_fieldids(dex_dst, dex_src, fieldids): | |
480 clones = [dexfile_insert_fieldid(dex_dst, dex_src, fieldid) | |
481 for fieldid in fieldids] | |
423 return clones | 482 return clones |
424 | 483 |
425 | 484 |
426 ## \brief Clone and insert a _DEX_TypeId to another DEXFile_linked. | 485 ## \brief Clone and insert a _DEX_TypeId to another DEXFile_linked. |
427 # | 486 # |
476 return clones | 535 return clones |
477 | 536 |
478 | 537 |
479 ## \brief Collects relative type IDs and classes definition for given class. | 538 ## \brief Collects relative type IDs and classes definition for given class. |
480 def collect_classdefs_relative(dex, classdefs): | 539 def collect_classdefs_relative(dex, classdefs): |
481 rel_set = classdef_rel_set(classdefs, [], []) | 540 rel_set = classdef_rel_set(classdefs, [], [], []) |
482 | 541 |
483 classdef_queue = list(classdefs) | 542 classdef_queue = list(classdefs) |
484 while classdef_queue: | 543 while classdef_queue: |
485 cur_classdef = classdef_queue.pop(0) | 544 cur_classdef = classdef_queue.pop(0) |
486 | 545 |
522 dexfile_insert_classdefs(dex_dst, dex_src, rel_set.classdefs) | 581 dexfile_insert_classdefs(dex_dst, dex_src, rel_set.classdefs) |
523 cloning_typeids = \ | 582 cloning_typeids = \ |
524 dexfile_insert_or_merge_typeids(dex_dst, dex_src, rel_set.typeids) | 583 dexfile_insert_or_merge_typeids(dex_dst, dex_src, rel_set.typeids) |
525 cloning_strids = \ | 584 cloning_strids = \ |
526 dexfile_insert_stringids(dex_dst, dex_src, rel_set.strids) | 585 dexfile_insert_stringids(dex_dst, dex_src, rel_set.strids) |
586 cloning_fieldids = \ | |
587 dexfile_insert_fieldids(dex_dst, dex_src, rel_set.fieldids) | |
527 | 588 |
528 cloning = classdef_rel_set(cloning_classdefs, cloning_typeids, | 589 cloning = classdef_rel_set(cloning_classdefs, cloning_typeids, |
529 cloning_strids) | 590 cloning_strids, cloning_fieldids) |
530 return cloning | 591 return cloning |
531 | 592 |
532 | 593 |
533 ## \brief Redirect types, methods and strings for the code of given method. | 594 ## \brief Redirect types, methods and strings for the code of given method. |
534 def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, | 595 def method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
535 stridxs_redir): | 596 stridxs_redir, fieldidxs_redir): |
536 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes | 597 from paraspace.dalvik_opcodes import decode_insn_blk, all_opcodes |
537 from paraspace.dalvik_opcodes import encode_opcode_vectors | 598 from paraspace.dalvik_opcodes import encode_opcode_vectors |
538 from paraspace.dexfile import DEXFile_linked | 599 from paraspace.dexfile import DEXFile_linked |
539 | 600 |
540 if not method.codeOffRef.is_true: | 601 if not method.codeOffRef.is_true: |
542 | 603 |
543 code = method.codeOffRef.value | 604 code = method.codeOffRef.value |
544 insns_blk = code.insns.data | 605 insns_blk = code.insns.data |
545 op_vectors = decode_insn_blk(insns_blk) | 606 op_vectors = decode_insn_blk(insns_blk) |
546 | 607 |
608 field_opcodes = set([all_opcodes.OP_IGET, | |
609 all_opcodes.OP_IGET_WIDE, | |
610 all_opcodes.OP_IGET_OBJECT, | |
611 all_opcodes.OP_IGET_BOOLEAN, | |
612 all_opcodes.OP_IGET_BYTE, | |
613 all_opcodes.OP_IGET_CHAR, | |
614 all_opcodes.OP_IGET_SHORT, | |
615 all_opcodes.OP_IPUT, | |
616 all_opcodes.OP_IPUT_WIDE, | |
617 all_opcodes.OP_IPUT_OBJECT, | |
618 all_opcodes.OP_IPUT_BOOLEAN, | |
619 all_opcodes.OP_IPUT_BYTE, | |
620 all_opcodes.OP_IPUT_CHAR, | |
621 all_opcodes.OP_IPUT_SHORT, | |
622 all_opcodes.OP_SGET, | |
623 all_opcodes.OP_SGET_WIDE, | |
624 all_opcodes.OP_SGET_OBJECT, | |
625 all_opcodes.OP_SGET_BOOLEAN, | |
626 all_opcodes.OP_SGET_BYTE, | |
627 all_opcodes.OP_SGET_CHAR, | |
628 all_opcodes.OP_SGET_SHORT, | |
629 all_opcodes.OP_SPUT, | |
630 all_opcodes.OP_SPUT_WIDE, | |
631 all_opcodes.OP_SPUT_OBJECT, | |
632 all_opcodes.OP_SPUT_BOOLEAN, | |
633 all_opcodes.OP_SPUT_BYTE, | |
634 all_opcodes.OP_SPUT_CHAR, | |
635 all_opcodes.OP_SPUT_SHORT]) | |
547 def redirect(opcode, args): | 636 def redirect(opcode, args): |
548 if opcode == all_opcodes.OP_NEW_INSTANCE: | 637 if opcode == all_opcodes.OP_NEW_INSTANCE: |
549 typeidx = args[1] | 638 typeidx = args[1] |
550 if typeidx in typeidxs_redir: | 639 if typeidx in typeidxs_redir: |
551 to_type = typeidxs_redir[typeidx] | 640 to_type = typeidxs_redir[typeidx] |
576 stridx = args[1] | 665 stridx = args[1] |
577 if stridx not in stridxs_redir: | 666 if stridx not in stridxs_redir: |
578 return opcode, args | 667 return opcode, args |
579 | 668 |
580 return opcode, (args[0], stridxs_redir[stridx]) | 669 return opcode, (args[0], stridxs_redir[stridx]) |
670 elif opcode in field_opcodes: | |
671 fieldidx = args[2] | |
672 if fieldidx not in fieldidxs_redir: | |
673 return opcode, args | |
674 return opcode, (args[0], args[1], fieldidxs_redir[fieldidx]) | |
581 return opcode, args | 675 return opcode, args |
582 | 676 |
583 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] | 677 new_op_vectors = [redirect(opcode, args) for opcode, args in op_vectors] |
584 new_insns_blk = encode_opcode_vectors(new_op_vectors) | 678 new_insns_blk = encode_opcode_vectors(new_op_vectors) |
585 | 679 |
623 # methods_redir respectively. | 717 # methods_redir respectively. |
624 # | 718 # |
625 # \param dex is a DEXFile_linked. | 719 # \param dex is a DEXFile_linked. |
626 # \param classdef is a class definition. | 720 # \param classdef is a class definition. |
627 # \param typeidxs_redir is a map of types. | 721 # \param typeidxs_redir is a map of types. |
722 # \param methods_redir is a map of methods. | |
628 # \param stridxs_redir is a map of strings. | 723 # \param stridxs_redir is a map of strings. |
629 # \param methods_redir is a map of methods. | 724 # \param fieldidxs_redir is a map of fields. |
630 # | 725 # |
631 def class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, | 726 def class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, |
632 stridxs_redir): | 727 stridxs_redir, fieldidxs_redir): |
633 if not classdef.classDataOffRef.is_true: | 728 if not classdef.classDataOffRef.is_true: |
634 return | 729 return |
635 | 730 |
636 classdata = classdef.classDataOffRef.value | 731 classdata = classdef.classDataOffRef.value |
637 for method in classdata.directMethods.items: | 732 for method in classdata.directMethods.items: |
638 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, | 733 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
639 stridxs_redir) | 734 stridxs_redir, fieldidxs_redir) |
640 pass | 735 pass |
641 for method in classdata.virtualMethods.items: | 736 for method in classdata.virtualMethods.items: |
642 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, | 737 method_redirect_indices(dex, method, typeidxs_redir, methods_redir, |
643 stridxs_redir) | 738 stridxs_redir, fieldidxs_redir) |
644 pass | 739 pass |
645 pass | 740 pass |
646 | 741 |
647 | 742 |
648 ## \brief Make a map to map methods from source types to destinate types. | 743 ## \brief Make a map to map methods from source types to destinate types. |
686 stridxs_map[idx] = tgt_idx | 781 stridxs_map[idx] = tgt_idx |
687 pass | 782 pass |
688 return stridxs_map | 783 return stridxs_map |
689 | 784 |
690 | 785 |
786 def make_fieldidxs_redir_map(dex_src, dex_dst): | |
787 fieldidxs_map = {} | |
788 for idx, fieldid in enumerate(dex_src.fieldIds.items): | |
789 try: | |
790 tgt_idx = dex_dst.fieldIds.items.index(fieldid) | |
791 except ValueError: | |
792 continue | |
793 fieldidxs_map[idx] = tgt_idx | |
794 pass | |
795 return fieldidxs_map | |
796 | |
797 | |
691 ## \biref Redirect types of all code in given DEXFile_linked. | 798 ## \biref Redirect types of all code in given DEXFile_linked. |
692 def dexfile_redirect_indices(dex, typeidxs_redir, methods_redir, stridxs_redir, | 799 def dexfile_redirect_indices(dex, typeidxs_redir, methods_redir, stridxs_redir, |
693 excludes=set([])): | 800 fieldidxs_redir, excludes=set([])): |
694 for classdef in dex.classDefs.items: | 801 for classdef in dex.classDefs.items: |
695 typeid = classdef.classIdx | 802 typeid = classdef.classIdx |
696 idx = dex.get_idx_typeid(typeid) | 803 idx = dex.get_idx_typeid(typeid) |
697 if idx in excludes: | 804 if idx in excludes: |
698 continue | 805 continue |
699 class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, | 806 class_redirect_indices(dex, classdef, typeidxs_redir, methods_redir, |
700 stridxs_redir) | 807 stridxs_redir, fieldidxs_redir) |
701 pass | 808 pass |
702 pass | 809 pass |
703 | 810 |
704 | 811 |
705 ## \brief Redirect types for code of types specified by given indices. | 812 ## \brief Redirect types for code of types specified by given indices. |
706 def dexfile_redirect_indices_typeidxs(dex, typeidxs_redir, methodidxs_redir, | 813 def dexfile_redirect_indices_typeidxs(dex, typeidxs_redir, methodidxs_redir, |
707 stridxs_redir, typeidxs): | 814 stridxs_redir, fieldidxs_redir, |
815 typeidxs): | |
708 typeidxs = set(typeidxs) | 816 typeidxs = set(typeidxs) |
709 for classdef in dex.classDefs.items: | 817 for classdef in dex.classDefs.items: |
710 typeid = classdef.classIdx | 818 typeid = classdef.classIdx |
711 idx = dex.get_idx_typeid(typeid) | 819 idx = dex.get_idx_typeid(typeid) |
712 if idx not in typeidxs: | 820 if idx not in typeidxs: |
713 continue | 821 continue |
714 class_redirect_indices(dex, classdef, typeidxs_redir, | 822 class_redirect_indices(dex, classdef, typeidxs_redir, |
715 methodidxs_redir, stridxs_redir) | 823 methodidxs_redir, stridxs_redir, |
824 fieldidxs_redir) | |
716 pass | 825 pass |
717 pass | 826 pass |
718 | 827 |
719 | 828 |
720 ## \brief Make a mapping for type indices of injection. | 829 ## \brief Make a mapping for type indices of injection. |
755 methodidxs_redir = \ | 864 methodidxs_redir = \ |
756 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) | 865 make_methodidxs_redir_map(dex_src, dex_dst, typeidxs_redir) |
757 | 866 |
758 stridxs_redir = \ | 867 stridxs_redir = \ |
759 make_stridxs_redir_map(dex_src, dex_dst) | 868 make_stridxs_redir_map(dex_src, dex_dst) |
869 | |
870 fieldidxs_redir = \ | |
871 make_fieldidxs_redir_map(dex_src, dex_dst) | |
760 | 872 |
761 dexfile_redirect_indices_typeidxs(dex_dst, typeidxs_redir, | 873 dexfile_redirect_indices_typeidxs(dex_dst, typeidxs_redir, |
762 methodidxs_redir, | 874 methodidxs_redir, |
763 stridxs_redir, | 875 stridxs_redir, |
876 fieldidxs_redir, | |
764 typeidxs_redir.values()) | 877 typeidxs_redir.values()) |
765 pass | 878 pass |
766 | 879 |
767 | 880 |
768 ## \brief Inject classes and relative information to a DEX file. | 881 ## \brief Inject classes and relative information to a DEX file. |
797 | 910 |
798 methodidxs_redir = \ | 911 methodidxs_redir = \ |
799 make_methodidxs_redir_map(dex, dex, typeidxs_redir) | 912 make_methodidxs_redir_map(dex, dex, typeidxs_redir) |
800 | 913 |
801 stridxs_redir = {} | 914 stridxs_redir = {} |
915 fieldidxs_redir = {} | |
802 | 916 |
803 ex_typeids = [dex.find_typeid_name(name) | 917 ex_typeids = [dex.find_typeid_name(name) |
804 for name in exclude_classnames] | 918 for name in exclude_classnames] |
805 ex_typeidxs = [dex.get_idx_typeid(typeid) | 919 ex_typeidxs = [dex.get_idx_typeid(typeid) |
806 for typeid in ex_typeids] | 920 for typeid in ex_typeids] |
807 dexfile_redirect_indices(dex, typeidxs_redir, methodidxs_redir, | 921 dexfile_redirect_indices(dex, typeidxs_redir, methodidxs_redir, |
808 stridxs_redir, excludes=ex_typeidxs) | 922 stridxs_redir, fieldidxs_redir, |
923 excludes=ex_typeidxs) | |
809 pass | 924 pass |
810 | 925 |
811 | 926 |
812 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. | 927 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. |
813 # | 928 # |
831 # It is used to create indices maps for typeid and methodid after | 946 # It is used to create indices maps for typeid and methodid after |
832 # changing order. For example, after sorting sorted array after an | 947 # changing order. For example, after sorting sorted array after an |
833 # injection, this function create maps for remapping indices mentioned | 948 # injection, this function create maps for remapping indices mentioned |
834 # in the code. | 949 # in the code. |
835 # | 950 # |
836 def _make_idx_map(saved_typeids, saved_methodids, saved_strids, | 951 def _make_idx_map(saved_typeids, saved_methodids, saved_strids, saved_fieldids, |
837 new_typeids, new_methodids, new_strids): | 952 new_typeids, new_methodids, new_strids, new_fieldids): |
838 methodidxs_map = dict([(idx, new_methodids.index(methodid)) | 953 methodidxs_map = dict([(idx, new_methodids.index(methodid)) |
839 for idx, methodid in enumerate(saved_methodids)]) | 954 for idx, methodid in enumerate(saved_methodids)]) |
840 typeidxs_map = dict([(idx, new_typeids.index(typeid)) | 955 typeidxs_map = dict([(idx, new_typeids.index(typeid)) |
841 for idx, typeid in enumerate(saved_typeids)]) | 956 for idx, typeid in enumerate(saved_typeids)]) |
842 stridxs_map = dict([(idx, new_strids.index(strid)) | 957 stridxs_map = dict([(idx, new_strids.index(strid)) |
843 for idx, strid in enumerate(saved_strids)]) | 958 for idx, strid in enumerate(saved_strids)]) |
844 | 959 fieldidxs_map = dict([(idx, new_fieldids.index(fieldid)) |
845 return typeidxs_map, methodidxs_map, stridxs_map | 960 for idx, fieldid in enumerate(saved_fieldids)]) |
961 | |
962 return typeidxs_map, methodidxs_map, stridxs_map, fieldidxs_map | |
846 | 963 |
847 | 964 |
848 ## \brief Sort sorted arrays and remapping indices for code blocks. | 965 ## \brief Sort sorted arrays and remapping indices for code blocks. |
849 # | 966 # |
850 # Since sorting changes the order of sorted arrays, code blocks should | 967 # Since sorting changes the order of sorted arrays, code blocks should |
854 from paraspace.dex_deptracker import dex_sort_sorted_arrays | 971 from paraspace.dex_deptracker import dex_sort_sorted_arrays |
855 | 972 |
856 saved_typeids = list(dex_linked.typeIds.items) | 973 saved_typeids = list(dex_linked.typeIds.items) |
857 saved_methodids = list(dex_linked.methodIds.items) | 974 saved_methodids = list(dex_linked.methodIds.items) |
858 saved_strids = list(dex_linked.stringIds.items) | 975 saved_strids = list(dex_linked.stringIds.items) |
976 saved_fieldids = list(dex_linked.fieldIds.items) | |
859 | 977 |
860 dex_sort_sorted_arrays(dex_linked) | 978 dex_sort_sorted_arrays(dex_linked) |
861 | 979 |
862 new_typeids = dex_linked.typeIds.items | 980 new_typeids = dex_linked.typeIds.items |
863 new_methodids = dex_linked.methodIds.items | 981 new_methodids = dex_linked.methodIds.items |
864 new_strids = dex_linked.stringIds.items | 982 new_strids = dex_linked.stringIds.items |
865 typeidxs_map, methodidxs_map, stridxs_map = \ | 983 new_fieldids = dex_linked.fieldIds.items |
984 typeidxs_map, methodidxs_map, stridxs_map, fieldidxs_map = \ | |
866 _make_idx_map(saved_typeids, saved_methodids, saved_strids, \ | 985 _make_idx_map(saved_typeids, saved_methodids, saved_strids, \ |
867 new_typeids, new_methodids, new_strids) | 986 saved_fieldids, \ |
987 new_typeids, new_methodids, new_strids, \ | |
988 new_fieldids) | |
868 | 989 |
869 dexfile_redirect_indices(dex_linked, typeidxs_map, methodidxs_map, | 990 dexfile_redirect_indices(dex_linked, typeidxs_map, methodidxs_map, |
870 stridxs_map) | 991 stridxs_map, fieldidxs_map) |
871 pass | 992 pass |
872 | 993 |
873 | 994 |
874 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. | 995 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. |
875 # | 996 # |