summaryrefslogtreecommitdiff
path: root/plugins/workflow_objc/GlobalState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/workflow_objc/GlobalState.cpp')
-rw-r--r--plugins/workflow_objc/GlobalState.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/plugins/workflow_objc/GlobalState.cpp b/plugins/workflow_objc/GlobalState.cpp
new file mode 100644
index 00000000..6aff3670
--- /dev/null
+++ b/plugins/workflow_objc/GlobalState.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2022-2023 Jon Palmisciano. All rights reserved.
+ *
+ * Use of this source code is governed by the BSD 3-Clause license; the full
+ * terms of the license can be found in the LICENSE.txt file.
+ */
+
+#include "GlobalState.h"
+
+#include <set>
+#include <shared_mutex>
+#include <unordered_map>
+
+static std::unordered_map<BinaryViewID, MessageHandler*> g_messageHandlers;
+static std::shared_mutex g_messageHandlerLock;
+static std::unordered_map<BinaryViewID, SharedAnalysisInfo> g_viewInfos;
+static std::shared_mutex g_viewInfoLock;
+static std::set<BinaryViewID> g_ignoredViews;
+
+
+MessageHandler* GlobalState::messageHandler(BinaryViewRef bv)
+{
+ std::unique_lock<std::shared_mutex> lock(g_messageHandlerLock);
+ auto messageHandler = g_messageHandlers.find(id(bv));
+ if (messageHandler != g_messageHandlers.end())
+ return messageHandler->second;
+ auto newMessageHandler = new MessageHandler(bv);
+ g_messageHandlers[id(bv)] = newMessageHandler;
+ return newMessageHandler;
+}
+
+BinaryViewID GlobalState::id(BinaryViewRef bv)
+{
+ return bv->GetFile()->GetSessionId();
+}
+
+void GlobalState::addIgnoredView(BinaryViewRef bv)
+{
+ g_ignoredViews.insert(id(std::move(bv)));
+}
+
+bool GlobalState::viewIsIgnored(BinaryViewRef bv)
+{
+ return g_ignoredViews.count(id(std::move(bv))) > 0;
+}
+
+SharedAnalysisInfo GlobalState::analysisInfo(BinaryViewRef data)
+{
+ {
+ std::shared_lock<std::shared_mutex> lock(g_viewInfoLock);
+ if (auto it = g_viewInfos.find(id(data)); it != g_viewInfos.end())
+ if (data->GetStart() == it->second->imageBase)
+ return it->second;
+ }
+
+ std::unique_lock<std::shared_mutex> lock(g_viewInfoLock);
+ SharedAnalysisInfo info = std::make_shared<AnalysisInfo>();
+ info->imageBase = data->GetStart();
+
+ if (auto objcStubs = data->GetSectionByName("__objc_stubs"))
+ {
+ info->objcStubsStartEnd = {objcStubs->GetStart(), objcStubs->GetEnd()};
+ info->hasObjcStubs = true;
+ }
+
+ auto meta = data->QueryMetadata("Objective-C");
+ if (!meta)
+ {
+ g_viewInfos[id(data)] = info;
+ return info;
+ }
+
+ auto metaKVS = meta->GetKeyValueStore();
+ if (metaKVS["version"]->GetUnsignedInteger() != 1)
+ {
+ BinaryNinja::LogError("workflow_objc: Invalid metadata version received!");
+ g_viewInfos[id(data)] = info;
+ return info;
+ }
+ for (const auto& selAndImps : metaKVS["selRefImplementations"]->GetArray())
+ info->selRefToImp[selAndImps->GetArray()[0]->GetUnsignedInteger()] = selAndImps->GetArray()[1]->GetUnsignedIntegerList();
+ for (const auto& selAndImps : metaKVS["selImplementations"]->GetArray())
+ info->selToImp[selAndImps->GetArray()[0]->GetUnsignedInteger()] = selAndImps->GetArray()[1]->GetUnsignedIntegerList();
+
+ g_viewInfos[id(data)] = info;
+ return info;
+}
+
+bool GlobalState::hasAnalysisInfo(BinaryViewRef data)
+{
+ return data->QueryMetadata("Objective-C") != nullptr;
+}
+
+bool GlobalState::hasFlag(BinaryViewRef bv, const std::string& flag)
+{
+ return bv->QueryMetadata(flag);
+}
+
+void GlobalState::setFlag(BinaryViewRef bv, const std::string& flag)
+{
+ bv->StoreMetadata(flag, new BinaryNinja::Metadata("YES"));
+}