| 774 | |
| 775 | |
| 776 | def perform_base_relocations(self, delta): |
| 777 | codeBaseAddr = self._codebaseaddr |
| 778 | directory = self.OPTIONAL_HEADER.DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_BASERELOC] |
| 779 | if directory.Size <= 0: return |
| 780 | relocaddr=codeBaseAddr + directory.VirtualAddress |
| 781 | relocation = IMAGE_BASE_RELOCATION.from_address(relocaddr) |
| 782 | |
| 783 | maxreloc = lambda r: (relocation.SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2 |
| 784 | while relocation.VirtualAddress > 0: |
| 785 | i = 0 |
| 786 | dest = codeBaseAddr + relocation.VirtualAddress |
| 787 | relinfoaddr = relocaddr + IMAGE_SIZEOF_BASE_RELOCATION |
| 788 | while i < maxreloc(relocaddr): |
| 789 | relinfo = c_ushort.from_address(relinfoaddr) |
| 790 | type = relinfo.value >> 12 |
| 791 | offset = relinfo.value & 0xfff |
| 792 | if type == IMAGE_REL_BASED_ABSOLUTE: |
| 793 | self.dbg("Skipping relocation") |
| 794 | elif type == IMAGE_REL_BASED_HIGHLOW or (type == IMAGE_REL_BASED_DIR64 and isx64): |
| 795 | self.dbg("Relocating offset: 0x%x", offset) |
| 796 | patchAddrHL = cast(dest + offset, LP_POINTER_TYPE) |
| 797 | patchAddrHL.contents.value += delta |
| 798 | else: |
| 799 | self.dbg("Unknown relocation at address: 0x%x", relocation) |
| 800 | break |
| 801 | # advancing two bytes at a time in the relocation table |
| 802 | relinfoaddr += 2 |
| 803 | i += 1 |
| 804 | relocaddr += relocation.SizeOfBlock |
| 805 | relocation = IMAGE_BASE_RELOCATION.from_address(relocaddr) |
| 806 | |
| 807 | |
| 808 | def build_import_table(self, dlopen = LoadLibraryW): |