diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-01 01:03:56 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-02 05:36:54 -0400 |
| commit | e1b164fa2bd10d5662c65ed930416d2f911c12e1 (patch) | |
| tree | 52edee3d42e0f414b4553145b523b3345f2665a4 /view/sharedcache/core/SharedCacheController.cpp | |
| parent | 7d8fab3ca667ea727becce31ce605d932c8784ed (diff) | |
[SharedCache] Fix some bugs
Diffstat (limited to 'view/sharedcache/core/SharedCacheController.cpp')
| -rw-r--r-- | view/sharedcache/core/SharedCacheController.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/view/sharedcache/core/SharedCacheController.cpp b/view/sharedcache/core/SharedCacheController.cpp index 29c1192a..72d5d950 100644 --- a/view/sharedcache/core/SharedCacheController.cpp +++ b/view/sharedcache/core/SharedCacheController.cpp @@ -60,6 +60,9 @@ SharedCacheController::SharedCacheController(SharedCache cache, Ref<Logger> logg m_logger = std::move(logger); m_loadedRegions = {}; m_loadedImages = {}; + m_processObjC = true; + m_processCFStrings = true; + m_regionFilter = std::regex(".*LINKEDIT.*"); } DSCRef<SharedCacheController> SharedCacheController::Initialize(BinaryView& view, SharedCache cache) @@ -111,16 +114,16 @@ bool SharedCacheController::ApplyRegionAtAddress(BinaryView& view, const uint64_ bool SharedCacheController::ApplyRegion(BinaryView& view, const CacheRegion& region) { - // TODO: Check m_loadedRegions? This seems redundant... + std::unique_lock<std::shared_mutex> lock(m_loadMutex); // Loads the given region into the BinaryView and marks it as loaded. - // First check to make sure there isn't already a segment at the address in the view. - if (view.GetSegmentAt(region.start)) + // First check to make sure we haven't already loaded the region. + if (m_loadedRegions.find(region.start) != m_loadedRegions.end()) return false; // Skip filtered regions, this defaults to just LINKEDIT regions. if (std::regex_match(region.name, m_regionFilter)) { - LogDebug("Skipping filtered region at %llx", region.start); + m_logger->LogDebug("Skipping filtered region at %llx", region.start); return false; } @@ -161,8 +164,9 @@ bool SharedCacheController::ApplyRegion(BinaryView& view, const CacheRegion& reg return true; } -bool SharedCacheController::IsRegionLoaded(const CacheRegion& region) const +bool SharedCacheController::IsRegionLoaded(const CacheRegion& region) { + std::shared_lock<std::shared_mutex> lock(m_loadMutex); return std::any_of(m_loadedRegions.begin(), m_loadedRegions.end(), [&](const auto& loadedRegion) { return loadedRegion == region.start; }); @@ -170,15 +174,19 @@ bool SharedCacheController::IsRegionLoaded(const CacheRegion& region) const bool SharedCacheController::ApplyImage(BinaryView& view, const CacheImage& image) { - // TODO: Check m_loadedImages? This seems redundant... // Load all regions of an image and mark the image as loaded. + // NOTE: The regions lock m_loadMutex themselves, so we do not hold it up here. bool loadedRegion = false; for (const auto& regionStart : image.regionStarts) if (ApplyRegionAtAddress(view, regionStart)) loadedRegion = true; + // The ApplyRegionAtAddress no longer holds the lock, we can take it now. + std::unique_lock<std::shared_mutex> lock(m_loadMutex); // If there was no loaded regions than we just want to forgo loading the image. - if (!loadedRegion) + // We also skip if we already loaded the image itself. We do this after loading regions + // as we regions have their own check. + if (!loadedRegion || m_loadedImages.find(image.headerAddress) != m_loadedImages.end()) return false; if (image.header) @@ -187,17 +195,16 @@ bool SharedCacheController::ApplyImage(BinaryView& view, const CacheImage& image auto machoProcessor = SharedCacheMachOProcessor(&view, m_cache.GetVirtualMemory()); machoProcessor.ApplyHeader(*image.header); - // TODO: Make this optional. - // Load objective-c information. - auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, false); // TODO: Passing in an image name here is weird considering this is shared with the MACHO view. // TODO: We should abstract out the "image" into an objc image type that represents what is required, which ig is the name? + // Load objective-c information. + auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, false); try { if (m_processObjC) objcProcessor.ProcessObjCData(image.GetName()); - if (m_processObjC) - objcProcessor.ProcessCFStrings(image.GetName()); + if (m_processCFStrings) + objcProcessor.ProcessCFStrings(image.GetName()); } catch (std::exception& e) { @@ -216,8 +223,9 @@ bool SharedCacheController::ApplyImage(BinaryView& view, const CacheImage& image return true; } -bool SharedCacheController::IsImageLoaded(const CacheImage& image) const +bool SharedCacheController::IsImageLoaded(const CacheImage& image) { + std::shared_lock<std::shared_mutex> lock(m_loadMutex); return std::any_of(m_loadedImages.begin(), m_loadedImages.end(), [&](const auto& loadedImage) { return loadedImage == image.headerAddress; }); |
