import os import ctypes import dataclasses import traceback import binaryninja from binaryninja._binaryninjacore import BNFreeStringList, BNAllocString, BNFreeString from . import _sharedcachecore as sccore from .sharedcache_enums import * @dataclasses.dataclass class DSCMemoryMapping: filePath: str name: str vmAddress: int rawViewOffset: int size: int def __str__(self): return repr(self) def __repr__(self): return f": {self.vmAddress:x}+{self.size:x}>" @dataclasses.dataclass class LoadedRegion: name: str headerAddress: int mappings: list[DSCMemoryMapping] def __str__(self): return repr(self) def __repr__(self): return f"" @dataclasses.dataclass class DSCBackingCacheMapping: vmAddress: int size: int fileOffset: int def __str__(self): return repr(self) def __repr__(self): return f"" @dataclasses.dataclass class DSCImageMemoryMapping: filePath: str name: str vmAddress: int size: int loaded: bool rawViewOffset: int def __str__(self): return repr(self) def __repr__(self): return f": {self.vmAddress:x}+{self.size:x}>" @dataclasses.dataclass class DSCImage: name: str headerAddress: int mappings: list[DSCImageMemoryMapping] def __str__(self): return repr(self) def __repr__(self): return f"" @dataclasses.dataclass class DSCSymbol: name: str image: str address: int def __str__(self): return repr(self) def __repr__(self): return f"" class SharedCache: def __init__(self, view): self.handle = sccore.BNGetSharedCache(view.handle) def load_image_with_install_name(self, installName): str = BNAllocString(installName.encode('utf-8')) return sccore.BNDSCViewLoadImageWithInstallName(self.handle, str) def load_section_at_address(self, addr): return sccore.BNDSCViewLoadSectionAtAddress(self.handle, addr) def load_image_containing_address(self, addr): return sccore.BNDSCViewLoadImageContainingAddress(self.handle, addr) @property def caches(self): count = ctypes.c_ulonglong() value = sccore.BNDSCViewGetBackingCaches(self.handle, count) if value is None: return [] result = [] for i in range(count.value): mappings = [] for j in range(value[i].mappingCount): mapping = DSCBackingCacheMapping( value[i].mappings[j].vmAddress, value[i].mappings[j].size, value[i].mappings[j].fileOffset ) mappings.append(mapping) result.append(DSCBackingCache( value[i].path, value[i].isPrimary, mappings )) sccore.BNDSCViewFreeBackingCaches(value, count) return result @property def images(self): count = ctypes.c_ulonglong() value = sccore.BNDSCViewGetAllImages(self.handle, count) if value is None: return [] result = [] for i in range(count.value): mappings = [] for j in range(value[i].mappingCount): mapping = DSCImageMemoryMapping( value[i].mappings[j].filePath, value[i].mappings[j].name, value[i].mappings[j].vmAddress, value[i].mappings[j].size, value[i].mappings[j].loaded, value[i].mappings[j].rawViewOffset ) mappings.append(mapping) result.append(DSCImage( value[i].name, value[i].headerAddress, mappings )) sccore.BNDSCViewFreeAllImages(value, count) return result @property def loaded_images(self): count = ctypes.c_ulonglong() value = sccore.BNDSCViewGetLoadedImages(self.handle, count) if value is None: return [] result = [] for i in range(count.value): mappings = [] for j in range(value[i].mappingCount): mapping = DSCMemoryMapping( value[i].mappings[j].filePath, value[i].mappings[j].name, value[i].mappings[j].vmAddress, value[i].mappings[j].rawViewOffset, value[i].mappings[j].size ) mappings.append(mapping) result.append(LoadedRegion( value[i].name, value[i].headerAddress, mappings )) sccore.BNDSCViewFreeLoadedImages(value, count) return result def load_all_symbols_and_wait(self): count = ctypes.c_ulonglong() value = sccore.BNDSCViewLoadAllSymbolsAndWait(self.handle, count) if value is None: return [] result = [] for i in range(count.value): sym = DSCSymbol( value[i].name, value[i].image, value[i].address ) result.append(sym) sccore.BNDSCViewFreeSymbols(value, count) return result @property def image_names(self): count = ctypes.c_ulonglong() value = sccore.BNDSCViewGetInstallNames(self.handle, count) if value is None: return [] result = [] for i in range(count.value): result.append(value[i].decode('utf-8')) BNFreeStringList(value, count) return result @property def image_count(self): return sccore.BNDSCViewLoadedImageCount(self.handle) @property def state(self): return DSCViewState(sccore.BNDSCViewGetState(self.handle)) def get_name_for_address(self, address): name = sccore.BNDSCViewGetNameForAddress(self.handle, address) if name is None: return "" result = name return result def get_image_name_for_address(self, address): name = sccore.BNDSCViewGetImageNameForAddress(self.handle, address) if name is None: return "" result = name return result def find_symbol_at_addr_and_apply_to_addr(self, symbolAddress, targetAddress, triggerReanalysis) -> None: sccore.BNDSCFindSymbolAtAddressAndApplyToAddress(self.handle, symbolAddress, targetAddress, triggerReanalysis)