summaryrefslogtreecommitdiff
path: root/python/binaryview.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/binaryview.py')
-rw-r--r--python/binaryview.py113
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)"""