MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / ApplyImage

Method ApplyImage

view/sharedcache/core/SharedCacheController.cpp:194–251  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

192}
193
194bool SharedCacheController::ApplyImage(BinaryView& view, const CacheImage& image)
195{
196 // Load all regions of an image and mark the image as loaded.
197 // NOTE: The regions lock m_loadMutex themselves, so we do not hold it up here.
198 bool loadedRegion = false;
199 for (const auto& regionStart : image.regionStarts)
200 if (ApplyRegionAtAddress(view, regionStart))
201 loadedRegion = true;
202
203 // The ApplyRegionAtAddress no longer holds the lock, we can take it now.
204 std::unique_lock<std::shared_mutex> lock(m_loadMutex);
205 // If there was no loaded regions than we just want to forgo loading the image.
206 // We also skip if we already loaded the image itself. We do this after loading regions
207 // as we regions have their own check.
208 if (!loadedRegion || m_loadedImages.find(image.headerAddress) != m_loadedImages.end())
209 return false;
210
211 if (image.header)
212 {
213 // Header information is applied to the view here, such as sections.
214 auto machoProcessor = SharedCacheMachOProcessor(&view, m_cache.GetVirtualMemory());
215
216 // Adding a user section will mark all functions for updates unless we disable this.
217 // Because images are known separate compilation units, we have a real reason to make sure we don't mark all previously
218 // analyzed functions as updated.
219 auto prevDisabledState = view.GetFunctionAnalysisUpdateDisabled();
220 view.SetFunctionAnalysisUpdateDisabled(true);
221 machoProcessor.ApplyHeader(GetCache(), *image.header);
222 view.SetFunctionAnalysisUpdateDisabled(prevDisabledState);
223
224 // Load objective-c information.
225 auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, false, image.headerAddress);
226 try
227 {
228 if (m_processObjC)
229 objcProcessor.ProcessObjCData();
230 if (m_processCFStrings)
231 objcProcessor.ProcessCFStrings();
232 }
233 catch (std::exception& e)
234 {
235 // Let the user know there was an error in processing the objc stuff but let the image load
236 // regardless, as its non-critical.
237 m_logger->LogError("Failed to process ObjC information: %s", e.what());
238 }
239 }
240
241 m_loadedImages.insert(image.headerAddress);
242
243 m_logger->LogInfoF("Loaded image: '{}'", image.path);
244
245 // TODO: This needs to be done in a "database save" callback.
246 // NOTE: We store on the parent view because hilariously, the view metadata is not available in view init.
247 view.GetParentView()->StoreMetadata(METADATA_KEY, GetMetadata());
248
249 // TODO: Partial failure state (i.e. 2 regions loaded, one failed)
250 return true;
251}

Callers 2

InitControllerMethod · 0.45

Calls 15

findMethod · 0.80
GetVirtualMemoryMethod · 0.80
ApplyHeaderMethod · 0.80
ProcessObjCDataMethod · 0.80
ProcessCFStringsMethod · 0.80
LogErrorMethod · 0.80
LogInfoFMethod · 0.80
GetParentViewMethod · 0.80

Tested by

no test coverage detected