Skip to content

Commit 63ed41b

Browse files
feat[python]: Support for custom RelocationHandler and
BinaryView.define_relocation
1 parent e2e420c commit 63ed41b

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
@@ -42,6 +42,7 @@
4242
from . import variable
4343
from . import basicblock
4444
from . import log
45+
from . import relocation
4546

4647
RegisterIndex = NewType('RegisterIndex', int)
4748
RegisterStackIndex = NewType('RegisterStackIndex', int)
@@ -2590,6 +2591,28 @@ def skip_and_return_value(self, data: bytes, addr: int, value: int) -> Optional[
25902591
"""
25912592
return NotImplemented
25922593

2594+
def register_relocation_handler(self, view_name: str, handler: 'relocation.RelocationHandler') -> None:
2595+
"""
2596+
``register_relocation_handler`` registers a new relocation handler for the Architecture.
2597+
2598+
:param RelocationHandler handler: RelocationHandler object to be registered
2599+
:rtype: None
2600+
"""
2601+
core.BNArchitectureRegisterRelocationHandler(self.handle, core.cstr(view_name), handler.handle)
2602+
2603+
def get_relocation_handler(self, view_name: str) -> Optional['relocation.RelocationHandler']:
2604+
"""
2605+
``get_relocation_handler`` gets a relocation handler by its view name for the Architecture.
2606+
2607+
:param str view_name: the name of the corresponding view
2608+
:rtype: Optional['relocation.RelocationHandler']
2609+
"""
2610+
handler_handle = core.BNArchitectureGetRelocationHandler(self.handle, core.cstr(view_name))
2611+
if handler_handle is None:
2612+
return None
2613+
2614+
return relocation.RelocationHandler(handler_handle)
2615+
25932616
def register_calling_convention(self, cc: 'callingconvention.CallingConvention') -> None:
25942617
"""
25952618
``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]
@@ -2124,101 +2125,6 @@ def data(self, value: str) -> None:
21242125
core.BNTagSetData(self.handle, value)
21252126

21262127

2127-
@dataclass
2128-
class RelocationInfo:
2129-
type: RelocationType
2130-
pc_relative: bool
2131-
base_relative: bool
2132-
base: int
2133-
size: int
2134-
truncate_size: int
2135-
native_type: int
2136-
addend: int
2137-
has_sign: bool
2138-
implicit_addend: bool
2139-
external: bool
2140-
symbol_index: int
2141-
section_index: int
2142-
address: int
2143-
target: int
2144-
data_relocation: bool
2145-
2146-
def __init__(self, info: core.BNRelocationInfo):
2147-
self.type = RelocationType(info.type)
2148-
self.pc_relative = info.pcRelative
2149-
self.base_relative = info.baseRelative
2150-
self.base = info.base
2151-
self.size = info.size
2152-
self.truncate_size = info.truncateSize
2153-
self.native_type = info.nativeType
2154-
self.addend = info.addend
2155-
self.has_sign = info.hasSign
2156-
self.implicit_addend = info.implicitAddend
2157-
self.external = info.external
2158-
self.symbol_index = info.symbolIndex
2159-
self.section_index = info.sectionIndex
2160-
self.address = info.address
2161-
self.target = info.target
2162-
self.data_relocation = info.dataRelocation
2163-
2164-
2165-
class Relocation:
2166-
def __init__(self, handle: core.BNRelocationHandle):
2167-
self.handle = handle
2168-
2169-
def __del__(self):
2170-
if core is not None:
2171-
core.BNFreeRelocation(self.handle)
2172-
2173-
def __repr__(self):
2174-
if self.symbol is None:
2175-
return f"<Relocation: {self.target:#x}>"
2176-
try:
2177-
return f"<Relocation: \"{self.symbol.full_name}\" @ {self.target:#x}>"
2178-
except UnicodeDecodeError:
2179-
return f"<Relocation: \"{self.symbol.raw_bytes}\" @ {self.target:#x}>"
2180-
2181-
def __eq__(self, other):
2182-
if not isinstance(other, self.__class__):
2183-
return NotImplemented
2184-
return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
2185-
2186-
def __ne__(self, other):
2187-
if not isinstance(other, self.__class__):
2188-
return NotImplemented
2189-
return not (self == other)
2190-
2191-
def __hash__(self):
2192-
return hash(ctypes.addressof(self.handle.contents))
2193-
2194-
@property
2195-
def info(self) -> RelocationInfo:
2196-
return RelocationInfo(core.BNRelocationGetInfo(self.handle))
2197-
2198-
@property
2199-
def arch(self) -> Optional['architecture.Architecture']:
2200-
"""The architecture associated with the :py:class:`Relocation` (read/write)"""
2201-
core_arch = core.BNRelocationGetArchitecture(self.handle)
2202-
return architecture.CoreArchitecture._from_cache(handle=core_arch)
2203-
2204-
@property
2205-
def target(self) -> int:
2206-
"""Where the reloc needs to point to"""
2207-
return core.BNRelocationGetTarget(self.handle)
2208-
2209-
@property
2210-
def reloc(self) -> int:
2211-
"""The actual pointer that needs to be relocated"""
2212-
return core.BNRelocationGetReloc(self.handle)
2213-
2214-
@property
2215-
def symbol(self) -> Optional['_types.CoreSymbol']:
2216-
core_symbol = core.BNRelocationGetSymbol(self.handle)
2217-
if core_symbol is None:
2218-
return None
2219-
return _types.CoreSymbol(core_symbol)
2220-
2221-
22222128
class _BinaryViewAssociatedDataStore(associateddatastore._AssociatedDataStore):
22232129
_defaults = {}
22242130

@@ -4020,7 +3926,19 @@ def max_function_size_for_analysis(self) -> int:
40203926
def max_function_size_for_analysis(self, size: int) -> None:
40213927
core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
40223928

4023-
def relocations_at(self, addr: int) -> List[Relocation]:
3929+
def define_relocation(self, info: 'relocation.RelocationInfo', target: 'int | _types.Symbol', reloc: int, arch: Optional['architecture.Architecture'] = None):
3930+
if arch is None:
3931+
if self.arch is None:
3932+
raise Exception("Can not define relocation with no Architecture specified")
3933+
arch = self.arch
3934+
3935+
_info = info._to_core_struct()
3936+
if isinstance(target, int):
3937+
core.BNDefineRelocation(self.handle, arch.handle, _info, target, reloc)
3938+
else:
3939+
core.BNDefineSymbolRelocation(self.handle, arch.handle, _info, target.handle, reloc)
3940+
3941+
def relocations_at(self, addr: int) -> List['relocation.Relocation']:
40243942
"""List of relocations for a given address"""
40253943
count = ctypes.c_ulonglong()
40263944
relocs = core.BNGetRelocationsAt(self.handle, addr, count)
@@ -4030,7 +3948,7 @@ def relocations_at(self, addr: int) -> List[Relocation]:
40303948
for i in range(0, count.value):
40313949
reloc_handle = core.BNNewRelocationReference(relocs[i])
40323950
assert reloc_handle is not None, "core.BNNewRelocationReference is not None"
4033-
result.append(Relocation(reloc_handle))
3951+
result.append(relocation.Relocation(reloc_handle))
40343952
return result
40353953
finally:
40363954
core.BNFreeRelocationList(relocs, count)

0 commit comments

Comments
 (0)