Skip to content

Commit 189a44b

Browse files
feat[python]: Support for custom RelocationHandler and
BinaryView.define_relocation
1 parent 63ed3b6 commit 189a44b

File tree

3 files changed

+341
-97
lines changed

3 files changed

+341
-97
lines changed

python/architecture.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from . import binaryview
4242
from . import variable
4343
from . import basicblock
44+
from . import relocation
4445

4546
RegisterIndex = NewType('RegisterIndex', int)
4647
RegisterStackIndex = NewType('RegisterStackIndex', int)
@@ -2374,6 +2375,28 @@ def skip_and_return_value(self, data: bytes, addr: int, value: int) -> Optional[
23742375
"""
23752376
return NotImplemented
23762377

2378+
def register_relocation_handler(self, view_name: str, handler: 'relocation.RelocationHandler') -> None:
2379+
"""
2380+
``register_relocation_handler`` registers a new relocation handler for the Architecture.
2381+
2382+
:param RelocationHandler handler: RelocationHandler object to be registered
2383+
:rtype: None
2384+
"""
2385+
core.BNArchitectureRegisterRelocationHandler(self.handle, core.cstr(view_name), handler.handle)
2386+
2387+
def get_relocation_handler(self, view_name: str) -> Optional['relocation.RelocationHandler']:
2388+
"""
2389+
``get_relocation_handler`` gets a relocation handler by its view name for the Architecture.
2390+
2391+
:param str view_name: the name of the corresponding view
2392+
:rtype: Optional['relocation.RelocationHandler']
2393+
"""
2394+
handler_handle = core.BNArchitectureGetRelocationHandler(self.handle, core.cstr(view_name))
2395+
if handler_handle is None:
2396+
return None
2397+
2398+
return relocation.RelocationHandler(handler_handle)
2399+
23772400
def register_calling_convention(self, cc: 'callingconvention.CallingConvention') -> None:
23782401
"""
23792402
``register_calling_convention`` registers a new calling convention for the Architecture.

python/binaryview.py

Lines changed: 15 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
from . import externallibrary
8383
from . import undo
8484
from . import stringrecognizer
85+
from . import relocation
8586

8687

8788
PathType = Union[str, os.PathLike]
@@ -2046,101 +2047,6 @@ def data(self, value: str) -> None:
20462047
core.BNTagSetData(self.handle, value)
20472048

20482049

2049-
@dataclass
2050-
class RelocationInfo:
2051-
type: RelocationType
2052-
pc_relative: bool
2053-
base_relative: bool
2054-
base: int
2055-
size: int
2056-
truncate_size: int
2057-
native_type: int
2058-
addend: int
2059-
has_sign: bool
2060-
implicit_addend: bool
2061-
external: bool
2062-
symbol_index: int
2063-
section_index: int
2064-
address: int
2065-
target: int
2066-
data_relocation: bool
2067-
2068-
def __init__(self, info: core.BNRelocationInfo):
2069-
self.type = RelocationType(info.type)
2070-
self.pc_relative = info.pcRelative
2071-
self.base_relative = info.baseRelative
2072-
self.base = info.base
2073-
self.size = info.size
2074-
self.truncate_size = info.truncateSize
2075-
self.native_type = info.nativeType
2076-
self.addend = info.addend
2077-
self.has_sign = info.hasSign
2078-
self.implicit_addend = info.implicitAddend
2079-
self.external = info.external
2080-
self.symbol_index = info.symbolIndex
2081-
self.section_index = info.sectionIndex
2082-
self.address = info.address
2083-
self.target = info.target
2084-
self.data_relocation = info.dataRelocation
2085-
2086-
2087-
class Relocation:
2088-
def __init__(self, handle: core.BNRelocationHandle):
2089-
self.handle = handle
2090-
2091-
def __del__(self):
2092-
if core is not None:
2093-
core.BNFreeRelocation(self.handle)
2094-
2095-
def __repr__(self):
2096-
if self.symbol is None:
2097-
return f"<Relocation: {self.target:#x}>"
2098-
try:
2099-
return f"<Relocation: \"{self.symbol.full_name}\" @ {self.target:#x}>"
2100-
except UnicodeDecodeError:
2101-
return f"<Relocation: \"{self.symbol.raw_bytes}\" @ {self.target:#x}>"
2102-
2103-
def __eq__(self, other):
2104-
if not isinstance(other, self.__class__):
2105-
return NotImplemented
2106-
return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
2107-
2108-
def __ne__(self, other):
2109-
if not isinstance(other, self.__class__):
2110-
return NotImplemented
2111-
return not (self == other)
2112-
2113-
def __hash__(self):
2114-
return hash(ctypes.addressof(self.handle.contents))
2115-
2116-
@property
2117-
def info(self) -> RelocationInfo:
2118-
return RelocationInfo(core.BNRelocationGetInfo(self.handle))
2119-
2120-
@property
2121-
def arch(self) -> Optional['architecture.Architecture']:
2122-
"""The architecture associated with the :py:class:`Relocation` (read/write)"""
2123-
core_arch = core.BNRelocationGetArchitecture(self.handle)
2124-
return architecture.CoreArchitecture._from_cache(handle=core_arch)
2125-
2126-
@property
2127-
def target(self) -> int:
2128-
"""Where the reloc needs to point to"""
2129-
return core.BNRelocationGetTarget(self.handle)
2130-
2131-
@property
2132-
def reloc(self) -> int:
2133-
"""The actual pointer that needs to be relocated"""
2134-
return core.BNRelocationGetReloc(self.handle)
2135-
2136-
@property
2137-
def symbol(self) -> Optional['_types.CoreSymbol']:
2138-
core_symbol = core.BNRelocationGetSymbol(self.handle)
2139-
if core_symbol is None:
2140-
return None
2141-
return _types.CoreSymbol(core_symbol)
2142-
2143-
21442050
class _BinaryViewAssociatedDataStore(associateddatastore._AssociatedDataStore):
21452051
_defaults = {}
21462052

@@ -3942,7 +3848,19 @@ def max_function_size_for_analysis(self) -> int:
39423848
def max_function_size_for_analysis(self, size: int) -> None:
39433849
core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
39443850

3945-
def relocations_at(self, addr: int) -> List[Relocation]:
3851+
def define_relocation(self, info: 'relocation.RelocationInfo', target: 'int | _types.Symbol', reloc: int, arch: Optional['architecture.Architecture'] = None):
3852+
if arch is None:
3853+
if self.arch is None:
3854+
raise Exception("Can not define relocation with no Architecture specified")
3855+
arch = self.arch
3856+
3857+
_info = info._to_core_struct()
3858+
if isinstance(target, int):
3859+
core.BNDefineRelocation(self.handle, arch.handle, _info, target, reloc)
3860+
else:
3861+
core.BNDefineSymbolRelocation(self.handle, arch.handle, _info, target.handle, reloc)
3862+
3863+
def relocations_at(self, addr: int) -> List['relocation.Relocation']:
39463864
"""List of relocations for a given address"""
39473865
count = ctypes.c_ulonglong()
39483866
relocs = core.BNGetRelocationsAt(self.handle, addr, count)
@@ -3952,7 +3870,7 @@ def relocations_at(self, addr: int) -> List[Relocation]:
39523870
for i in range(0, count.value):
39533871
reloc_handle = core.BNNewRelocationReference(relocs[i])
39543872
assert reloc_handle is not None, "core.BNNewRelocationReference is not None"
3955-
result.append(Relocation(reloc_handle))
3873+
result.append(relocation.Relocation(reloc_handle))
39563874
return result
39573875
finally:
39583876
core.BNFreeRelocationList(relocs, count)

0 commit comments

Comments
 (0)