From 04bc6f11ae0289aae57d63d4cd32f4ef305d1a7a Mon Sep 17 00:00:00 2001 From: KyleMiles Date: Thu, 29 Jun 2023 20:49:26 -0400 Subject: Move binary view loading in to the core; deprecate open_view in favor of load; update examples --- binaryview.cpp | 221 ++++----------------------------------------------------- 1 file changed, 15 insertions(+), 206 deletions(-) (limited to 'binaryview.cpp') diff --git a/binaryview.cpp b/binaryview.cpp index 258cf6af..343dc322 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -4585,225 +4585,34 @@ Ref BinaryData::CreateFromFile(FileMetadata* file, FileAccessor* acc } -Ref BinaryNinja::OpenView(const std::string& filename, bool updateAnalysis, std::function progress, Json::Value options) +Ref BinaryNinja::Load(const std::string& filename, bool updateAnalysis, + std::function progress, Ref options) { - if (!progress) - progress = [](size_t, size_t) { return true; }; - - // Loading will surely fail if the file does not exist, so exit early - if (!BNPathExists(filename.c_str())) - return nullptr; - - // Detect bndb - bool isDatabase = false; - Ref view = nullptr; - - if (filename.size() > 6 && filename.substr(filename.size() - 5) == ".bndb") - { - // Open database, read raw view contents from it - static const std::string sqlite_header = "SQLite format 3"; - - FILE* f = fopen(filename.c_str(), "rb"); - // Unable to open file - if (f == nullptr) - return nullptr; - - char header[0x20]; - fread(header, 1, sqlite_header.size(), f); - fclose(f); - header[sqlite_header.size()] = 0; - - // File is not a valid sqlite db - if (sqlite_header != header) - return nullptr; - - Ref file = new FileMetadata(filename); - view = file->OpenDatabaseForConfiguration(filename); - isDatabase = true; - } - else - { - // Open file, read raw contents - Ref file = new FileMetadata(filename); - view = BinaryData::CreateFromFilename(file, filename); - } - - if (!view) + BNBinaryView* handle = BNLoadFilename(filename.c_str(), updateAnalysis, + (bool (*)(size_t, size_t))progress.target(), options->m_object); + if (!handle) return nullptr; - return OpenView(view, updateAnalysis, progress, options, isDatabase); + return new BinaryView(handle); } -Ref BinaryNinja::OpenView(const DataBuffer& rawData, bool updateAnalysis, std::function progress, Json::Value options) +Ref BinaryNinja::Load( + const DataBuffer& rawData, bool updateAnalysis, std::function progress, Ref options) { Ref file = new FileMetadata(); Ref view = new BinaryData(file, rawData); - return OpenView(view, updateAnalysis, progress, options, false); + return Load(view, updateAnalysis, progress, options, false); } -Ref BinaryNinja::OpenView(Ref view, bool updateAnalysis, std::function progress, Json::Value options, bool isDatabase) +Ref BinaryNinja::Load(Ref view, bool updateAnalysis, + std::function progress, Ref options, bool isDatabase) { - Ref bvt; - Ref universalBvt; - for (auto available : BinaryViewType::GetViewTypesForData(view)) - { - if (available->GetName() == "Universal") - { - universalBvt = available; - continue; - } - if (!bvt && available->GetName() != "Raw") - { - bvt = available; - } - } - - // No available views: Load as Mapped - if (!bvt) - bvt = BinaryViewType::GetByName("Mapped"); - - Ref defaultSettings = Settings::Instance(bvt->GetName() + "_settings"); - defaultSettings->DeserializeSchema(Settings::Instance()->SerializeSchema()); - defaultSettings->SetResourceId(bvt->GetName()); - - Ref loadSettings; - if (isDatabase) - { - loadSettings = view->GetLoadSettings(bvt->GetName()); - } - if (!loadSettings) - { - if (universalBvt && options.isMember("files.universal.architecturePreference")) - { - // Load universal architecture - loadSettings = universalBvt->GetLoadSettingsForData(view); - if (!loadSettings) - { - LogError("Could not load entry from Universal image. No load settings!"); - return nullptr; - } - std::string architectures = loadSettings->Get("loader.universal.architectures"); - - std::unique_ptr reader(Json::CharReaderBuilder().newCharReader()); - Json::Value archList; - std::string errors; - if (!reader->parse((const char*)architectures.data(), (const char*)architectures.data() + architectures.size(), &archList, &errors)) - { - BinaryNinja::LogError("Error parsing architecture list: %s", errors.data()); - return nullptr; - } - - Json::Value archEntry; - for (auto archPref : options["files.universal.architecturePreference"]) - { - for (auto entry : archList) - { - if (entry["architecture"].asString() == archPref.asString()) - { - archEntry = entry; - break; - } - } - if (!archEntry.isNull()) - break; - } - if (archEntry.isNull()) - { - std::string error = "Could not load any of:"; - for (auto archPref : options["files.universal.architecturePreference"]) - { - error += string(" ") + archPref.asString(); - } - error += " from Universal image. Entry not found! Available entries:"; - for (auto entry : archList) - { - error += string(" ") + entry["architecture"].asString(); - } - LogError("%s", error.c_str()); - return nullptr; - } - - loadSettings = Settings::Instance(GetUniqueIdentifierString()); - - Json::StreamWriterBuilder builder; - loadSettings->DeserializeSchema(archEntry["loadSchema"].asString()); - } - else - { - // Load non-universal architecture - loadSettings = bvt->GetLoadSettingsForData(view); - } - } - - if (!loadSettings) - { - LogError("Could not get load settings for binary view of type '%s'", bvt->GetName().c_str()); + BNBinaryView* handle = BNLoadBinaryView(view->GetObject(), updateAnalysis, + (bool (*)(size_t, size_t))progress.target(), options->m_object, isDatabase); + if (!handle) return nullptr; - } - - loadSettings->SetResourceId(bvt->GetName()); - view->SetLoadSettings(bvt->GetName(), loadSettings); - - for (auto key : options.getMemberNames()) - { - auto value = options[key]; - if (loadSettings->Contains(key)) - { - Json::StreamWriterBuilder builder; - builder["indentation"] = ""; - string json = Json::writeString(builder, value); - - if (!loadSettings->SetJson(key, json, view)) - { - LogError("Setting: %s set operation failed!", key.c_str()); - return nullptr; - } - } - else if (defaultSettings->Contains(key)) - { - Json::StreamWriterBuilder builder; - builder["indentation"] = ""; - string json = Json::writeString(builder, value); - - if (!defaultSettings->SetJson(key, json, view)) - { - LogError("Setting: %s set operation failed!", key.c_str()); - return nullptr; - } - } - else - { - LogError("Setting: %s not available!", key.c_str()); - return nullptr; - } - } - - Ref bv; - if (isDatabase) - { - view = view->GetFile()->OpenExistingDatabase(view->GetFile()->GetFilename(), progress); - if (!view) - { - LogError("Unable to open existing database with filename %s", view->GetFile()->GetFilename().c_str()); - return nullptr; - } - bv = view->GetFile()->GetViewOfType(bvt->GetName()); - } - else - { - bv = bvt->Create(view); - } - - if (!bv) - { - return view; - } - if (updateAnalysis) - { - bv->UpdateAnalysisAndWait(); - } - return bv; + return new BinaryView(handle); } -- cgit v1.3.1