(self, address, patch_data, len)
| 630 | # patch at address, return the number of written bytes & original data |
| 631 | # on patch failure, we revert to the original code, then return (None, None) |
| 632 | def patch(self, address, patch_data, len): |
| 633 | # save original function end to fix IDA re-analyze issue after patching |
| 634 | orig_func_end = idc.GetFunctionAttr(address, idc.FUNCATTR_END) |
| 635 | |
| 636 | (patched_len, orig_data) = self.patch_raw(address, patch_data, len) |
| 637 | |
| 638 | if len != patched_len: |
| 639 | # patch failure |
| 640 | if patched_len > 0: |
| 641 | # revert the changes |
| 642 | (rlen, _) = self.patch_raw(address, orig_data, patched_len) |
| 643 | if rlen == patched_len: |
| 644 | print("Keypatch: successfully reverted changes of {0:d} byte(s) at 0x{1:X} [{2}]".format( |
| 645 | patched_len, address, to_hexstr(orig_data))) |
| 646 | else: |
| 647 | print("Keypatch: FAILED to revert changes of {0:d} byte(s) at 0x{1:X} [{2}]".format( |
| 648 | patched_len, address, to_hexstr(orig_data))) |
| 649 | |
| 650 | return (None, None) |
| 651 | |
| 652 | # ask IDA to re-analyze the patched area |
| 653 | if orig_func_end == idc.BADADDR: |
| 654 | # only analyze patched bytes, otherwise it would take a lot of time to re-analyze the whole binary |
| 655 | idaapi.analyze_area(address, address + patched_len + 1) |
| 656 | else: |
| 657 | idaapi.analyze_area(address, orig_func_end) |
| 658 | |
| 659 | # try to fix IDA function re-analyze issue after patching |
| 660 | idaapi.func_setend(address, orig_func_end) |
| 661 | |
| 662 | return (patched_len, orig_data) |
| 663 | |
| 664 | # return number of bytes patched |
| 665 | # return |
no test coverage detected