summaryrefslogtreecommitdiff
path: root/view/sharedcache/core
diff options
context:
space:
mode:
authorkat <kat@vector35.com>2024-10-30 08:39:09 -0400
committerkat <kat@vector35.com>2024-11-05 09:03:12 -0500
commitf4a4b17b9e30cf603eb614e153d68226a3b24520 (patch)
treee33d18742c1a9e9b47af04df24bf88248c17f06a /view/sharedcache/core
parentfd8eb478a7a3bbc848da37bd33e62c2d8cf26b99 (diff)
[SharedCache] Implement LoadedImage API, Fix serialized image names, more robust system for out-of-date databases
Diffstat (limited to 'view/sharedcache/core')
-rw-r--r--view/sharedcache/core/CMakeLists.txt41
-rw-r--r--view/sharedcache/core/DSCView.cpp15
-rw-r--r--view/sharedcache/core/SharedCache.cpp22
-rw-r--r--view/sharedcache/core/SharedCache.h26
4 files changed, 85 insertions, 19 deletions
diff --git a/view/sharedcache/core/CMakeLists.txt b/view/sharedcache/core/CMakeLists.txt
index 9cf3fa9d..22c7ea28 100644
--- a/view/sharedcache/core/CMakeLists.txt
+++ b/view/sharedcache/core/CMakeLists.txt
@@ -46,25 +46,36 @@ endfunction()
get_recursive_include_dirs(binaryninjaapi INCLUDES)
+set(COMPILE_DEFS "")
+
+if (HARD_FAIL_MODE)
+ set(COMPILE_DEFS "${COMPILE_DEFS} ABORT_FAILURES;")
+endif()
+
+if (BN_REF_COUNT_DEBUG)
+ set(COMPILE_DEFS "${COMPILE_DEFS} BN_REF_COUNT_DEBUG;")
+endif()
+
+if (SLIDEINFO_DEBUG_TAGS)
+ set(COMPILE_DEFS "${COMPILE_DEFS} SLIDEINFO_DEBUG_TAGS;")
+endif()
+
if (VIEW_NAME)
- if (SLIDEINFO_DEBUG_TAGS)
- if (BN_REF_COUNT_DEBUG)
- target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY SLIDEINFO_DEBUG_TAGS BN_REF_COUNT_DEBUG)
- else()
- target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY SLIDEINFO_DEBUG_TAGS)
- endif()
- else()
- if (BN_REF_COUNT_DEBUG)
- target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY BN_REF_COUNT_DEBUG)
- else()
- target_compile_definitions(sharedcachecore PRIVATE VIEW_NAME="${VIEW_NAME}" SHAREDCACHE_LIBRARY)
- endif()
- endif()
- message(STATUS "VIEW_NAME: ${VIEW_NAME}")
+ set(COMPILE_DEFS "${COMPILE_DEFS} VIEW_NAME=\"${VIEW_NAME}\";")
+else()
+ message(FATAL_ERROR "No view name provided. Fatal.")
+endif()
+
+if (METADATA_VERSION)
+ set(COMPILE_DEFS "${COMPILE_DEFS} METADATA_VERSION=${METADATA_VERSION};")
else()
- error("VIEW_NAME must be defined")
+ message(FATAL_ERROR "No metadata version provided. Fatal.")
endif()
+target_compile_definitions(sharedcachecore PRIVATE ${COMPILE_DEFS})
+
+
+target_compile_definitions(sharedcachecore PRIVATE SHAREDCACHE_LIBRARY ${COMPILE_DEFS})
target_include_directories(sharedcachecore PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${INCLUDES})
diff --git a/view/sharedcache/core/DSCView.cpp b/view/sharedcache/core/DSCView.cpp
index 7a1b3677..80456fc7 100644
--- a/view/sharedcache/core/DSCView.cpp
+++ b/view/sharedcache/core/DSCView.cpp
@@ -629,6 +629,21 @@ bool DSCView::Init()
ss.str(data);
rapidjson::Document result(rapidjson::kObjectType);
+ if (result.HasMember("metadataVersion"))
+ {
+ if (result["metadataVersion"].GetInt() != METADATA_VERSION)
+ {
+ LogError("Shared cache metadata version mismatch: expected %d, got %d", METADATA_VERSION,
+ result["metadataVersion"].GetInt());
+ return false;
+ }
+ }
+ else
+ {
+ LogError("Shared cache metadata version not found");
+ return false;
+ }
+
result.Parse(data.c_str());
for (auto& imgV : result["regionsMappedIntoMemory"].GetArray())
{
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp
index 49aa3174..ec0db6e7 100644
--- a/view/sharedcache/core/SharedCache.cpp
+++ b/view/sharedcache/core/SharedCache.cpp
@@ -164,7 +164,14 @@ uint64_t readValidULEB128(DataBuffer& buffer, size_t& cursor)
uint64_t SharedCache::FastGetBackingCacheCount(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView)
{
- auto baseFile = MMappedFileAccessor::Open(dscView->GetFile()->GetSessionId(), dscView->GetFile()->GetOriginalFilename())->lock();
+ std::shared_ptr<MMappedFileAccessor> baseFile;
+ try {
+ baseFile = MMappedFileAccessor::Open(dscView->GetFile()->GetSessionId(), dscView->GetFile()->GetOriginalFilename())->lock();
+ }
+ catch (...){
+ LogError("SharedCache preload: Failed to open file");
+ return 0;
+ }
dyld_cache_header header {};
size_t header_size = baseFile->ReadUInt32(16);
@@ -749,7 +756,7 @@ void SharedCache::PerformInitialLoad()
memcpy(segName, segment.segname, 16);
segName[16] = 0;
MemoryRegion sectionRegion;
- sectionRegion.prettyName = std::string(segName);
+ sectionRegion.prettyName = imageHeader.value().identifierPrefix + "::" + std::string(segName);
sectionRegion.start = segment.vmaddr;
sectionRegion.size = segment.vmsize;
uint32_t flags = 0;
@@ -983,14 +990,21 @@ void SharedCache::DeserializeFromRawView()
m_baseFilePath = c.m_baseFilePath;
m_exportInfos = c.m_exportInfos;
m_symbolInfos = c.m_symbolInfos;
+ m_metadataValid = true;
}
else
{
LoadFromString(m_dscView->GetStringMetadata(SharedCacheMetadataTag));
}
+ if (!m_metadataValid)
+ {
+ m_logger->LogError("Failed to deserialize Shared Cache metadata");
+ m_viewState = DSCViewStateUnloaded;
+ }
}
else
{
+ m_metadataValid = true;
m_viewState = DSCViewStateUnloaded;
m_images.clear(); // fixme ??
}
@@ -1343,6 +1357,8 @@ SharedCache::SharedCache(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView) : m_
INIT_SHAREDCACHE_API_OBJECT()
m_logger = LogRegistry::GetLogger("SharedCache", dscView->GetFile()->GetSessionId());
DeserializeFromRawView();
+ if (!m_metadataValid)
+ return;
if (m_viewState == DSCViewStateUnloaded)
{
if (m_viewState == DSCViewStateUnloaded)
@@ -2935,6 +2951,8 @@ bool SharedCache::SaveToDSCView()
c.m_symbolInfos = m_symbolInfos;
viewStateCache[m_dscView->GetFile()->GetSessionId()] = c;
+ m_metadataValid = true;
+
return true;
}
return false;
diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h
index 2f099773..9e9688bd 100644
--- a/view/sharedcache/core/SharedCache.h
+++ b/view/sharedcache/core/SharedCache.h
@@ -940,6 +940,8 @@ namespace SharedCacheCore {
void Store() override
{
+ m_activeContext.doc.AddMember("metadataVersion", METADATA_VERSION, m_activeContext.allocator);
+
MSS(m_viewState);
MSS_CAST(m_cacheFormat, uint8_t);
MSS(m_imageStarts);
@@ -1026,6 +1028,19 @@ namespace SharedCacheCore {
}
void Load() override
{
+ if (m_activeDeserContext.doc.HasMember("metadataVersion"))
+ {
+ if (m_activeDeserContext.doc["metadataVersion"].GetUint() != METADATA_VERSION)
+ {
+ m_logger->LogError("SharedCache metadata version mismatch");
+ return;
+ }
+ }
+ else
+ {
+ m_logger->LogError("SharedCache metadata version missing");
+ return;
+ }
m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState);
m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat);
m_headers.clear();
@@ -1101,6 +1116,8 @@ namespace SharedCacheCore {
si.LoadFromValue(siV);
m_nonImageRegions.push_back(si);
}
+
+ m_metadataValid = true;
}
private:
@@ -1108,7 +1125,7 @@ namespace SharedCacheCore {
/* VIEW STATE BEGIN -- SERIALIZE ALL OF THIS AND STORE IT IN RAW VIEW */
// Updated as the view is loaded further, more images are added, etc
- DSCViewState m_viewState;
+ DSCViewState m_viewState = DSCViewStateUnloaded;
std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>
m_exportInfos;
std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>
@@ -1116,6 +1133,8 @@ namespace SharedCacheCore {
// ---
// Serialized once by PerformInitialLoad and available after m_viewState == Loaded
+ bool m_metadataValid = false;
+
std::string m_baseFilePath;
SharedCacheFormat m_cacheFormat;
@@ -1171,7 +1190,10 @@ namespace SharedCacheCore {
void FindSymbolAtAddrAndApplyToAddr(uint64_t symbolLocation, uint64_t targetLocation, bool triggerReanalysis);
- std::vector<BackingCache> BackingCaches() const { return m_backingCaches; }
+ std::vector<BackingCache> BackingCaches() const {
+
+ return m_backingCaches;
+ }
DSCViewState State() const { return m_viewState; }