MCPcopy Index your code
hub / github.com/keystone-engine/keypatch / fill_code

Method fill_code

keypatch.py:762–823  ·  view source on GitHub ↗
(self, addr_begin, addr_end, assembly, syntax, padding, save_origcode, orig_asm=None)

Source from the content-addressed store, hash-verified

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

Callers 1

fill_rangeMethod · 0.80

Calls 4

assembleMethod · 0.95
ida_get_disasm_rangeMethod · 0.95
patchMethod · 0.95
convert_hexstrFunction · 0.85

Tested by

no test coverage detected