diff options
Diffstat (limited to 'view/sharedcache/core/Utility.cpp')
| -rw-r--r-- | view/sharedcache/core/Utility.cpp | 131 |
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; +} |
