(self, addr_begin, addr_end, assembly, syntax, padding, save_origcode, orig_asm=None)
| 760 | # return the length of patched area |
| 761 | # on failure, return 0 = wrong input, -1 = failed to patch |
| 762 | def fill_code(self, addr_begin, addr_end, assembly, syntax, padding, save_origcode, orig_asm=None): |
| 763 | # treat input as assembly code first |
| 764 | (encoding, _) = self.assemble(assembly, addr_begin, syntax=syntax) |
| 765 | |
| 766 | if encoding is None: |
| 767 | # input might be a hexcode string. try to convert it to raw bytes |
| 768 | encoding = convert_hexstr(assembly) |
| 769 | |
| 770 | if encoding == None: |
| 771 | # invalid input: this is neither assembly nor hexcode string |
| 772 | return 0 |
| 773 | |
| 774 | # save original assembly code before overwritting them |
| 775 | orig_asm = self.ida_get_disasm_range(addr_begin, addr_end) |
| 776 | |
| 777 | # save original comment at addr_begin |
| 778 | # TODO: save comments in this range, but how to interleave them? |
| 779 | orig_comment = idc.Comment(addr_begin) |
| 780 | if orig_comment == None: |
| 781 | orig_comment = '' |
| 782 | |
| 783 | patch_data = "" |
| 784 | assembly_new = [] |
| 785 | size = addr_end - addr_begin |
| 786 | # calculate filling data |
| 787 | encode_chr = ''.join(chr(c) for c in encoding) |
| 788 | while True: |
| 789 | if len(patch_data) + len(encode_chr) <= size: |
| 790 | patch_data = patch_data + encode_chr |
| 791 | assembly_new += [assembly.strip()] |
| 792 | else: |
| 793 | break |
| 794 | |
| 795 | # for now, only support NOP padding on Intel CPU |
| 796 | if padding and self.arch == KS_ARCH_X86: |
| 797 | for i in range(size -len(patch_data)): |
| 798 | assembly_new += ["nop"] |
| 799 | patch_data = patch_data.ljust(size, X86_NOP) |
| 800 | |
| 801 | (plen, p_orig_data) = self.patch(addr_begin, patch_data, len(patch_data)) |
| 802 | if plen == None: |
| 803 | # failed to patch |
| 804 | return -1 |
| 805 | |
| 806 | new_patch_comment = '' |
| 807 | # append original instruction to comments |
| 808 | if save_origcode == True: |
| 809 | if orig_comment == '': |
| 810 | new_patch_comment = "Keypatch filled range [0x{0:X}:0x{1:X}] ({2} bytes), replaced:\n {3}".format(addr_begin, addr_end - 1, addr_end - addr_begin, '\n '.join(orig_asm)) |
| 811 | else: |
| 812 | new_patch_comment = "\nKeypatch filled range [0x{0:X}:0x{1:X}] ({2} bytes), replaced:\n {3}".format(addr_begin, addr_end - 1, addr_end - addr_begin, '\n '.join(orig_asm)) |
| 813 | |
| 814 | new_comment = "{0}{1}".format(orig_comment, new_patch_comment) |
| 815 | idc.MakeComm(addr_begin, new_comment) |
| 816 | |
| 817 | print("Keypatch: successfully filled range [0x{0:X}:0x{1:X}] ({2} bytes) with \"{3}\", replaced \"{4}\"".format( |
| 818 | addr_begin, addr_end - 1, addr_end - addr_begin, assembly, '; '.join(orig_asm))) |
| 819 |
no test coverage detected