Skip to content

Commit c91df9b

Browse files
committed
wip
1 parent 6167e21 commit c91df9b

31 files changed

+3115
-6630
lines changed

view/sharedcache/api/python/sharedcache.py

Lines changed: 26 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ def __str__(self):
5959
return repr(self)
6060

6161
def __repr__(self):
62-
cache_type_str = 'Unknown'
63-
if self.cacheType == BackingCacheType.BackingCacheTypePrimary:
64-
cache_type_str = 'Primary'
65-
elif self.cacheType == BackingCacheType.BackingCacheTypeSecondary:
66-
cache_type_str = 'Secondary'
67-
elif self.cacheType == BackingCacheType.BackingCacheTypeSymbols:
68-
cache_type_str = 'Symbols'
69-
return f"<DSCBackingCache {self.path} {cache_type_str} | {len(self.mappings)} mappings>"
62+
match self.cacheType:
63+
case BackingCacheType.BackingCacheTypePrimary:
64+
cacheTypeStr = 'Primary'
65+
case BackingCacheType.BackingCacheTypeSecondary:
66+
cacheTypeStr = 'Secondary'
67+
case BackingCacheType.BackingCacheTypeSymbols:
68+
cacheTypeStr = 'Symbols'
69+
return f"<DSCBackingCache {self.path} {cacheTypeStr} | {len(self.mappings)} mappings>"
7070

7171

7272
@dataclasses.dataclass
@@ -112,75 +112,26 @@ def __repr__(self):
112112

113113

114114
class SharedCache:
115-
"""
116-
SharedCache is the primary class for interacting with the shared cache processor and DSCView metadata.
117-
118-
You can create a SharedCache object from a BinaryView object by calling `SharedCache(bv)`, where `bv` is the BinaryView.
119-
120-
By default `bv` in the console will return the instance of the BinaryView that is currently open, \
121-
so in the UI, you can use `dsc = SharedCache(bv)` to create a SharedCache object in the scripting console.
122-
123-
Methods and attributes in this class have documentation which can be viewed by typing `SharedCache.method_or_attribute_name?` in the console.
124-
"""
125115
def __init__(self, view):
126116
self.handle = sccore.BNGetSharedCache(view.handle)
127117

128-
def load_image_with_install_name(self, install_name, skip_loading_objective_c = False) -> bool:
129-
"""
130-
Locate an image with the provided install name and load it into the shared cache view
131-
132-
:param install_name: Install name of the image
133-
:param skip_loading_objective_c: Whether to skip process Objective-C information for this image. Default false.
134-
:return:
135-
"""
136-
return sccore.BNDSCViewLoadImageWithInstallName(self.handle, install_name, skip_loading_objective_c)
137-
138-
def load_section_at_address(self, addr) -> bool:
139-
"""
140-
Load a singular section at the provided address into the shared cache view.
141-
142-
This will partial-load the image, only mapping the requested segment containing this section.
118+
def load_image_with_install_name(self, installName, skipObjC = False):
119+
return sccore.BNDSCViewLoadImageWithInstallName(self.handle, installName, skipObjC)
143120

144-
Image info will still be processed, but will only be applied to mapped regions.
145-
146-
:param addr: Address within the section
147-
:return:
148-
"""
121+
def load_section_at_address(self, addr):
149122
return sccore.BNDSCViewLoadSectionAtAddress(self.handle, addr)
150123

151-
def load_image_containing_address(self, addr, skip_loading_objective_c = False) -> bool:
152-
"""
153-
Load the image containing the provided address into the shared cache view.
154-
155-
:param addr: Address within the image to load
156-
:param skip_loading_objective_c: Whether to skip processing Objective-C information for this image. Default false.
157-
:return:
158-
"""
159-
return sccore.BNDSCViewLoadImageContainingAddress(self.handle, addr, skip_loading_objective_c)
160-
161-
def process_objc_sections_for_image_with_install_name(self, install_name) -> bool:
162-
"""
163-
Process Objective-C information for the image with the provided install name.
164-
165-
:param install_name: Install name of the image
166-
:return:
167-
"""
168-
return sccore.BNDSCViewProcessObjCSectionsForImageWithInstallName(self.handle, install_name, False)
124+
def load_image_containing_address(self, addr, skipObjC = False):
125+
return sccore.BNDSCViewLoadImageContainingAddress(self.handle, addr, skipObjC)
169126

170-
def process_all_objc_sections(self) -> bool:
171-
"""
172-
Process Objective-C information for all images in the shared cache view.
127+
def process_objc_sections_for_image_with_install_name(self, installName):
128+
return sccore.BNDSCViewProcessObjCSectionsForImageWithInstallName(self.handle, installName)
173129

174-
:return:
175-
"""
130+
def process_all_objc_sections(self):
176131
return sccore.BNDSCViewProcessAllObjCSections(self.handle)
177132

178133
@property
179-
def caches(self) -> list[DSCBackingCache]:
180-
"""
181-
Get all backing caches in the shared cache.
182-
:return:
183-
"""
134+
def caches(self):
184135
count = ctypes.c_ulonglong()
185136
value = sccore.BNDSCViewGetBackingCaches(self.handle, count)
186137
if value is None:
@@ -206,11 +157,7 @@ def caches(self) -> list[DSCBackingCache]:
206157
return result
207158

208159
@property
209-
def images(self) -> list[DSCImage]:
210-
"""
211-
Get all images in the shared cache
212-
:return:
213-
"""
160+
def images(self):
214161
count = ctypes.c_ulonglong()
215162
value = sccore.BNDSCViewGetAllImages(self.handle, count)
216163
if value is None:
@@ -239,7 +186,7 @@ def images(self) -> list[DSCImage]:
239186
return result
240187

241188
@property
242-
def loaded_regions(self) -> list[LoadedRegion]:
189+
def loaded_regions(self):
243190
"""
244191
Get all loaded regions in the shared cache
245192
@@ -267,23 +214,7 @@ def loaded_regions(self) -> list[LoadedRegion]:
267214
sccore.BNDSCViewFreeLoadedRegions(value, count)
268215
return result
269216

270-
def load_all_symbols_and_wait(self) -> list[DSCSymbol]:
271-
"""
272-
Load all symbols in the shared cache. This will block on the current thread waiting for processing to finish.
273-
274-
While all functions in this API are synchronous, this function can be particularly slow due to the large number
275-
of symbols in the shared cache. "and_wait" is appended to the function name to indicate that this function
276-
will block until processing is complete, and for performant applications, you should consider calling this
277-
function in a separate thread and waiting on its return. An example of this is provided in the shared cache
278-
triage view.
279-
280-
This may take several seconds if this is the first time this function is called. Subsequent calls will be faster.
281-
282-
In UI-based API usage, it is likely that the triage view will have already performed this operation, and calls
283-
to this function will be much faster.
284-
285-
:return: A list of all symbols in the shared cache
286-
"""
217+
def load_all_symbols_and_wait(self):
287218
count = ctypes.c_ulonglong()
288219
value = sccore.BNDSCViewLoadAllSymbolsAndWait(self.handle, count)
289220
if value is None:
@@ -301,11 +232,7 @@ def load_all_symbols_and_wait(self) -> list[DSCSymbol]:
301232
return result
302233

303234
@property
304-
def image_names(self) -> list[str]:
305-
"""
306-
Get all image names in the shared cache
307-
:return:
308-
"""
235+
def image_names(self):
309236
count = ctypes.c_ulonglong()
310237
value = sccore.BNDSCViewGetInstallNames(self.handle, count)
311238
if value is None:
@@ -319,71 +246,22 @@ def image_names(self) -> list[str]:
319246
return result
320247

321248
@property
322-
def state(self) -> DSCViewState:
323-
"""
324-
Get the current image state of the shared cache view. Useful for checking if images have been loaded yet or not.
325-
:return:
326-
"""
249+
def state(self):
327250
return DSCViewState(sccore.BNDSCViewGetState(self.handle))
328251

329-
def get_name_for_address(self, address) -> str:
330-
"""
331-
Get the "name" for the provided address. Specifically, the name of the memory region this address lies in.
332-
333-
If this lies within an image segment, this will be in the format image_name + "::" + segment_name.
334-
335-
It may also be the name of a branch pool or other non-image region.
336-
337-
This is the API call utilized on the first dynamic entry in the right-click context menu.
338-
339-
:param address: address to check
340-
:return:
341-
"""
252+
def get_name_for_address(self, address):
342253
name = sccore.BNDSCViewGetNameForAddress(self.handle, address)
343254
if name is None:
344255
return ""
345256
result = name
346257
return result
347258

348-
def get_image_name_for_address(self, address) -> str:
349-
"""
350-
Return the install name for the image containing the provided address.
351-
352-
If the address is not within an image, this will return an empty string.
353-
354-
This is the API call used in the second dynamic entry in the right-click context menu.
355-
356-
:param address: address to check
357-
:return:
358-
"""
259+
def get_image_name_for_address(self, address):
359260
name = sccore.BNDSCViewGetImageNameForAddress(self.handle, address)
360261
if name is None:
361262
return ""
362263
result = name
363264
return result
364265

365-
def find_symbol_at_addr_and_apply_to_addr(self, symbol_address, target_address, trigger_reanalysis) -> None:
366-
"""
367-
This is primarily a function utilized for automated backwards symbol propagation for stubs in the workflow, however
368-
it is passed through here as well in the event you need to use it to do something similar, or want to create
369-
your own version of the workflow.
370-
371-
This is currently a blocking function.
372-
373-
This will check the cache for a symbol located at symbol_address, and apply it to target_address, appending a
374-
`j_` to the front of the symbol name copy at `target_address`.
375-
376-
It will additionally backwards-propagate type information that was specifically applied via TypeLibrary to the stub.
377-
378-
This includes calling conventions and can be seen in stubs pointing to objc_release_x[register] functions.
379-
380-
This check will not run if:
381-
- The symbol address and target address are the same
382-
- The target address has already been given a name by this function
383-
384-
:param symbol_address: Symbol address to check
385-
:param target_address: Target address to apply symbol name and type to
386-
:param trigger_reanalysis: Whether to reanalyze the function at target_address if the function already existed.
387-
:return: None
388-
"""
389-
sccore.BNDSCFindSymbolAtAddressAndApplyToAddress(self.handle, symbol_address, target_address, trigger_reanalysis)
266+
def find_symbol_at_addr_and_apply_to_addr(self, symbolAddress, targetAddress, triggerReanalysis) -> None:
267+
sccore.BNDSCFindSymbolAtAddressAndApplyToAddress(self.handle, symbolAddress, targetAddress, triggerReanalysis)

view/sharedcache/api/sharedcache.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ std::vector<std::string> SharedCache::GetAvailableImages()
5555
return result;
5656
}
5757

58-
void SharedCache::ProcessObjCSectionsForImageWithInstallName(std::string installName)
58+
void SharedCache::ProcessObjCSectionsForImageWithInstallName(const std::string& installName)
5959
{
60-
char* str = BNAllocString(installName.c_str());
61-
BNDSCViewProcessObjCSectionsForImageWithInstallName(m_object, str, true);
60+
BNDSCViewProcessObjCSectionsForImageWithInstallName(m_object, installName.c_str());
6261
}
6362

6463
void SharedCache::ProcessAllObjCSections()

view/sharedcache/api/sharedcacheapi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ namespace SharedCacheAPI {
147147
bool LoadImageContainingAddress(uint64_t addr, bool skipObjC = false);
148148
std::vector<std::string> GetAvailableImages();
149149

150-
void ProcessObjCSectionsForImageWithInstallName(std::string installName);
150+
void ProcessObjCSectionsForImageWithInstallName(const std::string& installName);
151151
void ProcessAllObjCSections();
152152

153153
std::vector<DSCSymbol> LoadAllSymbolsAndWait();

view/sharedcache/api/sharedcachecore.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ extern "C"
127127

128128
SHAREDCACHE_FFI_API char** BNDSCViewGetInstallNames(BNSharedCache* cache, size_t* count);
129129

130-
SHAREDCACHE_FFI_API bool BNDSCViewLoadImageWithInstallName(BNSharedCache* cache, char* name, bool skipObjC);
130+
SHAREDCACHE_FFI_API bool BNDSCViewLoadImageWithInstallName(BNSharedCache* cache, const char* name, bool skipObjC);
131131
SHAREDCACHE_FFI_API bool BNDSCViewLoadSectionAtAddress(BNSharedCache* cache, uint64_t name);
132132
SHAREDCACHE_FFI_API bool BNDSCViewLoadImageContainingAddress(BNSharedCache* cache, uint64_t address, bool skipObjC);
133133

134-
SHAREDCACHE_FFI_API void BNDSCViewProcessObjCSectionsForImageWithInstallName(BNSharedCache* cache, char* name, bool deallocName);
134+
SHAREDCACHE_FFI_API void BNDSCViewProcessObjCSectionsForImageWithInstallName(BNSharedCache* cache, const char* name);
135135
SHAREDCACHE_FFI_API void BNDSCViewProcessAllObjCSections(BNSharedCache* cache);
136136

137137
SHAREDCACHE_FFI_API char* BNDSCViewGetNameForAddress(BNSharedCache* cache, uint64_t address);
@@ -156,7 +156,7 @@ extern "C"
156156
SHAREDCACHE_FFI_API void BNDSCFindSymbolAtAddressAndApplyToAddress(BNSharedCache* cache, uint64_t symbolLocation, uint64_t targetLocation, bool triggerReanalysis);
157157

158158
SHAREDCACHE_FFI_API char* BNDSCViewGetImageHeaderForAddress(BNSharedCache* cache, uint64_t address);
159-
SHAREDCACHE_FFI_API char* BNDSCViewGetImageHeaderForName(BNSharedCache* cache, char* name);
159+
SHAREDCACHE_FFI_API char* BNDSCViewGetImageHeaderForName(BNSharedCache* cache, const char* name);
160160

161161
SHAREDCACHE_FFI_API BNDSCMemoryUsageInfo BNDSCViewGetMemoryUsageInfo();
162162

view/sharedcache/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ if((NOT BN_API_PATH) AND (NOT BN_INTERNAL_BUILD))
99
endif()
1010
endif()
1111

12-
file(GLOB SOURCES *.cpp *.h ../../../objectivec/*)
12+
file(GLOB_RECURSE SOURCES *.cpp *.h ../../../objectivec/*)
1313

1414
add_library(sharedcachecore OBJECT ${SOURCES})
1515

view/sharedcache/core/DSCView.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
* */
1414

1515
#include "DSCView.h"
16+
17+
#include "FileAccessorCache.h"
18+
#include "MappedFileAccessor.h"
1619
#include "view/macho/machoview.h"
1720
#include "SharedCache.h"
1821

@@ -196,7 +199,7 @@ bool DSCView::Init()
196199
auto metadataVersion = SharedCacheCore::SharedCacheMetadata::ViewMetadataVersion(GetParentView());
197200
if (metadataVersion.has_value() && metadataVersion.value() != METADATA_VERSION)
198201
{
199-
// TODO: This is fucked up lmaooooo
202+
// TODO: dont worry this will go away with the refactor, eta this week idk.
200203
ShowMessageBox("Invalid Shared Cache Metadata!", "The BNDB shared cache metadata was created with a different version of the Shared Cache view, to continue the metadata has to be recreated. You will need to add your images back again.");
201204
}
202205

@@ -650,8 +653,11 @@ DSCViewType::DSCViewType() : BinaryViewType(VIEW_NAME, VIEW_NAME)
650653

651654
void DSCViewType::Register()
652655
{
653-
MMappedFileAccessor::InitialVMSetup();
654-
std::atexit(VMShutdown);
656+
auto fdLimit = AdjustFileDescriptorLimit();
657+
BinaryNinja::LogDebug("Shared Cache processing initialized with a max file descriptor limit of %lld", fdLimit);
658+
659+
// Adjust the global accessor cache to the fdlimit.
660+
FileAccessorCache::Global().SetCacheSize(fdLimit);
655661

656662
static DSCViewType type;
657663
BinaryViewType::Register(&type);

0 commit comments

Comments
 (0)