Source code for cle.backends.pe.relocation.generic

import logging
import struct

from cle.address_translator import AT

from .pereloc import PEReloc

log = logging.getLogger(name=__name__)

__all__ = [
    "DllImport",
    "IMAGE_REL_BASED_ABSOLUTE",
    "IMAGE_REL_BASED_HIGHADJ",
    "IMAGE_REL_BASED_HIGHLOW",
    "IMAGE_REL_BASED_DIR64",
    "IMAGE_REL_BASED_HIGH",
    "IMAGE_REL_BASED_LOW",
]


[docs] class DllImport(PEReloc): """ There's nothing special to be done for DLL imports but this class provides a unique name to the relocation type. """ pass
[docs] class IMAGE_REL_BASED_ABSOLUTE(PEReloc):
[docs] def relocate(self): pass
[docs] class IMAGE_REL_BASED_HIGHADJ(PEReloc):
[docs] def __init__(self, owner, addr, next_rva): super().__init__(owner, None, addr) self.next_rva = next_rva
@property def value(self): """ In all the other cases, we can ignore the relocation difference part of the calculation because we simply use to_mva() to get our rebased address. In this case, however, we have to adjust the un-rebased address first. """ org_bytes = self.owner.memory.load(self.relative_addr, 2) org_value = struct.unpack("<I", org_bytes)[0] adjusted_value = (org_value << 16) + self.next_rva adjusted_value = (AT.from_lva(adjusted_value, self.owner) & 0xFFFF0000) >> 16 adjusted_bytes = struct.pack("<I", adjusted_value) return adjusted_bytes
[docs] class IMAGE_REL_BASED_HIGHLOW(PEReloc): @property def value(self): org_bytes = self.owner.memory.load(self.relative_addr, 4) org_value = struct.unpack("<I", org_bytes)[0] rebased_value = AT.from_lva(org_value, self.owner).to_mva() rebased_bytes = struct.pack("<I", rebased_value & 0xFFFFFFFF) return rebased_bytes
[docs] class IMAGE_REL_BASED_DIR64(PEReloc): @property def value(self): org_bytes = self.owner.memory.load(self.relative_addr, 8) org_value = struct.unpack("<Q", org_bytes)[0] rebased_value = AT.from_lva(org_value, self.owner).to_mva() if rebased_value < 0 or rebased_value >= 0x10000000000000000: log.error( "Incorrect rebased address %x found at %s. Maybe the relocation table is broken.", rebased_value, self.owner, ) return None rebased_bytes = struct.pack("<Q", rebased_value) return rebased_bytes
[docs] class IMAGE_REL_BASED_HIGH(PEReloc): @property def value(self): org_bytes = self.owner.memory.load(self.relative_addr, 2) org_value = struct.unpack("<H", org_bytes)[0] rebased_value = AT.from_lva(org_value, self.owner).to_mva() adjusted_value = (rebased_value >> 16) & 0xFFFF adjusted_bytes = struct.pack("<H", adjusted_value) return adjusted_bytes
[docs] class IMAGE_REL_BASED_LOW(PEReloc): @property def value(self): org_bytes = self.owner.memory.load(self.relative_addr, 2) org_value = struct.unpack("<H", org_bytes)[0] rebased_value = AT.from_lva(org_value, self.owner).to_mva() adjusted_value = rebased_value & 0x0000FFFF adjusted_bytes = struct.pack("<H", adjusted_value) return adjusted_bytes