diff options
| author | Brian Potchik <brian@vector35.com> | 2025-07-12 11:24:18 -0400 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2025-07-12 11:24:18 -0400 |
| commit | 7a6f1553a1a4c621ffac81edaa859fb36cce95b7 (patch) | |
| tree | a4cb59487e4f9ad2f5972949b7f742e56e38637f | |
| parent | 41507e5f49989fbf60f303270e0a051b546469f4 (diff) | |
Add support for unbacked memory regions directly in the memory map.
| -rw-r--r-- | binaryninjaapi.h | 10 | ||||
| -rw-r--r-- | binaryninjacore.h | 4 | ||||
| -rw-r--r-- | python/binaryview.py | 39 |
3 files changed, 39 insertions, 14 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 9710f919..27564dc1 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -7202,6 +7202,11 @@ namespace BinaryNinja { return BNAddRemoteMemoryRegion(m_object, name.c_str(), start, source->GetCallbacks(), flags); } + bool AddUnbackedMemoryRegion(const std::string& name, uint64_t start, uint64_t length, uint32_t flags = 0, uint8_t fill = 0) + { + return BNAddUnbackedMemoryRegion(m_object, name.c_str(), start, length, flags, fill); + } + bool RemoveMemoryRegion(const std::string& name) { return BNRemoveMemoryRegion(m_object, name.c_str()); @@ -7255,6 +7260,11 @@ namespace BinaryNinja { return BNSetMemoryRegionFill(m_object, name.c_str(), fill); } + bool IsMemoryRegionLocal(const std::string& name) + { + return BNIsMemoryRegionLocal(m_object, name.c_str()); + } + void Reset() { BNResetMemoryMap(m_object); diff --git a/binaryninjacore.h b/binaryninjacore.h index 82817ab8..3d32680c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,7 +37,7 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 122 +#define BN_CURRENT_CORE_ABI_VERSION 123 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and @@ -4222,6 +4222,7 @@ extern "C" BINARYNINJACOREAPI bool BNIsMemoryMapActivated(BNBinaryView* view); BINARYNINJACOREAPI bool BNAddBinaryMemoryRegion(BNBinaryView* view, const char* name, uint64_t start, BNBinaryView* data, uint32_t flags); BINARYNINJACOREAPI bool BNAddDataMemoryRegion(BNBinaryView* view, const char* name, uint64_t start, BNDataBuffer* data, uint32_t flags); + BINARYNINJACOREAPI bool BNAddUnbackedMemoryRegion(BNBinaryView* view, const char* name, uint64_t start, uint64_t length, uint32_t flags, uint8_t fill); BINARYNINJACOREAPI bool BNAddRemoteMemoryRegion(BNBinaryView* view, const char* name, uint64_t start, BNFileAccessor* accessor, uint32_t flags); BINARYNINJACOREAPI bool BNRemoveMemoryRegion(BNBinaryView* view, const char* name); BINARYNINJACOREAPI char* BNGetActiveMemoryRegionAt(BNBinaryView* view, uint64_t addr); @@ -4233,6 +4234,7 @@ extern "C" BINARYNINJACOREAPI bool BNSetMemoryRegionRebaseable(BNBinaryView* view, const char* name, bool rebaseable); BINARYNINJACOREAPI uint8_t BNGetMemoryRegionFill(BNBinaryView* view, const char* name); BINARYNINJACOREAPI bool BNSetMemoryRegionFill(BNBinaryView* view, const char* name, uint8_t fill); + BINARYNINJACOREAPI bool BNIsMemoryRegionLocal(BNBinaryView* view, const char* name); BINARYNINJACOREAPI void BNResetMemoryMap(BNBinaryView* view); // Binary view access diff --git a/python/binaryview.py b/python/binaryview.py index e2af96a1..55a2321f 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -2410,35 +2410,45 @@ class MemoryMap: """Whether the memory map is activated for the associated view.""" return core.BNIsMemoryMapActivated(self.handle) - def add_memory_region(self, name: str, start: int, source: Union['os.PathLike', str, bytes, bytearray, 'BinaryView', 'databuffer.DataBuffer', 'fileaccessor.FileAccessor'], flags: SegmentFlag = 0) -> bool: + def add_memory_region(self, name: str, start: int, source: Optional[Union['os.PathLike', str, bytes, bytearray, 'BinaryView', 'databuffer.DataBuffer', 'fileaccessor.FileAccessor']] = None, flags: SegmentFlag = 0, fill: int = 0, length: Optional[int] = None) -> bool: """ Adds a memory region to the memory map. Depending on the source parameter, the memory region is created as one of the following types: - - **BinaryMemoryRegion** (***Unimplemented***): Represents a memory region loaded from a binary format, providing persistence across sessions. - - **DataMemoryRegion**: Represents a memory region loaded from flat files or raw bytes, providing persistence across sessions. - - **RemoteMemoryRegion**: Represents a memory region managed via a proxy callback interface. This region is ephemeral and not persisted across sessions. + - **BinaryMemoryRegion** (***Unimplemented***): Represents a memory region loaded from a binary format. + - **DataMemoryRegion**: Region backed by flat file or raw data (str, bytes, DataBuffer). + - **RemoteMemoryRegion**: Ephemeral memory region via FileAccessor. + - **UnbackedMemoryRegion**: Region not backed by any data source (requires `length` to be set). - The type of memory region created is determined by the `source` parameter: - - `os.PathLike` or `str`: Treated as a file path to be loaded into memory as a `DataMemoryRegion`. + The `source` parameter determines the type: + - `os.PathLike` or `str`: File path to be loaded into memory as a `DataMemoryRegion`. - `bytes` or `bytearray`: Directly loaded into memory as a `DataMemoryRegion`. - `databuffer.DataBuffer`: Loaded as a `DataMemoryRegion`. - - `fileaccessor.FileAccessor`: Creates a `RemoteMemoryRegion` that fetches data via a remote source. - - `BinaryView`: (Not yet implemented) Intended for future exploration. + - `fileaccessor.FileAccessor`: Remote proxy source. + - `BinaryView`: (Reserved for future). + - `None`: Creates an unbacked memory region (must specify `length`). .. note:: If no flags are specified and the new memory region overlaps with one or more existing regions, the overlapping portions of the new region will inherit the flags of the respective underlying regions. Parameters: name (str): A unique name for the memory region. - start (int): The starting address in memory for the region. - source (Union[os.PathLike, str, bytes, bytearray, BinaryView, databuffer.DataBuffer, fileaccessor.FileAccessor]): The source from which the memory is loaded. - flags (SegmentFlag, optional): Flags to apply to the memory region. Defaults to 0 (no flags). + start (int): Starting address. + source (Optional[Union[os.PathLike, str, bytes, bytearray, BinaryView, databuffer.DataBuffer, fileaccessor.FileAccessor]]): Source of data or `None` for unbacked. + length (Optional[int]): Required if source is None (unbacked). + flags (SegmentFlag): Flags to apply to the memory region. Defaults to 0 (no flags). + fill (int): Fill byte for unbacked regions. Defaults to 0. Returns: bool: `True` if the memory region was successfully added, `False` otherwise. Raises: - NotImplementedError: If the specified `source` type is unsupported. + NotImplementedError: If source type is unsupported. + ValueError: If source is None and length is not specified. """ + if source is None: + if length is None: + raise ValueError("Must specify `length` when `source` is None for unbacked memory region") + return core.BNAddUnbackedMemoryRegion(self.handle, name, start, length, flags, fill) + if isinstance(source, os.PathLike): source = str(source) if isinstance(source, bytes) or isinstance(source, bytearray): @@ -2457,7 +2467,7 @@ class MemoryMap: elif isinstance(source, fileaccessor.FileAccessor): return core.BNAddRemoteMemoryRegion(self.handle, name, start, source._cb, flags) else: - raise NotImplementedError + raise NotImplementedError(f"Unsupported memory region source type: {type(source)}") def remove_memory_region(self, name: str) -> bool: return core.BNRemoveMemoryRegion(self.handle, name) @@ -2490,6 +2500,9 @@ class MemoryMap: def set_memory_region_fill(self, name: str, fill: int) -> bool: return core.BNSetMemoryRegionFill(self.handle, name, fill) + def is_memory_region_local(self, name: str) -> bool: + return core.BNIsMemoryRegionLocal(self.handle, name) + def reset(self): core.BNResetMemoryMap(self.handle) |
