diff options
| author | Mason Reed <mason@vector35.com> | 2024-12-03 12:34:40 -0500 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2024-12-03 12:34:40 -0500 |
| commit | 815c3fa9cd3334bdc010a07db431735b49c71546 (patch) | |
| tree | e478b54a7ab059d6d3dd3b100219305eed21849a /python/binaryview.py | |
| parent | c7f728bf5cdef1d05c6443de800cbc5464c0bb4f (diff) | |
Add `Relocation` information to python api
Previously only the relocation ranges were available
Diffstat (limited to 'python/binaryview.py')
| -rw-r--r-- | python/binaryview.py | 113 |
1 files changed, 112 insertions, 1 deletions
diff --git a/python/binaryview.py b/python/binaryview.py index db1ce945..06783723 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -44,7 +44,8 @@ from . import _binaryninjacore as core from . import decorators from .enums import ( AnalysisState, SymbolType, Endianness, ModificationStatus, StringType, SegmentFlag, SectionSemantics, FindFlag, - TypeClass, BinaryViewEventType, FunctionGraphType, TagReferenceType, TagTypeType, RegisterValueType, DisassemblyOption + TypeClass, BinaryViewEventType, FunctionGraphType, TagReferenceType, TagTypeType, RegisterValueType, DisassemblyOption, + RelocationType ) from .exceptions import RelocationWriteException, ILException, ExternalLinkException @@ -1741,6 +1742,101 @@ class Tag: core.BNTagSetData(self.handle, value) +@dataclass +class RelocationInfo: + type: RelocationType + pc_relative: bool + base_relative: bool + base: int + size: int + truncate_size: int + native_type: int + addend: int + has_sign: bool + implicit_addend: bool + external: bool + symbol_index: int + section_index: int + address: int + target: int + data_relocation: bool + + def __init__(self, info: core.BNRelocationInfo): + self.type = RelocationType(info.type) + self.pc_relative = info.pcRelative + self.base_relative = info.baseRelative + self.base = info.base + self.size = info.size + self.truncate_size = info.truncateSize + self.native_type = info.nativeType + self.addend = info.addend + self.has_sign = info.hasSign + self.implicit_addend = info.implicitAddend + self.external = info.external + self.symbol_index = info.symbolIndex + self.section_index = info.sectionIndex + self.address = info.address + self.target = info.target + self.data_relocation = info.dataRelocation + + +class Relocation: + def __init__(self, handle: core.BNRelocationHandle): + self.handle = handle + + def __del__(self): + if core is not None: + core.BNFreeRelocation(self.handle) + + def __repr__(self): + if self.symbol is None: + return f"<Relocation: {self.target:#x}>" + try: + return f"<Relocation: \"{self.symbol.full_name}\" @ {self.target:#x}>" + except UnicodeDecodeError: + return f"<Relocation: \"{self.symbol.raw_bytes}\" @ {self.target:#x}>" + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) + + def __ne__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return not (self == other) + + def __hash__(self): + return hash(ctypes.addressof(self.handle.contents)) + + @property + def info(self) -> RelocationInfo: + return RelocationInfo(core.BNRelocationGetInfo(self.handle)) + + @property + def arch(self) -> Optional['architecture.Architecture']: + """The architecture associated with the :py:class:`Relocation` (read/write)""" + core_arch = core.BNRelocationGetArchitecture(self.handle) + return architecture.CoreArchitecture._from_cache(handle=core_arch) + + @property + def target(self) -> int: + """Where the reloc needs to point to""" + return core.BNRelocationGetTarget(self.handle) + + @property + def reloc(self) -> int: + """The actual pointer that needs to be relocated""" + return core.BNRelocationGetReloc(self.handle) + + @property + def symbol(self) -> Optional['_types.CoreSymbol']: + core_symbol = core.BNRelocationGetSymbol(self.handle) + if core_symbol is None: + return None + return _types.CoreSymbol(core_symbol) + + class _BinaryViewAssociatedDataStore(associateddatastore._AssociatedDataStore): _defaults = {} @@ -3453,6 +3549,21 @@ class BinaryView: def max_function_size_for_analysis(self, size: int) -> None: core.BNSetMaxFunctionSizeForAnalysis(self.handle, size) + def relocations_at(self, addr: int) -> List[Relocation]: + """List of relocations for a given address""" + count = ctypes.c_ulonglong() + relocs = core.BNGetRelocationsAt(self.handle, addr, count) + assert relocs is not None, "core.BNGetRelocationRanges returned None" + result = [] + try: + for i in range(0, count.value): + reloc_handle = core.BNNewRelocationReference(relocs[i]) + assert reloc_handle is not None, "core.BNNewRelocationReference is not None" + result.append(Relocation(reloc_handle)) + return result + finally: + core.BNFreeRelocationList(relocs, count) + @property def relocation_ranges(self) -> List[Tuple[int, int]]: """List of relocation range tuples (read-only)""" |
