diff --git a/.gitignore b/.gitignore index a5ff059e6..f9d2ef820 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ python/generator.log python/generator.tlog .cache/ target/ +view/sharedcache/api/python/_sharedcachecore.py # Unit Tests suite/unit.py diff --git a/view/sharedcache/CMakeLists.txt b/view/sharedcache/CMakeLists.txt index 407fb0d56..89cbd8203 100644 --- a/view/sharedcache/CMakeLists.txt +++ b/view/sharedcache/CMakeLists.txt @@ -33,7 +33,7 @@ endif() set(HARD_FAIL_MODE OFF CACHE BOOL "Enable hard fail mode") set(SLIDEINFO_DEBUG_TAGS OFF CACHE BOOL "Enable debug tags in slideinfo") set(VIEW_NAME "DSCView" CACHE STRING "Name of the view") -set(METADATA_VERSION 3 CACHE STRING "Version of the metadata") +set(METADATA_VERSION 4 CACHE STRING "Version of the metadata") add_subdirectory(core) add_subdirectory(api) diff --git a/view/sharedcache/api/python/_sharedcachecore.py b/view/sharedcache/api/python/_sharedcachecore.py deleted file mode 100644 index 5f31697ed..000000000 --- a/view/sharedcache/api/python/_sharedcachecore.py +++ /dev/null @@ -1,684 +0,0 @@ -import binaryninja -import ctypes, os - -from typing import Optional -from . import sharedcache_enums -# Load core module -import platform -core = None -core_platform = platform.system() - -# By the time the debugger is loaded, binaryninja has not fully initialized. -# So we cannot call binaryninja.bundled_plugin_path() -from binaryninja._binaryninjacore import BNGetBundledPluginDirectory, BNFreeString -if core_platform == "Darwin": - _base_path = BNGetBundledPluginDirectory() - core = ctypes.CDLL(os.path.join(_base_path, "libsharedcache.dylib")) - -elif core_platform == "Linux": - _base_path = BNGetBundledPluginDirectory() - core = ctypes.CDLL(os.path.join(_base_path, "libsharedcache.so")) - -elif (core_platform == "Windows") or (core_platform.find("CYGWIN_NT") == 0): - _base_path = BNGetBundledPluginDirectory() - core = ctypes.CDLL(os.path.join(_base_path, "sharedcache.dll")) -else: - raise Exception("OS not supported") - -def cstr(var) -> Optional[ctypes.c_char_p]: - if var is None: - return None - if isinstance(var, bytes): - return var - return var.encode("utf-8") - -def pyNativeStr(arg): - if isinstance(arg, str): - return arg - else: - return arg.decode('utf8') - -def free_string(value:ctypes.c_char_p) -> None: - BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte))) - -# Type definitions -from binaryninja._binaryninjacore import BNBinaryView, BNBinaryViewHandle -class BNDSCBackingCache(ctypes.Structure): - @property - def path(self): - return pyNativeStr(self._path) - @path.setter - def path(self, value): - self._path = cstr(value) -BNDSCBackingCacheHandle = ctypes.POINTER(BNDSCBackingCache) -class BNDSCBackingCacheMapping(ctypes.Structure): - pass -BNDSCBackingCacheMappingHandle = ctypes.POINTER(BNDSCBackingCacheMapping) -class BNDSCImage(ctypes.Structure): - @property - def name(self): - return pyNativeStr(self._name) - @name.setter - def name(self, value): - self._name = cstr(value) -BNDSCImageHandle = ctypes.POINTER(BNDSCImage) -class BNDSCImageMemoryMapping(ctypes.Structure): - @property - def filePath(self): - return pyNativeStr(self._filePath) - @filePath.setter - def filePath(self, value): - self._filePath = cstr(value) - @property - def name(self): - return pyNativeStr(self._name) - @name.setter - def name(self, value): - self._name = cstr(value) -BNDSCImageMemoryMappingHandle = ctypes.POINTER(BNDSCImageMemoryMapping) -class BNDSCMappedMemoryRegion(ctypes.Structure): - @property - def name(self): - return pyNativeStr(self._name) - @name.setter - def name(self, value): - self._name = cstr(value) -BNDSCMappedMemoryRegionHandle = ctypes.POINTER(BNDSCMappedMemoryRegion) -class BNDSCMemoryUsageInfo(ctypes.Structure): - pass -BNDSCMemoryUsageInfoHandle = ctypes.POINTER(BNDSCMemoryUsageInfo) -class BNDSCSymbolRep(ctypes.Structure): - @property - def name(self): - return pyNativeStr(self._name) - @name.setter - def name(self, value): - self._name = cstr(value) - @property - def image(self): - return pyNativeStr(self._image) - @image.setter - def image(self, value): - self._image = cstr(value) -BNDSCSymbolRepHandle = ctypes.POINTER(BNDSCSymbolRep) -DSCViewLoadProgressEnum = ctypes.c_int -DSCViewStateEnum = ctypes.c_int -class BNSharedCache(ctypes.Structure): - pass -BNSharedCacheHandle = ctypes.POINTER(BNSharedCache) - -# Structure definitions -BNDSCBackingCache._fields_ = [ - ("_path", ctypes.c_char_p), - ("isPrimary", ctypes.c_bool), - ("mappings", ctypes.POINTER(BNDSCBackingCacheMapping)), - ("mappingCount", ctypes.c_ulonglong), - ] -BNDSCBackingCacheMapping._fields_ = [ - ("vmAddress", ctypes.c_ulonglong), - ("size", ctypes.c_ulonglong), - ("fileOffset", ctypes.c_ulonglong), - ] -BNDSCImage._fields_ = [ - ("_name", ctypes.c_char_p), - ("headerAddress", ctypes.c_ulonglong), - ("mappings", ctypes.POINTER(BNDSCImageMemoryMapping)), - ("mappingCount", ctypes.c_ulonglong), - ] -BNDSCImageMemoryMapping._fields_ = [ - ("_filePath", ctypes.c_char_p), - ("_name", ctypes.c_char_p), - ("vmAddress", ctypes.c_ulonglong), - ("size", ctypes.c_ulonglong), - ("loaded", ctypes.c_bool), - ("rawViewOffset", ctypes.c_ulonglong), - ] -BNDSCMappedMemoryRegion._fields_ = [ - ("vmAddress", ctypes.c_ulonglong), - ("size", ctypes.c_ulonglong), - ("_name", ctypes.c_char_p), - ] -BNDSCMemoryUsageInfo._fields_ = [ - ("sharedCacheRefs", ctypes.c_ulonglong), - ("mmapRefs", ctypes.c_ulonglong), - ] -BNDSCSymbolRep._fields_ = [ - ("address", ctypes.c_ulonglong), - ("_name", ctypes.c_char_p), - ("_image", ctypes.c_char_p), - ] - -# Function definitions -# ------------------------------------------------------- -# _BNDSCFindSymbolAtAddressAndApplyToAddress - -_BNDSCFindSymbolAtAddressAndApplyToAddress = core.BNDSCFindSymbolAtAddressAndApplyToAddress -_BNDSCFindSymbolAtAddressAndApplyToAddress.restype = None -_BNDSCFindSymbolAtAddressAndApplyToAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ctypes.c_ulonglong, - ctypes.c_bool, - ] - - -# noinspection PyPep8Naming -def BNDSCFindSymbolAtAddressAndApplyToAddress( - cache: ctypes.POINTER(BNSharedCache), - symbolLocation: int, - targetLocation: int, - triggerReanalysis: bool - ) -> None: - return _BNDSCFindSymbolAtAddressAndApplyToAddress(cache, symbolLocation, targetLocation, triggerReanalysis) - - -# ------------------------------------------------------- -# _BNDSCViewFastGetBackingCacheCount - -_BNDSCViewFastGetBackingCacheCount = core.BNDSCViewFastGetBackingCacheCount -_BNDSCViewFastGetBackingCacheCount.restype = ctypes.c_ulonglong -_BNDSCViewFastGetBackingCacheCount.argtypes = [ - ctypes.POINTER(BNBinaryView), - ] - - -# noinspection PyPep8Naming -def BNDSCViewFastGetBackingCacheCount( - view: ctypes.POINTER(BNBinaryView) - ) -> int: - return _BNDSCViewFastGetBackingCacheCount(view) - - -# ------------------------------------------------------- -# _BNDSCViewFreeAllImages - -_BNDSCViewFreeAllImages = core.BNDSCViewFreeAllImages -_BNDSCViewFreeAllImages.restype = None -_BNDSCViewFreeAllImages.argtypes = [ - ctypes.POINTER(BNDSCImage), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewFreeAllImages( - images: ctypes.POINTER(BNDSCImage), - count: int - ) -> None: - return _BNDSCViewFreeAllImages(images, count) - - -# ------------------------------------------------------- -# _BNDSCViewFreeBackingCaches - -_BNDSCViewFreeBackingCaches = core.BNDSCViewFreeBackingCaches -_BNDSCViewFreeBackingCaches.restype = None -_BNDSCViewFreeBackingCaches.argtypes = [ - ctypes.POINTER(BNDSCBackingCache), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewFreeBackingCaches( - caches: ctypes.POINTER(BNDSCBackingCache), - count: int - ) -> None: - return _BNDSCViewFreeBackingCaches(caches, count) - - -# ------------------------------------------------------- -# _BNDSCViewFreeLoadedRegions - -_BNDSCViewFreeLoadedRegions = core.BNDSCViewFreeLoadedRegions -_BNDSCViewFreeLoadedRegions.restype = None -_BNDSCViewFreeLoadedRegions.argtypes = [ - ctypes.POINTER(BNDSCMappedMemoryRegion), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewFreeLoadedRegions( - images: ctypes.POINTER(BNDSCMappedMemoryRegion), - count: int - ) -> None: - return _BNDSCViewFreeLoadedRegions(images, count) - - -# ------------------------------------------------------- -# _BNDSCViewFreeSymbols - -_BNDSCViewFreeSymbols = core.BNDSCViewFreeSymbols -_BNDSCViewFreeSymbols.restype = None -_BNDSCViewFreeSymbols.argtypes = [ - ctypes.POINTER(BNDSCSymbolRep), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewFreeSymbols( - symbols: ctypes.POINTER(BNDSCSymbolRep), - count: int - ) -> None: - return _BNDSCViewFreeSymbols(symbols, count) - - -# ------------------------------------------------------- -# _BNDSCViewGetAllImages - -_BNDSCViewGetAllImages = core.BNDSCViewGetAllImages -_BNDSCViewGetAllImages.restype = ctypes.POINTER(BNDSCImage) -_BNDSCViewGetAllImages.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.POINTER(ctypes.c_ulonglong), - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetAllImages( - cache: ctypes.POINTER(BNSharedCache), - count: ctypes.POINTER(ctypes.c_ulonglong) - ) -> Optional[ctypes.POINTER(BNDSCImage)]: - result = _BNDSCViewGetAllImages(cache, count) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNDSCViewGetBackingCaches - -_BNDSCViewGetBackingCaches = core.BNDSCViewGetBackingCaches -_BNDSCViewGetBackingCaches.restype = ctypes.POINTER(BNDSCBackingCache) -_BNDSCViewGetBackingCaches.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.POINTER(ctypes.c_ulonglong), - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetBackingCaches( - cache: ctypes.POINTER(BNSharedCache), - count: ctypes.POINTER(ctypes.c_ulonglong) - ) -> Optional[ctypes.POINTER(BNDSCBackingCache)]: - result = _BNDSCViewGetBackingCaches(cache, count) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNDSCViewGetImageHeaderForAddress - -_BNDSCViewGetImageHeaderForAddress = core.BNDSCViewGetImageHeaderForAddress -_BNDSCViewGetImageHeaderForAddress.restype = ctypes.POINTER(ctypes.c_byte) -_BNDSCViewGetImageHeaderForAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetImageHeaderForAddress( - cache: ctypes.POINTER(BNSharedCache), - address: int - ) -> Optional[Optional[str]]: - result = _BNDSCViewGetImageHeaderForAddress(cache, address) - if not result: - return None - string = str(pyNativeStr(ctypes.cast(result, ctypes.c_char_p).value)) - BNFreeString(result) - return string - - -# ------------------------------------------------------- -# _BNDSCViewGetImageHeaderForName - -_BNDSCViewGetImageHeaderForName = core.BNDSCViewGetImageHeaderForName -_BNDSCViewGetImageHeaderForName.restype = ctypes.POINTER(ctypes.c_byte) -_BNDSCViewGetImageHeaderForName.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_char_p, - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetImageHeaderForName( - cache: ctypes.POINTER(BNSharedCache), - name: Optional[str] - ) -> Optional[Optional[str]]: - result = _BNDSCViewGetImageHeaderForName(cache, cstr(name)) - if not result: - return None - string = str(pyNativeStr(ctypes.cast(result, ctypes.c_char_p).value)) - BNFreeString(result) - return string - - -# ------------------------------------------------------- -# _BNDSCViewGetImageNameForAddress - -_BNDSCViewGetImageNameForAddress = core.BNDSCViewGetImageNameForAddress -_BNDSCViewGetImageNameForAddress.restype = ctypes.POINTER(ctypes.c_byte) -_BNDSCViewGetImageNameForAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetImageNameForAddress( - cache: ctypes.POINTER(BNSharedCache), - address: int - ) -> Optional[Optional[str]]: - result = _BNDSCViewGetImageNameForAddress(cache, address) - if not result: - return None - string = str(pyNativeStr(ctypes.cast(result, ctypes.c_char_p).value)) - BNFreeString(result) - return string - - -# ------------------------------------------------------- -# _BNDSCViewGetInstallNames - -_BNDSCViewGetInstallNames = core.BNDSCViewGetInstallNames -_BNDSCViewGetInstallNames.restype = ctypes.POINTER(ctypes.c_char_p) -_BNDSCViewGetInstallNames.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.POINTER(ctypes.c_ulonglong), - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetInstallNames( - cache: ctypes.POINTER(BNSharedCache), - count: ctypes.POINTER(ctypes.c_ulonglong) - ) -> Optional[ctypes.POINTER(ctypes.c_char_p)]: - result = _BNDSCViewGetInstallNames(cache, count) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNDSCViewGetLoadProgress - -_BNDSCViewGetLoadProgress = core.BNDSCViewGetLoadProgress -_BNDSCViewGetLoadProgress.restype = DSCViewLoadProgressEnum -_BNDSCViewGetLoadProgress.argtypes = [ - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetLoadProgress( - sessionID: int - ) -> DSCViewLoadProgressEnum: - return _BNDSCViewGetLoadProgress(sessionID) - - -# ------------------------------------------------------- -# _BNDSCViewGetLoadedRegions - -_BNDSCViewGetLoadedRegions = core.BNDSCViewGetLoadedRegions -_BNDSCViewGetLoadedRegions.restype = ctypes.POINTER(BNDSCMappedMemoryRegion) -_BNDSCViewGetLoadedRegions.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.POINTER(ctypes.c_ulonglong), - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetLoadedRegions( - cache: ctypes.POINTER(BNSharedCache), - count: ctypes.POINTER(ctypes.c_ulonglong) - ) -> Optional[ctypes.POINTER(BNDSCMappedMemoryRegion)]: - result = _BNDSCViewGetLoadedRegions(cache, count) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNDSCViewGetMemoryUsageInfo - -_BNDSCViewGetMemoryUsageInfo = core.BNDSCViewGetMemoryUsageInfo -_BNDSCViewGetMemoryUsageInfo.restype = BNDSCMemoryUsageInfo -_BNDSCViewGetMemoryUsageInfo.argtypes = [ - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetMemoryUsageInfo( - ) -> BNDSCMemoryUsageInfo: - return _BNDSCViewGetMemoryUsageInfo() - - -# ------------------------------------------------------- -# _BNDSCViewGetNameForAddress - -_BNDSCViewGetNameForAddress = core.BNDSCViewGetNameForAddress -_BNDSCViewGetNameForAddress.restype = ctypes.POINTER(ctypes.c_byte) -_BNDSCViewGetNameForAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetNameForAddress( - cache: ctypes.POINTER(BNSharedCache), - address: int - ) -> Optional[Optional[str]]: - result = _BNDSCViewGetNameForAddress(cache, address) - if not result: - return None - string = str(pyNativeStr(ctypes.cast(result, ctypes.c_char_p).value)) - BNFreeString(result) - return string - - -# ------------------------------------------------------- -# _BNDSCViewGetState - -_BNDSCViewGetState = core.BNDSCViewGetState -_BNDSCViewGetState.restype = DSCViewStateEnum -_BNDSCViewGetState.argtypes = [ - ctypes.POINTER(BNSharedCache), - ] - - -# noinspection PyPep8Naming -def BNDSCViewGetState( - cache: ctypes.POINTER(BNSharedCache) - ) -> DSCViewStateEnum: - return _BNDSCViewGetState(cache) - - -# ------------------------------------------------------- -# _BNDSCViewLoadAllSymbolsAndWait - -_BNDSCViewLoadAllSymbolsAndWait = core.BNDSCViewLoadAllSymbolsAndWait -_BNDSCViewLoadAllSymbolsAndWait.restype = ctypes.POINTER(BNDSCSymbolRep) -_BNDSCViewLoadAllSymbolsAndWait.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.POINTER(ctypes.c_ulonglong), - ] - - -# noinspection PyPep8Naming -def BNDSCViewLoadAllSymbolsAndWait( - cache: ctypes.POINTER(BNSharedCache), - count: ctypes.POINTER(ctypes.c_ulonglong) - ) -> Optional[ctypes.POINTER(BNDSCSymbolRep)]: - result = _BNDSCViewLoadAllSymbolsAndWait(cache, count) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNDSCViewLoadImageContainingAddress - -_BNDSCViewLoadImageContainingAddress = core.BNDSCViewLoadImageContainingAddress -_BNDSCViewLoadImageContainingAddress.restype = ctypes.c_bool -_BNDSCViewLoadImageContainingAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ctypes.c_bool, - ] - - -# noinspection PyPep8Naming -def BNDSCViewLoadImageContainingAddress( - cache: ctypes.POINTER(BNSharedCache), - address: int, - skipObjC: bool - ) -> bool: - return _BNDSCViewLoadImageContainingAddress(cache, address, skipObjC) - - -# ------------------------------------------------------- -# _BNDSCViewLoadImageWithInstallName - -_BNDSCViewLoadImageWithInstallName = core.BNDSCViewLoadImageWithInstallName -_BNDSCViewLoadImageWithInstallName.restype = ctypes.c_bool -_BNDSCViewLoadImageWithInstallName.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_char_p, - ctypes.c_bool, - ] - - -# noinspection PyPep8Naming -def BNDSCViewLoadImageWithInstallName( - cache: ctypes.POINTER(BNSharedCache), - name: Optional[str], - skipObjC: bool - ) -> bool: - return _BNDSCViewLoadImageWithInstallName(cache, cstr(name), skipObjC) - - -# ------------------------------------------------------- -# _BNDSCViewLoadSectionAtAddress - -_BNDSCViewLoadSectionAtAddress = core.BNDSCViewLoadSectionAtAddress -_BNDSCViewLoadSectionAtAddress.restype = ctypes.c_bool -_BNDSCViewLoadSectionAtAddress.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_ulonglong, - ] - - -# noinspection PyPep8Naming -def BNDSCViewLoadSectionAtAddress( - cache: ctypes.POINTER(BNSharedCache), - name: int - ) -> bool: - return _BNDSCViewLoadSectionAtAddress(cache, name) - - -# ------------------------------------------------------- -# _BNDSCViewProcessAllObjCSections - -_BNDSCViewProcessAllObjCSections = core.BNDSCViewProcessAllObjCSections -_BNDSCViewProcessAllObjCSections.restype = None -_BNDSCViewProcessAllObjCSections.argtypes = [ - ctypes.POINTER(BNSharedCache), - ] - - -# noinspection PyPep8Naming -def BNDSCViewProcessAllObjCSections( - cache: ctypes.POINTER(BNSharedCache) - ) -> None: - return _BNDSCViewProcessAllObjCSections(cache) - - -# ------------------------------------------------------- -# _BNDSCViewProcessObjCSectionsForImageWithInstallName - -_BNDSCViewProcessObjCSectionsForImageWithInstallName = core.BNDSCViewProcessObjCSectionsForImageWithInstallName -_BNDSCViewProcessObjCSectionsForImageWithInstallName.restype = None -_BNDSCViewProcessObjCSectionsForImageWithInstallName.argtypes = [ - ctypes.POINTER(BNSharedCache), - ctypes.c_char_p, - ctypes.c_bool, - ] - - -# noinspection PyPep8Naming -def BNDSCViewProcessObjCSectionsForImageWithInstallName( - cache: ctypes.POINTER(BNSharedCache), - name: Optional[str], - deallocName: bool - ) -> None: - return _BNDSCViewProcessObjCSectionsForImageWithInstallName(cache, cstr(name), deallocName) - - -# ------------------------------------------------------- -# _BNFreeSharedCacheReference - -_BNFreeSharedCacheReference = core.BNFreeSharedCacheReference -_BNFreeSharedCacheReference.restype = None -_BNFreeSharedCacheReference.argtypes = [ - ctypes.POINTER(BNSharedCache), - ] - - -# noinspection PyPep8Naming -def BNFreeSharedCacheReference( - cache: ctypes.POINTER(BNSharedCache) - ) -> None: - return _BNFreeSharedCacheReference(cache) - - -# ------------------------------------------------------- -# _BNGetSharedCache - -_BNGetSharedCache = core.BNGetSharedCache -_BNGetSharedCache.restype = ctypes.POINTER(BNSharedCache) -_BNGetSharedCache.argtypes = [ - ctypes.POINTER(BNBinaryView), - ] - - -# noinspection PyPep8Naming -def BNGetSharedCache( - data: ctypes.POINTER(BNBinaryView) - ) -> Optional[ctypes.POINTER(BNSharedCache)]: - result = _BNGetSharedCache(data) - if not result: - return None - return result - - -# ------------------------------------------------------- -# _BNNewSharedCacheReference - -_BNNewSharedCacheReference = core.BNNewSharedCacheReference -_BNNewSharedCacheReference.restype = ctypes.POINTER(BNSharedCache) -_BNNewSharedCacheReference.argtypes = [ - ctypes.POINTER(BNSharedCache), - ] - - -# noinspection PyPep8Naming -def BNNewSharedCacheReference( - cache: ctypes.POINTER(BNSharedCache) - ) -> Optional[ctypes.POINTER(BNSharedCache)]: - result = _BNNewSharedCacheReference(cache) - if not result: - return None - return result - - - -# Helper functions -def handle_of_type(value, handle_type): - if isinstance(value, ctypes.POINTER(handle_type)) or isinstance(value, ctypes.c_void_p): - return ctypes.cast(value, ctypes.POINTER(handle_type)) - raise ValueError('expected pointer to %s' % str(handle_type)) diff --git a/view/sharedcache/core/DSCView.cpp b/view/sharedcache/core/DSCView.cpp index 459a37bcb..f1528095e 100644 --- a/view/sharedcache/core/DSCView.cpp +++ b/view/sharedcache/core/DSCView.cpp @@ -18,59 +18,6 @@ using namespace BinaryNinja; -/* - * DSCRawView is a "fake" parent view that the child view actually fills with data on init. - * - * This is the 'magic' that makes this sort of horrible "serialize the file headers and then refill the parent view" - * work. - * - * This throws errors on deser due to undo actions, but it still works. - * */ -DSCRawView::DSCRawView(const std::string& typeName, BinaryView* data, bool parseOnly) : - BinaryView(typeName, data->GetFile(), data) -{ - // This is going to load _only_ the dyld header of the loaded file. - // This written region will be immediately overwritten on image loading by SharedCache.cpp - GetFile()->SetFilename(data->GetFile()->GetOriginalFilename()); - uint32_t size; - GetParentView()->Read(&size, 16, 4); - size += 8; - AddAutoSegment(0, size, 0, size, SegmentReadable); - GetParentView()->WriteBuffer(0, GetParentView()->ReadBuffer(0, size)); -} - -bool DSCRawView::Init() -{ - return true; -} - -DSCRawViewType::DSCRawViewType() : BinaryViewType("DSCRaw", "DSCRaw") {} - -BinaryNinja::Ref DSCRawViewType::Create(BinaryView* data) -{ - return new DSCRawView("DSCRaw", data, false); -} - -BinaryNinja::Ref DSCRawViewType::Parse(BinaryView* data) -{ - return new DSCRawView("DSCRaw", data, true); -} - -bool DSCRawViewType::IsTypeValidForData(BinaryNinja::BinaryView* data) -{ - // Always return false here. - // This view pretty much exists to keep a bunch of internal core logic happy as it expects certain things - // from our view's parent that we need to control, and cannot control on a standard raw view. - - // IIRC an example of this was the need to add more data past the end of the original file. - - // in ios16 caches, the primary file can be like 100kb while a standard image will easily break 1MB - - // I actually should check if the stuff related to non-file-backed-segments changes the need for this, - // but at the time it was created (2022) it was necessary. - return false; -} - DSCView::DSCView(const std::string& typeName, BinaryView* data, bool parseOnly) : BinaryView(typeName, data->GetFile(), data), m_parseOnly(parseOnly) @@ -92,12 +39,14 @@ enum DSCPlatform { bool DSCView::Init() { + std::string os; + std::string arch; + uint32_t platform; GetParentView()->Read(&platform, 0xd8, 4); char magic[17]; GetParentView()->Read(&magic, 0, 16); magic[16] = 0; - std::string os; if (platform == DSCPlatformMacOS) { os = "mac"; @@ -111,21 +60,24 @@ bool DSCView::Init() LogError("Unknown platform: %d", platform); return false; } + if (std::string(magic) == "dyld_v1 arm64" || std::string(magic) == "dyld_v1 arm64e") { - SetDefaultPlatform(Platform::GetByName(os + "-aarch64")); - SetDefaultArchitecture(Architecture::GetByName("aarch64")); + arch = "aarch64"; } else if (std::string(magic) == "dyld_v1 x86_64") { - SetDefaultPlatform(Platform::GetByName(os + "-x86_64")); - SetDefaultArchitecture(Architecture::GetByName("x86_64")); + arch = "x86_64"; } else { LogError("Unknown magic: %s", magic); return false; } + + SetDefaultPlatform(Platform::GetByName(os + "-" + arch)); + SetDefaultArchitecture(Architecture::GetByName(arch)); + QualifiedNameAndType headerType; std::string err; @@ -631,9 +583,9 @@ bool DSCView::Init() DefineType(filesetEntryCommandTypeId, filesetEntryCommandName, filesetEntryCommandType); std::vector regionsMappedIntoMemory; - if (auto meta = GetParentView()->GetParentView()->QueryMetadata(SharedCacheCore::SharedCacheMetadataTag)) + if (auto meta = GetParentView()->QueryMetadata(SharedCacheCore::SharedCacheMetadataTag)) { - std::string data = GetParentView()->GetParentView()->GetStringMetadata(SharedCacheCore::SharedCacheMetadataTag); + std::string data = GetParentView()->GetStringMetadata(SharedCacheCore::SharedCacheMetadataTag); std::stringstream ss; ss.str(data); rapidjson::Document result(rapidjson::kObjectType); @@ -683,14 +635,6 @@ bool DSCView::Init() exportInfos.push_back({obj1["key"].GetUint64(), innerVec}); } - // We need to re-map data located in the Raw (parent parent) viewtype to the DSCRaw (parent) viewtype. - for (auto region : regionsMappedIntoMemory) - { - GetParentView()->AddUserSegment( - region.rawViewOffsetIfLoaded, region.size, region.rawViewOffsetIfLoaded, region.size, region.flags); - GetParentView()->WriteBuffer( - region.rawViewOffsetIfLoaded, GetParentView()->GetParentView()->ReadBuffer(region.rawViewOffsetIfLoaded, region.size)); - } BeginBulkModifySymbols(); for (const auto & [imageBaseAddr, exportList] : exportInfos) @@ -727,14 +671,14 @@ bool DSCView::Init() // first uint64_t in that struct is the base address of the primary // double gpv here because DSCRaw explicitly stops at the start of this mapping table uint64_t basePointer = 0; - GetParentView()->GetParentView()->Read(&basePointer, 16, 4); + GetParentView()->Read(&basePointer, 16, 4); if (basePointer == 0) { LogError("Failed to read base pointer"); return false; } uint64_t primaryBase = 0; - GetParentView()->GetParentView()->Read(&primaryBase, basePointer, 8); + GetParentView()->Read(&primaryBase, basePointer, 8); if (primaryBase == 0) { LogError("Failed to read primary base at 0x%llx", basePointer); @@ -755,12 +699,13 @@ bool DSCView::Init() } -DSCViewType::DSCViewType() : BinaryViewType(VIEW_NAME, VIEW_NAME) {} +DSCViewType::DSCViewType() : BinaryViewType(VIEW_NAME, VIEW_NAME) +{ +} BinaryNinja::Ref DSCViewType::Create(BinaryNinja::BinaryView* data) { - Ref rawViewRef = new DSCRawView("DSCRawView", data, false); - return new DSCView(VIEW_NAME, rawViewRef, false); + return new DSCView(VIEW_NAME, data, false); } @@ -858,7 +803,7 @@ Ref DSCViewType::GetLoadSettingsForData(BinaryView* data) BinaryNinja::Ref DSCViewType::Parse(BinaryNinja::BinaryView* data) { - return new DSCView(VIEW_NAME, new DSCRawView("DSCRawView", data, true), true); + return new DSCView(VIEW_NAME, data, true); } bool DSCViewType::IsTypeValidForData(BinaryNinja::BinaryView* data) diff --git a/view/sharedcache/core/DSCView.h b/view/sharedcache/core/DSCView.h index 1b891e369..bde2f7c2e 100644 --- a/view/sharedcache/core/DSCView.h +++ b/view/sharedcache/core/DSCView.h @@ -7,31 +7,6 @@ #include -class DSCRawView : public BinaryNinja::BinaryView { - std::string m_filename; -public: - - DSCRawView(const std::string &typeName, BinaryView *data, bool parseOnly = false); - - bool Init() override; -}; - - -class DSCRawViewType : public BinaryNinja::BinaryViewType { - -public: - BinaryNinja::Ref Create(BinaryNinja::BinaryView* data) override; - BinaryNinja::Ref Parse(BinaryNinja::BinaryView* data) override; - bool IsTypeValidForData(BinaryNinja::BinaryView *data) override; - - bool IsDeprecated() override { return false; } - - BinaryNinja::Ref GetLoadSettingsForData(BinaryNinja::BinaryView *data) override { return nullptr; } - -public: - DSCRawViewType(); -}; - class DSCView : public BinaryNinja::BinaryView { bool m_parseOnly; diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 0eb52c6a2..9e43ce0b4 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -1252,7 +1252,7 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptrGetParentView()->GetEnd(); - - auto name = stubIsland.prettyName; - m_dscView->GetParentView()->GetParentView()->WriteBuffer( - m_dscView->GetParentView()->GetParentView()->GetEnd(), buff); - m_dscView->GetParentView()->AddAutoSegment(rawViewEnd, stubIsland.size, rawViewEnd, stubIsland.size, - SegmentReadable | SegmentExecutable); - m_dscView->AddUserSegment(stubIsland.start, stubIsland.size, rawViewEnd, stubIsland.size, - SegmentReadable | SegmentExecutable); - m_dscView->AddUserSection(name, stubIsland.start, stubIsland.size, ReadOnlyCodeSectionSemantics); - m_dscView->WriteBuffer(stubIsland.start, buff); + m_dscView->GetMemoryMap()->AddDataMemoryRegion(stubIsland.prettyName, stubIsland.start, buff, SegmentReadable | SegmentExecutable); + m_dscView->AddUserSection(stubIsland.prettyName, stubIsland.start, stubIsland.size, ReadOnlyCodeSectionSemantics); stubIsland.loaded = true; - stubIsland.rawViewOffsetIfLoaded = rawViewEnd; - MutableState().regionsMappedIntoMemory.push_back(stubIsland); SaveToDSCView(); @@ -1625,20 +1614,10 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address) ParseAndApplySlideInfoForFile(targetFile); auto reader = VMReader(vm); auto buff = reader.ReadBuffer(dyldData.start, dyldData.size); - auto rawViewEnd = m_dscView->GetParentView()->GetEnd(); - - auto name = dyldData.prettyName; - m_dscView->GetParentView()->GetParentView()->WriteBuffer( - m_dscView->GetParentView()->GetParentView()->GetEnd(), buff); - m_dscView->GetParentView()->WriteBuffer(rawViewEnd, buff); - m_dscView->GetParentView()->AddAutoSegment(rawViewEnd, dyldData.size, rawViewEnd, dyldData.size, - SegmentReadable); - m_dscView->AddUserSegment(dyldData.start, dyldData.size, rawViewEnd, dyldData.size, SegmentReadable); - m_dscView->AddUserSection(name, dyldData.start, dyldData.size, ReadOnlyDataSectionSemantics); - m_dscView->WriteBuffer(dyldData.start, buff); + m_dscView->GetMemoryMap()->AddDataMemoryRegion(dyldData.prettyName, dyldData.start, buff, SegmentReadable); + m_dscView->AddUserSection(dyldData.prettyName, dyldData.start, dyldData.size, ReadOnlyDataSectionSemantics); dyldData.loaded = true; - dyldData.rawViewOffsetIfLoaded = rawViewEnd; MutableState().regionsMappedIntoMemory.push_back(dyldData); @@ -1664,19 +1643,10 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address) ParseAndApplySlideInfoForFile(targetFile); auto reader = VMReader(vm); auto buff = reader.ReadBuffer(region.start, region.size); - auto rawViewEnd = m_dscView->GetParentView()->GetEnd(); - - auto name = region.prettyName; - m_dscView->GetParentView()->GetParentView()->WriteBuffer( - m_dscView->GetParentView()->GetParentView()->GetEnd(), buff); - m_dscView->GetParentView()->WriteBuffer(rawViewEnd, buff); - m_dscView->GetParentView()->AddAutoSegment(rawViewEnd, region.size, rawViewEnd, region.size, region.flags); - m_dscView->AddUserSegment(region.start, region.size, rawViewEnd, region.size, region.flags); - m_dscView->AddUserSection(name, region.start, region.size, region.flags & SegmentDenyExecute ? ReadOnlyDataSectionSemantics : ReadOnlyCodeSectionSemantics); - m_dscView->WriteBuffer(region.start, buff); + m_dscView->GetMemoryMap()->AddDataMemoryRegion(region.prettyName, region.start, buff, region.flags); + m_dscView->AddUserSection(region.prettyName, region.start, region.size, region.flags & SegmentDenyExecute ? ReadOnlyDataSectionSemantics : ReadOnlyCodeSectionSemantics); region.loaded = true; - region.rawViewOffsetIfLoaded = rawViewEnd; MutableState().regionsMappedIntoMemory.push_back(region); @@ -1694,7 +1664,6 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address) } auto id = m_dscView->BeginUndoActions(); - auto rawViewEnd = m_dscView->GetParentView()->GetEnd(); auto reader = VMReader(vm); m_logger->LogDebug("Partial loading image %s", targetHeader.installName.c_str()); @@ -1702,17 +1671,9 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address) auto targetFile = vm->MappingAtAddress(targetSegment->start).first.fileAccessor->lock(); ParseAndApplySlideInfoForFile(targetFile); auto buff = reader.ReadBuffer(targetSegment->start, targetSegment->size); - m_dscView->GetParentView()->GetParentView()->WriteBuffer( - m_dscView->GetParentView()->GetParentView()->GetEnd(), buff); - m_dscView->GetParentView()->WriteBuffer(rawViewEnd, buff); - m_dscView->GetParentView()->AddAutoSegment( - rawViewEnd, targetSegment->size, rawViewEnd, targetSegment->size, SegmentReadable); - m_dscView->AddUserSegment( - targetSegment->start, targetSegment->size, rawViewEnd, targetSegment->size, targetSegment->flags); - m_dscView->WriteBuffer(targetSegment->start, buff); + m_dscView->GetMemoryMap()->AddDataMemoryRegion(targetSegment->prettyName, targetSegment->start, buff, targetSegment->flags); targetSegment->loaded = true; - targetSegment->rawViewOffsetIfLoaded = rawViewEnd; MutableState().regionsMappedIntoMemory.push_back(*targetSegment); @@ -1793,7 +1754,7 @@ void SharedCache::ProcessAllObjCSections() { if (!region.loaded) continue; - + // Don't repeat the same images multiple times auto header = HeaderForAddress(region.start); if (!header) @@ -1860,20 +1821,12 @@ bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObj auto targetFile = vm->MappingAtAddress(region.start).first.fileAccessor->lock(); ParseAndApplySlideInfoForFile(targetFile); - auto rawViewEnd = m_dscView->GetParentView()->GetEnd(); - auto buff = reader.ReadBuffer(region.start, region.size); - m_dscView->GetParentView()->GetParentView()->WriteBuffer(rawViewEnd, buff); - m_dscView->GetParentView()->WriteBuffer(rawViewEnd, buff); region.loaded = true; - region.rawViewOffsetIfLoaded = rawViewEnd; MutableState().regionsMappedIntoMemory.push_back(region); - - m_dscView->GetParentView()->AddAutoSegment(rawViewEnd, region.size, rawViewEnd, region.size, region.flags); - m_dscView->AddUserSegment(region.start, region.size, rawViewEnd, region.size, region.flags); - m_dscView->WriteBuffer(region.start, buff); + m_dscView->GetMemoryMap()->AddDataMemoryRegion(region.prettyName, region.start, buff, region.flags); regionsToLoad.push_back(®ion); } @@ -3032,7 +2985,7 @@ bool SharedCache::SaveToDSCView() { auto data = AsMetadata(); m_dscView->StoreMetadata(SharedCacheMetadataTag, data); - m_dscView->GetParentView()->GetParentView()->StoreMetadata(SharedCacheMetadataTag, data); + m_dscView->GetParentView()->StoreMetadata(SharedCacheMetadataTag, data); // By moving our state the to cache we can avoid creating a copy in the case // that no further mutations are made to `this`. If we're not done being mutated, @@ -3413,19 +3366,15 @@ extern "C" } [[maybe_unused]] DSCViewType* g_dscViewType; -[[maybe_unused]] DSCRawViewType* g_dscRawViewType; void InitDSCViewType() { MMappedFileAccessor::InitialVMSetup(); std::atexit(VMShutdown); - static DSCRawViewType rawType; - BinaryViewType::Register(&rawType); static DSCViewType type; BinaryViewType::Register(&type); g_dscViewType = &type; - g_dscRawViewType = &rawType; } namespace SharedCacheCore {