Skip to content

Commit 210b0d5

Browse files
feat[python]: Support for custom RelocationHandler and
BinaryView.define_relocation
1 parent d92b368 commit 210b0d5

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]
@@ -2125,101 +2126,6 @@ def data(self, value: str) -> None:
21252126
core.BNTagSetData(self.handle, value)
21262127

21272128

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

@@ -4021,7 +3927,19 @@ def max_function_size_for_analysis(self) -> int:
40213927
def max_function_size_for_analysis(self, size: int) -> None:
40223928
core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
40233929

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

0 commit comments

Comments
 (0)