From 3006c68e108a18f9b8782bc937dc9ec7e2cb3b54 Mon Sep 17 00:00:00 2001 From: kat Date: Wed, 23 Oct 2024 21:56:29 -0400 Subject: Initial commit of the alpha dyld_shared_cache view API Plugin. This is an early release of our DSC processing plugin. We're still hard at work improving this feature. You should be able to just drop in a dyld_shared_cache and use the 'Shared Cache Triage' view to load and analyze images. --- view/sharedcache/api/python/sharedcache.py | 260 +++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 view/sharedcache/api/python/sharedcache.py (limited to 'view/sharedcache/api/python/sharedcache.py') diff --git a/view/sharedcache/api/python/sharedcache.py b/view/sharedcache/api/python/sharedcache.py new file mode 100644 index 00000000..ca031e03 --- /dev/null +++ b/view/sharedcache/api/python/sharedcache.py @@ -0,0 +1,260 @@ +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) -- cgit v1.3.1