summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/Utility.cpp
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-03-10 11:05:40 -0400
committerMason Reed <mason@vector35.com>2025-04-02 05:36:54 -0400
commit25cc02431b61097b2adfc2fbc493b648b0300c3b (patch)
treea79d9c4f4f67234d3bf9bda413e8608f479a4cc8 /view/sharedcache/core/Utility.cpp
parentfa85bf28502286c4821427c5d0ed91a7ed46f8f6 (diff)
[SharedCache] Refactor Shared Cache
In absence of a better name, this commit refactors the shared cache code.
Diffstat (limited to 'view/sharedcache/core/Utility.cpp')
-rw-r--r--view/sharedcache/core/Utility.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/view/sharedcache/core/Utility.cpp b/view/sharedcache/core/Utility.cpp
new file mode 100644
index 00000000..91729578
--- /dev/null
+++ b/view/sharedcache/core/Utility.cpp
@@ -0,0 +1,131 @@
+#include "Utility.h"
+#include "binaryninjaapi.h"
+#include "view/macho/machoview.h"
+
+using namespace BinaryNinja;
+
+BNSegmentFlag SegmentFlagsFromMachOProtections(int initProt, int maxProt)
+{
+ uint32_t flags = 0;
+ if (initProt & MACHO_VM_PROT_READ)
+ flags |= SegmentReadable;
+ if (initProt & MACHO_VM_PROT_WRITE)
+ flags |= SegmentWritable;
+ if (initProt & MACHO_VM_PROT_EXECUTE)
+ flags |= SegmentExecutable;
+ if (((initProt & MACHO_VM_PROT_WRITE) == 0) && ((maxProt & MACHO_VM_PROT_WRITE) == 0))
+ flags |= SegmentDenyWrite;
+ if (((initProt & MACHO_VM_PROT_EXECUTE) == 0) && ((maxProt & MACHO_VM_PROT_EXECUTE) == 0))
+ flags |= SegmentDenyExecute;
+ return static_cast<BNSegmentFlag>(flags);
+}
+
+int64_t readSLEB128(const uint8_t*& current, const uint8_t* end)
+{
+ uint8_t cur;
+ int64_t value = 0;
+ size_t shift = 0;
+ while (current != end)
+ {
+ cur = *current++;
+ value |= (cur & 0x7f) << shift;
+ shift += 7;
+ if ((cur & 0x80) == 0)
+ break;
+ }
+ value = (value << (64 - shift)) >> (64 - shift);
+ return value;
+}
+
+uint64_t readLEB128(const uint8_t*& current, const uint8_t* end)
+{
+ uint64_t result = 0;
+ int bit = 0;
+ do
+ {
+ if (current >= end)
+ return -1;
+
+ uint64_t slice = *current & 0x7f;
+
+ if (bit > 63)
+ return -1;
+ result |= (slice << bit);
+ bit += 7;
+ } while (*current++ & 0x80);
+ return result;
+}
+
+
+uint64_t readValidULEB128(const uint8_t*& current, const uint8_t* end)
+{
+ uint64_t value = readLEB128(current, end);
+ if ((int64_t)value == -1)
+ throw ReadException();
+ return value;
+}
+
+void ApplySymbol(Ref<BinaryView> view, Ref<TypeLibrary> typeLib, Ref<Symbol> symbol)
+{
+ Ref<Function> func = nullptr;
+ auto symbolAddress = symbol->GetAddress();
+ auto symbolName = symbol->GetFullName();
+
+ if (symbol->GetType() == FunctionSymbol)
+ {
+ Ref<Platform> targetPlatform = view->GetDefaultPlatform();
+ func = view->AddFunctionForAnalysis(targetPlatform, symbolAddress);
+ }
+
+ if (typeLib)
+ {
+ auto type = view->ImportTypeLibraryObject(typeLib, {symbolName});
+ // TODO: This is still auto
+ if (type)
+ view->DefineAutoSymbolAndVariableOrFunction(view->GetDefaultPlatform(), symbol, type);
+ else
+ view->DefineAutoSymbol(symbol);
+ }
+ else
+ {
+ view->DefineAutoSymbol(symbol);
+ }
+
+ if (!func)
+ func = view->GetAnalysisFunction(view->GetDefaultPlatform(), symbolAddress);
+ if (func)
+ {
+ if (symbolName == "_objc_msgSend")
+ {
+ func->SetHasVariableArguments(false);
+ }
+ else if (symbolName.find("_objc_retain_x") != std::string::npos
+ || symbolName.find("_objc_release_x") != std::string::npos)
+ {
+ auto x = symbolName.rfind('x');
+ auto num = symbolName.substr(x + 1);
+
+ std::vector<FunctionParameter> callTypeParams;
+ auto cc = view->GetDefaultArchitecture()->GetCallingConventionByName("apple-arm64-objc-fast-arc-" + num);
+
+ if (auto idType = view->GetTypeByName({"id"}))
+ {
+ callTypeParams.emplace_back("obj", idType, true, Variable());
+ auto funcType = Type::FunctionType(idType, cc, callTypeParams);
+ func->SetUserType(funcType);
+ }
+ else
+ {
+ LogWarn("Failed to find id type for %llx, objective-c processor not ran?", func->GetStart());
+ }
+ }
+ }
+}
+
+std::string BaseFileName(const std::string& path)
+{
+ auto lastSlashPos = path.find_last_of("/\\");
+ if (lastSlashPos != std::string::npos)
+ return path.substr(lastSlashPos + 1);
+ return path;
+}