mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-27 14:42:51 -04:00
Use relocation table with reccmp (#327)
This commit is contained in:
parent
403b3dddb4
commit
5f8e26fc5b
@ -372,7 +372,7 @@ BOOL MxDirectDraw::DDSetMode(int width, int height, int bpp)
|
|||||||
|
|
||||||
m_bIgnoreWMSIZE = TRUE;
|
m_bIgnoreWMSIZE = TRUE;
|
||||||
dwStyle = GetWindowLong(m_hWndMain, GWL_STYLE);
|
dwStyle = GetWindowLong(m_hWndMain, GWL_STYLE);
|
||||||
dwStyle &= ~(WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_OVERLAPPED);
|
dwStyle &= ~WS_POPUP;
|
||||||
dwStyle |= WS_CAPTION | WS_THICKFRAME | WS_OVERLAPPED;
|
dwStyle |= WS_CAPTION | WS_THICKFRAME | WS_OVERLAPPED;
|
||||||
SetWindowLong(m_hWndMain, GWL_STYLE, dwStyle);
|
SetWindowLong(m_hWndMain, GWL_STYLE, dwStyle);
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ class Bin:
|
|||||||
self.imagebase = None
|
self.imagebase = None
|
||||||
self.sections = []
|
self.sections = []
|
||||||
self.last_section = None
|
self.last_section = None
|
||||||
|
self._relocated_addrs = set()
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._debuglog(f"Bin {self.filename} Enter")
|
self._debuglog(f"Bin {self.filename} Enter")
|
||||||
@ -100,6 +101,8 @@ class Bin:
|
|||||||
for i in range(pe_hdr.NumberOfSections)
|
for i in range(pe_hdr.NumberOfSections)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self._populate_relocations()
|
||||||
|
|
||||||
text_section = self._get_section_by_name(".text")
|
text_section = self._get_section_by_name(".text")
|
||||||
self.last_section = text_section
|
self.last_section = text_section
|
||||||
|
|
||||||
@ -116,6 +119,52 @@ class Bin:
|
|||||||
if self.logger is not None:
|
if self.logger is not None:
|
||||||
self.logger.debug(msg)
|
self.logger.debug(msg)
|
||||||
|
|
||||||
|
def get_relocated_addresses(self):
|
||||||
|
return sorted(self._relocated_addrs)
|
||||||
|
|
||||||
|
def is_relocated_addr(self, vaddr) -> bool:
|
||||||
|
return vaddr in self._relocated_addrs
|
||||||
|
|
||||||
|
def _populate_relocations(self):
|
||||||
|
"""The relocation table in .reloc gives each virtual address where the next four
|
||||||
|
bytes are, itself, another virtual address. During loading, these values will be
|
||||||
|
patched according to the virtual address space for the image, as provided by Windows.
|
||||||
|
We can use this information to get a list of where each significant "thing"
|
||||||
|
in the file is located. Anything that is referenced absolutely (i.e. excluding
|
||||||
|
jump destinations given by local offset) will be here.
|
||||||
|
One use case is to tell whether an immediate value in an operand represents
|
||||||
|
a virtual address or just a big number."""
|
||||||
|
|
||||||
|
ofs = self.get_section_offset_by_name(".reloc")
|
||||||
|
reloc_addrs = []
|
||||||
|
|
||||||
|
# Parse the structure in .reloc to get the list locations to check.
|
||||||
|
# The first 8 bytes are 2 dwords that give the base page address
|
||||||
|
# and the total block size (including this header).
|
||||||
|
# The page address is used to compact the list; each entry is only
|
||||||
|
# 2 bytes, and these are added to the base to get the full location.
|
||||||
|
# If the entry read in is zero, we are at the end of this section and
|
||||||
|
# these are padding bytes.
|
||||||
|
while True:
|
||||||
|
(page_base, block_size) = struct.unpack("<2I", self.read(ofs, 8))
|
||||||
|
if block_size == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
# HACK: ignore the relocation type for now (the top 4 bits of the value).
|
||||||
|
values = list(struct.iter_unpack("<H", self.read(ofs + 8, block_size - 8)))
|
||||||
|
reloc_addrs += [
|
||||||
|
self.imagebase + page_base + (v[0] & 0xFFF) for v in values if v[0] != 0
|
||||||
|
]
|
||||||
|
|
||||||
|
ofs += block_size
|
||||||
|
|
||||||
|
# We are now interested in the relocated addresses themselves. Seek to the
|
||||||
|
# address where there is a relocation, then read the four bytes into our set.
|
||||||
|
reloc_addrs.sort()
|
||||||
|
for addr in reloc_addrs:
|
||||||
|
(relocated_addr,) = struct.unpack("<I", self.read(addr, 4))
|
||||||
|
self._relocated_addrs.add(relocated_addr)
|
||||||
|
|
||||||
def _set_section_for_vaddr(self, vaddr):
|
def _set_section_for_vaddr(self, vaddr):
|
||||||
if self.last_section is not None and section_contains_vaddr(
|
if self.last_section is not None and section_contains_vaddr(
|
||||||
self.last_section, self.imagebase, vaddr
|
self.last_section, self.imagebase, vaddr
|
||||||
|
@ -87,7 +87,7 @@ def sanitize(file, placeholder_generator, mnemonic, op_str):
|
|||||||
for i, word in enumerate(words):
|
for i, word in enumerate(words):
|
||||||
try:
|
try:
|
||||||
inttest = int(word, 16)
|
inttest = int(word, 16)
|
||||||
if inttest >= file.get_section_offset_by_index(1):
|
if file.is_relocated_addr(inttest):
|
||||||
words[i] = placeholder_generator.get(inttest)
|
words[i] = placeholder_generator.get(inttest)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user