summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h496
-rw-r--r--binaryninjacore.h5
-rw-r--r--binaryview.cpp221
-rw-r--r--docs/dev/batch.md16
-rw-r--r--enterprise.h2
-rw-r--r--python/__init__.py33
-rw-r--r--python/binaryview.py354
-rw-r--r--python/enterprise.py2
-rw-r--r--python/examples/bin_info.py5
-rwxr-xr-xpython/examples/debug_info.py2
-rw-r--r--python/examples/feature_map.py2
-rw-r--r--python/examples/instruction_iterator.py4
-rw-r--r--python/examples/mappedview.py2
-rwxr-xr-xpython/examples/pe_stat.py2
-rw-r--r--python/examples/print_syscalls.py4
-rw-r--r--python/filemetadata.py5
-rw-r--r--python/function.py2
-rw-r--r--python/settings.py4
-rw-r--r--rust/examples/basic_script/src/main.rs2
-rw-r--r--rust/examples/decompile/src/main.rs2
-rw-r--r--rust/examples/template/src/main.rs2
-rw-r--r--rust/src/headless.rs2
-rw-r--r--rust/src/lib.rs222
-rw-r--r--rust/src/metadata.rs72
-rw-r--r--suite/api_test.py6
-rw-r--r--suite/testcommon.py102
26 files changed, 563 insertions, 1008 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index ef47dc23..2170e82f 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -940,6 +940,239 @@ namespace BinaryNinja {
@}
*/
+ class Metadata;
+ typedef BNMetadataType MetadataType;
+
+ /*!
+ \ingroup binaryview
+ */
+ class Metadata : public CoreRefCountObject<BNMetadata, BNNewMetadataReference, BNFreeMetadata>
+ {
+ public:
+ explicit Metadata(BNMetadata* structuredData);
+ /*! Create a new Metadata object representing a bool
+
+ @threadsafe
+
+ \param data Bool to store
+
+ */
+ explicit Metadata(bool data);
+
+ /*! Create a new Metadata object representing a string
+
+ @threadsafe
+
+ \param data string to store
+
+ */
+ explicit Metadata(const std::string& data);
+
+ /*! Create a new Metadata object representing a uint64
+
+ @threadsafe
+
+ \param data - uint64 to store
+
+ */
+ explicit Metadata(uint64_t data);
+
+ /*! Create a new Metadata object representing an int64
+
+ @threadsafe
+
+ \param data - int64 to store
+
+ */
+ explicit Metadata(int64_t data);
+
+ /*! Create a new Metadata object representing a double
+
+ @threadsafe
+
+ \param data - double to store
+
+ */
+ explicit Metadata(double data);
+
+ /*! Create a new Metadata object representing a vector of bools
+
+ @threadsafe
+
+ \param data - list of bools to store
+
+ */
+ explicit Metadata(const std::vector<bool>& data);
+
+ /*! Create a new Metadata object representing a vector of strings
+
+ @threadsafe
+
+ \param data - list of strings to store
+
+ */
+ explicit Metadata(const std::vector<std::string>& data);
+
+ /*! Create a new Metadata object representing a vector of uint64s
+
+ @threadsafe
+
+ \param data - list of uint64s to store
+
+ */
+ explicit Metadata(const std::vector<uint64_t>& data);
+
+ /*! Create a new Metadata object representing a vector of int64s
+
+ @threadsafe
+
+ \param data - list of int64s to store
+
+ */
+ explicit Metadata(const std::vector<int64_t>& data);
+
+ /*! Create a new Metadata object representing a vector of doubles
+
+ @threadsafe
+
+ \param data - list of doubles to store
+
+ */
+ explicit Metadata(const std::vector<double>& data);
+
+ /*! Create a new Metadata object representing a vector of bytes to store
+
+ @threadsafe
+
+ \param data - list of bytes to store
+
+ */
+ explicit Metadata(const std::vector<uint8_t>& data);
+
+ /*! Create a new Metadata object representing a vector of children Metadata objects
+
+ @threadsafe
+
+ \param data - list of Metadata objects to store
+
+ */
+ explicit Metadata(const std::vector<Ref<Metadata>>& data);
+
+ /*! Create a new Metadata object representing a map of strings to metadata objects
+
+ @threadsafe
+
+ \param data - map of strings to metadata objects
+
+ */
+ explicit Metadata(const std::map<std::string, Ref<Metadata>>& data);
+ explicit Metadata(MetadataType type);
+ virtual ~Metadata() {}
+
+ bool operator==(const Metadata& rhs);
+ Ref<Metadata> operator[](const std::string& key);
+ Ref<Metadata> operator[](size_t idx);
+
+ MetadataType GetType() const;
+ bool GetBoolean() const;
+ std::string GetString() const;
+ uint64_t GetUnsignedInteger() const;
+ int64_t GetSignedInteger() const;
+ double GetDouble() const;
+ std::vector<bool> GetBooleanList() const;
+ std::vector<std::string> GetStringList() const;
+ std::vector<uint64_t> GetUnsignedIntegerList() const;
+ std::vector<int64_t> GetSignedIntegerList() const;
+ std::vector<double> GetDoubleList() const;
+ std::vector<uint8_t> GetRaw() const;
+ std::vector<Ref<Metadata>> GetArray();
+ std::map<std::string, Ref<Metadata>> GetKeyValueStore();
+
+ // For key-value data only
+ /*! Get a Metadata object by key. Only for if IsKeyValueStore == true
+
+ @threadunsafewith{SetValueForKey and RemoveKey}
+
+ \param key
+ \return
+ */
+ Ref<Metadata> Get(const std::string& key);
+ /*! Set the value mapped to by a particular string. Only for if IsKeyValueStore == true
+
+ @threadunsafewith{Get and RemoveKey}
+
+ \param key
+ \param data
+ \return
+ */
+ bool SetValueForKey(const std::string& key, Ref<Metadata> data);
+
+ /*! Remove a key from the map. Only for if IsKeyValueStore == true
+
+ @threadunsafewith{SetValueForKey and Get}
+
+ \param key - Key to remove
+ */
+ void RemoveKey(const std::string& key);
+
+ // For array data only
+ /*! Get an item at a given index
+
+ For array data only
+
+ @threadunsafewith{Array data modifiers}
+
+ \param index Index of the item to retrieve
+ \return Item at that index, if valid.
+ */
+ Ref<Metadata> Get(size_t index);
+
+ /*! Append an item to the array
+
+ For array data only
+
+ @threadunsafewith{Array data modifiers}
+
+ \param data Data to append
+ \return Whether the append was successful
+ */
+ bool Append(Ref<Metadata> data);
+
+ /*! Remove an item at a given index
+
+ For array data only
+
+ @threadunsafewith{Array data modifiers}
+
+ \param index Index of the item to remove
+ */
+ void RemoveIndex(size_t index);
+
+ /*! Get the size of the array
+
+ For array data only
+
+ @threadunsafewith{Array data modifiers}
+
+ \return Size of the array
+ */
+ size_t Size() const;
+
+ bool IsBoolean() const;
+ bool IsString() const;
+ bool IsUnsignedInteger() const;
+ bool IsSignedInteger() const;
+ bool IsDouble() const;
+ bool IsBooleanList() const;
+ bool IsStringList() const;
+ bool IsUnsignedIntegerList() const;
+ bool IsSignedIntegerList() const;
+ bool IsDoubleList() const;
+ bool IsRaw() const;
+ bool IsArray() const;
+ bool IsKeyValueStore() const;
+ };
+
class BinaryView;
/*! OpenView opens a file on disk and returns a BinaryView, attempting to use the most
@@ -964,60 +1197,62 @@ namespace BinaryNinja {
SettingsUserScope and can be modified as follows:
\code{.cpp}
- Json::Value options(Json::objectValue);
- options["files.universal.architecturePreference"] = Json::Value(Json::arrayValue);
- options["files.universal.architecturePreference"].append("arm64");
- Ref<BinaryView> bv = OpenView("/bin/ls", true, {}, options);
+ Metadata options = {{"files.universal.architecturePreference", Metadata({"arm64"})}};
+ Ref<BinaryView> bv = Load("/bin/ls", true, {}, options);
\endcode
\param filename Path to filename or BNDB to open.
\param updateAnalysis If true, UpdateAnalysisAndWait() will be called after opening
a BinaryView.
\param progress Optional function to be called with progress updates as the view is
- being loaded. If the function returns false, it will cancel OpenView.
+ being loaded. If the function returns false, it will cancel Load.
\param options A Json object whose keys are setting identifiers and whose values are
the desired settings.
\return Constructed view, or a nullptr Ref<BinaryView>
*/
- Ref<BinaryView> OpenView(const std::string& filename, bool updateAnalysis = true, std::function<bool(size_t, size_t)> progress = {}, Json::Value options = Json::Value(Json::objectValue));
+ Ref<BinaryView> Load(const std::string& filename, bool updateAnalysis = true,
+ std::function<bool(size_t, size_t)> progress = {}, Ref<Metadata> options = new Metadata(MetadataType::KeyValueDataType));
/*! Open a BinaryView from a raw data buffer, initializing data views and loading settings.
@threadmainonly
- \see BinaryNinja::OpenView(const std::string&, bool, std::function<bool(size_t, size_t)>, Json::Value)
+ \see BinaryNinja::Load(const std::string&, bool, std::function<bool(size_t, size_t)>, Json::Value)
for discussion of this function.
\param rawData Buffer with raw binary data to load (cannot load from bndb)
\param updateAnalysis If true, UpdateAnalysisAndWait() will be called after opening
a BinaryView.
\param progress Optional function to be called with progress updates as the view is
- being loaded. If the function returns false, it will cancel OpenView.
+ being loaded. If the function returns false, it will cancel Load.
\param options A Json object whose keys are setting identifiers and whose values are
the desired settings.
\return Constructed view, or a nullptr Ref<BinaryView>
*/
- Ref<BinaryView> OpenView(const DataBuffer& rawData, bool updateAnalysis = true, std::function<bool(size_t, size_t)> progress = {}, Json::Value options = Json::Value(Json::objectValue));
+ Ref<BinaryView> Load(const DataBuffer& rawData, bool updateAnalysis = true,
+ std::function<bool(size_t, size_t)> progress = {}, Ref<Metadata> options = new Metadata(MetadataType::KeyValueDataType));
/*! Open a BinaryView from a raw BinaryView, initializing data views and loading settings.
@threadmainonly
- \see BinaryNinja::OpenView(const std::string&, bool, std::function<bool(size_t, size_t)>, Json::Value)
+ \see BinaryNinja::Load(const std::string&, bool, std::function<bool(size_t, size_t)>, Json::Value)
for discussion of this function.
\param rawData BinaryView with raw binary data to load
\param updateAnalysis If true, UpdateAnalysisAndWait() will be called after opening
a BinaryView.
\param progress Optional function to be called with progress updates as the view is
- being loaded. If the function returns false, it will cancel OpenView.
+ being loaded. If the function returns false, it will cancel Load.
\param options A Json object whose keys are setting identifiers and whose values are
the desired settings.
\param isDatabase True if the view being loaded is the raw view of an already opened database.
\return Constructed view, or a nullptr Ref<BinaryView>
*/
- Ref<BinaryView> OpenView(Ref<BinaryView> rawData, bool updateAnalysis = true, std::function<bool(size_t, size_t)> progress = {}, Json::Value options = Json::Value(Json::objectValue), bool isDatabase = false);
+ Ref<BinaryView> Load(Ref<BinaryView> rawData, bool updateAnalysis = true,
+ std::function<bool(size_t, size_t)> progress = {}, Ref<Metadata> options = new Metadata(MetadataType::KeyValueDataType),
+ bool isDatabase = false);
/*! Demangles a Microsoft Visual Studio C++ name
@@ -3251,7 +3486,7 @@ namespace BinaryNinja {
To open a file with a given BinaryView the following code is recommended:
\code{.cpp}
- auto bv = OpenView("/bin/ls");
+ auto bv = Load("/bin/ls");
\endcode
\remark By convention in the rest of this document we will use bv to mean an open and, analyzed, BinaryView of an executable file.
@@ -14446,9 +14681,8 @@ namespace BinaryNinja {
"ignore": ["SettingsProjectScope", "SettingsResourceScope"]
})~");
- Json::Value options(Json::objectValue);
- options["myPlugin.enablePreAnalysis"] = Json::Value(true);
- Ref<BinaryView> bv = OpenView("/bin/ls", true, {}, options);
+ Metadata options = {{"myPlugin.enablePreAnalysis", Metadata(true)}};
+ Ref<BinaryView> bv = Load("/bin/ls", true, {}, options);
Settings::Instance()->Get<bool>("myPlugin.enablePreAnalysis"); // false
Settings::Instance()->Get<bool>("myPlugin.enablePreAnalysis", bv); // true
@@ -14629,236 +14863,6 @@ namespace BinaryNinja {
typedef BNMetadataType MetadataType;
- /*!
- \ingroup binaryview
- */
- class Metadata : public CoreRefCountObject<BNMetadata, BNNewMetadataReference, BNFreeMetadata>
- {
- public:
- explicit Metadata(BNMetadata* structuredData);
- /*! Create a new Metadata object representing a bool
-
- @threadsafe
-
- \param data Bool to store
-
- */
- explicit Metadata(bool data);
-
- /*! Create a new Metadata object representing a string
-
- @threadsafe
-
- \param data string to store
-
- */
- explicit Metadata(const std::string& data);
-
- /*! Create a new Metadata object representing a uint64
-
- @threadsafe
-
- \param data - uint64 to store
-
- */
- explicit Metadata(uint64_t data);
-
- /*! Create a new Metadata object representing an int64
-
- @threadsafe
-
- \param data - int64 to store
-
- */
- explicit Metadata(int64_t data);
-
- /*! Create a new Metadata object representing a double
-
- @threadsafe
-
- \param data - double to store
-
- */
- explicit Metadata(double data);
-
- /*! Create a new Metadata object representing a vector of bools
-
- @threadsafe
-
- \param data - list of bools to store
-
- */
- explicit Metadata(const std::vector<bool>& data);
-
- /*! Create a new Metadata object representing a vector of strings
-
- @threadsafe
-
- \param data - list of strings to store
-
- */
- explicit Metadata(const std::vector<std::string>& data);
-
- /*! Create a new Metadata object representing a vector of uint64s
-
- @threadsafe
-
- \param data - list of uint64s to store
-
- */
- explicit Metadata(const std::vector<uint64_t>& data);
-
- /*! Create a new Metadata object representing a vector of int64s
-
- @threadsafe
-
- \param data - list of int64s to store
-
- */
- explicit Metadata(const std::vector<int64_t>& data);
-
- /*! Create a new Metadata object representing a vector of doubles
-
- @threadsafe
-
- \param data - list of doubles to store
-
- */
- explicit Metadata(const std::vector<double>& data);
-
- /*! Create a new Metadata object representing a vector of bytes to store
-
- @threadsafe
-
- \param data - list of bytes to store
-
- */
- explicit Metadata(const std::vector<uint8_t>& data);
-
- /*! Create a new Metadata object representing a vector of children Metadata objects
-
- @threadsafe
-
- \param data - list of Metadata objects to store
-
- */
- explicit Metadata(const std::vector<Ref<Metadata>>& data);
-
- /*! Create a new Metadata object representing a map of strings to metadata objects
-
- @threadsafe
-
- \param data - map of strings to metadata objects
-
- */
- explicit Metadata(const std::map<std::string, Ref<Metadata>>& data);
- explicit Metadata(MetadataType type);
- virtual ~Metadata() {}
-
- bool operator==(const Metadata& rhs);
- Ref<Metadata> operator[](const std::string& key);
- Ref<Metadata> operator[](size_t idx);
-
- MetadataType GetType() const;
- bool GetBoolean() const;
- std::string GetString() const;
- uint64_t GetUnsignedInteger() const;
- int64_t GetSignedInteger() const;
- double GetDouble() const;
- std::vector<bool> GetBooleanList() const;
- std::vector<std::string> GetStringList() const;
- std::vector<uint64_t> GetUnsignedIntegerList() const;
- std::vector<int64_t> GetSignedIntegerList() const;
- std::vector<double> GetDoubleList() const;
- std::vector<uint8_t> GetRaw() const;
- std::vector<Ref<Metadata>> GetArray();
- std::map<std::string, Ref<Metadata>> GetKeyValueStore();
-
- // For key-value data only
- /*! Get a Metadata object by key. Only for if IsKeyValueStore == true
-
- @threadunsafewith{SetValueForKey and RemoveKey}
-
- \param key
- \return
- */
- Ref<Metadata> Get(const std::string& key);
- /*! Set the value mapped to by a particular string. Only for if IsKeyValueStore == true
-
- @threadunsafewith{Get and RemoveKey}
-
- \param key
- \param data
- \return
- */
- bool SetValueForKey(const std::string& key, Ref<Metadata> data);
-
- /*! Remove a key from the map. Only for if IsKeyValueStore == true
-
- @threadunsafewith{SetValueForKey and Get}
-
- \param key - Key to remove
- */
- void RemoveKey(const std::string& key);
-
- // For array data only
- /*! Get an item at a given index
-
- For array data only
-
- @threadunsafewith{Array data modifiers}
-
- \param index Index of the item to retrieve
- \return Item at that index, if valid.
- */
- Ref<Metadata> Get(size_t index);
-
- /*! Append an item to the array
-
- For array data only
-
- @threadunsafewith{Array data modifiers}
-
- \param data Data to append
- \return Whether the append was successful
- */
- bool Append(Ref<Metadata> data);
-
- /*! Remove an item at a given index
-
- For array data only
-
- @threadunsafewith{Array data modifiers}
-
- \param index Index of the item to remove
- */
- void RemoveIndex(size_t index);
-
- /*! Get the size of the array
-
- For array data only
-
- @threadunsafewith{Array data modifiers}
-
- \return Size of the array
- */
- size_t Size() const;
-
- bool IsBoolean() const;
- bool IsString() const;
- bool IsUnsignedInteger() const;
- bool IsSignedInteger() const;
- bool IsDouble() const;
- bool IsBooleanList() const;
- bool IsStringList() const;
- bool IsUnsignedIntegerList() const;
- bool IsSignedIntegerList() const;
- bool IsDoubleList() const;
- bool IsRaw() const;
- bool IsArray() const;
- bool IsKeyValueStore() const;
- };
-
/*! DataRenderer objects tell the Linear View how to render specific types.
The `IsValidForData` method returns a boolean to indicate if your derived class
diff --git a/binaryninjacore.h b/binaryninjacore.h
index dd5840fd..d2b51224 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -5605,6 +5605,11 @@ extern "C"
BINARYNINJACOREAPI BNComponent** BNGetFunctionParentComponents(BNBinaryView* view, BNFunction *func, size_t* count);
BINARYNINJACOREAPI BNComponent** BNGetDataVariableParentComponents(BNBinaryView* view, uint64_t dataVariable, size_t* count);
+ BINARYNINJACOREAPI BNBinaryView* BNLoadFilename(const char* const filename, const bool updateAnalysis,
+ bool (*progress)(size_t, size_t), const BNMetadata* const options);
+ BINARYNINJACOREAPI BNBinaryView* BNLoadBinaryView(BNBinaryView* view, const bool updateAnalysis,
+ bool (*progress)(size_t, size_t), const BNMetadata* const options, const bool isDatabase);
+
// Source code processing
BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors,
const char** includeDirs, size_t includeDirCount);
diff --git a/binaryview.cpp b/binaryview.cpp
index 258cf6af..343dc322 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -4585,225 +4585,34 @@ Ref<BinaryData> BinaryData::CreateFromFile(FileMetadata* file, FileAccessor* acc
}
-Ref<BinaryView> BinaryNinja::OpenView(const std::string& filename, bool updateAnalysis, std::function<bool(size_t, size_t)> progress, Json::Value options)
+Ref<BinaryView> BinaryNinja::Load(const std::string& filename, bool updateAnalysis,
+ std::function<bool(size_t, size_t)> progress, Ref<Metadata> 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<BinaryView> 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<FileMetadata> file = new FileMetadata(filename);
- view = file->OpenDatabaseForConfiguration(filename);
- isDatabase = true;
- }
- else
- {
- // Open file, read raw contents
- Ref<FileMetadata> 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<bool (*)(size_t, size_t)>(), options->m_object);
+ if (!handle)
return nullptr;
- return OpenView(view, updateAnalysis, progress, options, isDatabase);
+ return new BinaryView(handle);
}
-Ref<BinaryView> BinaryNinja::OpenView(const DataBuffer& rawData, bool updateAnalysis, std::function<bool(size_t, size_t)> progress, Json::Value options)
+Ref<BinaryView> BinaryNinja::Load(
+ const DataBuffer& rawData, bool updateAnalysis, std::function<bool(size_t, size_t)> progress, Ref<Metadata> options)
{
Ref<FileMetadata> file = new FileMetadata();
Ref<BinaryView> view = new BinaryData(file, rawData);
- return OpenView(view, updateAnalysis, progress, options, false);
+ return Load(view, updateAnalysis, progress, options, false);
}
-Ref<BinaryView> BinaryNinja::OpenView(Ref<BinaryView> view, bool updateAnalysis, std::function<bool(size_t, size_t)> progress, Json::Value options, bool isDatabase)
+Ref<BinaryView> BinaryNinja::Load(Ref<BinaryView> view, bool updateAnalysis,
+ std::function<bool(size_t, size_t)> progress, Ref<Metadata> options, bool isDatabase)
{
- Ref<BinaryViewType> bvt;
- Ref<BinaryViewType> 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<Settings> defaultSettings = Settings::Instance(bvt->GetName() + "_settings");
- defaultSettings->DeserializeSchema(Settings::Instance()->SerializeSchema());
- defaultSettings->SetResourceId(bvt->GetName());
-
- Ref<Settings> 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<std::string>("loader.universal.architectures");
-
- std::unique_ptr<Json::CharReader> 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<bool (*)(size_t, size_t)>(), 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<BinaryView> 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);
}
diff --git a/docs/dev/batch.md b/docs/dev/batch.md
index 8dbd908d..f6c2879a 100644
--- a/docs/dev/batch.md
+++ b/docs/dev/batch.md
@@ -28,7 +28,7 @@ Let's try a simple example script (note that this script will work identically o
```python
#!/usr/bin/env python3
import binaryninja
-with binaryninja.open_view("/bin/ls") as bv:
+with binaryninja.load("/bin/ls") as bv:
print(f"Opening {bv.file.filename} which has {len(list(bv.functions))} functions")
```
@@ -39,7 +39,7 @@ $ ./first.py
Opening /bin/ls which has 128 functions
```
-Note that we used the `open_view` method which lets you temporarily create a `bv` with the appropriate scope. The traditional way to do that was with `BinaryViewType.get_view_of_file` which returns a [BinaryView](https://api.binary.ninja/binaryninja.binaryview.BinaryView.html#binaryninja.binaryview.BinaryView) directly. Note however, that if you use that method you **MUST** close the BinaryView yourself when you are done with it. To do so, just:
+Note that we used the `load` method which lets you temporarily create a `bv` with the appropriate scope. If you don't use the `with` syntax, you **MUST** close the BinaryView yourself when you are done with it. To do so, just:
```python
bv.file.close() #close the file handle or else leak memory
@@ -51,10 +51,10 @@ Looks good! But what if we just want to parse basic headers or stop any major an
```python
#!/usr/bin/env python3
-from binaryninja import open_view
+from binaryninja import load
from glob import glob
for bin in glob("/bin/*"):
- with open_view(bin, update_analysis=False) as bv:
+ with load(bin, update_analysis=False) as bv:
print(f"Opening {bv.file.filename} which has {len(list(bv.functions))} functions")
```
@@ -77,8 +77,8 @@ Notice that we have far fewer functions in `/bin/ls` this time. By shortcutting
A common workflow is to analyze a single (or small number) of functions in a particular binaries. If we both the [maxFunctionSize](https://docs.binary.ninja/getting-started.html#analysis.limits.maxFunctionSize) setting in conjunction with the [analysis_skipped](https://api.binary.ninja/binaryninja.function-module.html#binaryninja.function.Function.analysis_skipped) function property we can select specific functions to analyze:
```python
-from binaryninja import open_view
-with open_view("/bin/ls", options={'analysis.limits.maxFunctionSize': 0}) as bv:
+from binaryninja import load
+with load("/bin/ls", options={'analysis.limits.maxFunctionSize': 0}) as bv:
fn = bv.entry_function
# Alternatively, use add_user_function at a particular address to first
# create the function
@@ -101,7 +101,7 @@ By default, logging will follow whatever the setting is for [minimum log level](
### Further Customization
-We can customize our analysis a lot more granularly than that though. `open_view` is actually a wrapper around [`get_view_of_file_with_options`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.binaryview.BinaryViewType.get_view_of_file_with_options). Notice the named `options` parameter, and the example code. Any setting you can set in the Binary Ninja "Open with Options" UI you can set through that parameter.
+We can customize our analysis a lot more granularly than that though. In [`load`](https://api.binary.ninja/binaryninja.binaryview-module.html#binaryninja.load), notice the named `options` parameter, and the example code. Any setting you can set in the Binary Ninja "Open with Options" UI you can set through that parameter.
## Parallelization
@@ -130,7 +130,7 @@ from multiprocessing import Pool, cpu_count, set_start_method
def spawn(filename):
binaryninja.set_worker_thread_count(1)
- with binaryninja.open_view(filename, update_analysis=False) as bv:
+ with binaryninja.load(filename, update_analysis=False) as bv:
print(f"Binary {bv.file.filename} has {len(list(bv.functions))} functions.")
if __name__ == '__main__':
diff --git a/enterprise.h b/enterprise.h
index b15dbba7..da609185 100644
--- a/enterprise.h
+++ b/enterprise.h
@@ -208,7 +208,7 @@ namespace BinaryNinja
assert(Enterprise::AuthenticateWithCredentials("username", "password", true));
{
Enterprise::LicenseCheckout _{};
- Ref<BinaryView> bv = OpenView("/bin/ls", true, {}, options);
+ Ref<BinaryView> bv = Load("/bin/ls", true, {}, options);
printf("%llx\n", bv->GetStart());
// License is released at end of scope
}
diff --git a/python/__init__.py b/python/__init__.py
index 40415e87..d1de2d91 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -287,7 +287,7 @@ def core_set_license(licenseData: str) -> None:
>>> import os
>>> core_set_license(os.environ['BNLICENSE']) #Do this before creating any BinaryViews
- >>> with open_view("/bin/ls") as bv:
+ >>> with load("/bin/ls") as bv:
... print(len(list(bv.functions)))
128
'''
@@ -307,7 +307,7 @@ def get_memory_usage_info() -> Mapping[str, int]:
def load(*args, **kwargs) -> BinaryView:
"""
- `load` is a convenience wrapper for :py:class:`BinaryViewType.load` that opens a BinaryView object.
+ Opens a BinaryView object.
:param Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike'] source: a file or byte stream to load into a virtual memory space
:param bool update_analysis: whether or not to run :func:`update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
@@ -331,38 +331,15 @@ def load(*args, **kwargs) -> BinaryView:
...
1
"""
- bv = BinaryViewType.load(*args, **kwargs)
+ bv = BinaryView.load(*args, **kwargs)
if bv is None:
raise Exception("Unable to create new BinaryView")
return bv
+@deprecation.deprecated(deprecated_in="3.5.4378", details='Use `load` instead')
def open_view(*args, **kwargs) -> BinaryView:
- """
- `open_view` is a convenience wrapper for :py:class:`get_view_of_file_with_options` that opens a BinaryView object.
-
- .. note:: If attempting to open a BNDB, the file MUST have the suffix .bndb, or else the file will not be loaded as a database.
-
- :param Union[str, 'os.PathLike'] filename: path to filename or bndb to open
- :param bool update_analysis: whether or not to run :func:`update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
- :param callback progress_func: optional function to be called with the current progress and total count
- :param dict options: a dictionary in the form {setting identifier string : object value}
- :return: returns a :py:class:`BinaryView` object for the given filename
- :rtype: :py:class:`BinaryView`
- :raises Exception: When a BinaryView could not be created
-
- :Example:
- >>> from binaryninja import *
- >>> with open_view("/bin/ls") as bv:
- ... print(len(list(bv.functions)))
- ...
- 128
-
- """
- bv = BinaryViewType.get_view_of_file_with_options(*args, **kwargs)
- if bv is None:
- raise Exception("Unable to create new BinaryView")
- return bv
+ return load(*args, **kwargs)
def connect_pycharm_debugger(port=5678):
diff --git a/python/binaryview.py b/python/binaryview.py
index 2735e882..cedb0160 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -947,287 +947,45 @@ class BinaryViewType(metaclass=_BinaryViewTypeMetaclass):
return None
return BinaryView(file_metadata=data.file, handle=view)
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
def open(self, src: PathType, file_metadata: 'filemetadata.FileMetadata' = None) -> Optional['BinaryView']:
- """
- ``open`` opens an instance of a particular BinaryViewType and returns it, or None if not possible.
-
- :param str src: path to filename or bndb to open
- :param FileMetadata file_metadata: Optional parameter for a :py:class:`~binaryninja.filemetadata.FileMetadata` object
- :return: returns a :py:class:`BinaryView` object for the given filename
- :rtype: :py:class:`BinaryView` or ``None``
- """
data = BinaryView.open(src, file_metadata)
if data is None:
return None
return self.create(data)
+ # TODO : Check if we need binary_view_type's at all after these deprecations? (move add_binaryview_finalized_event and add_binaryview_initial_analysis_completion_event to BinaryView?)
@classmethod
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
def get_view_of_file(
cls, filename: PathType, update_analysis: bool = True, progress_func: Optional[ProgressFuncType] = None
) -> Optional['BinaryView']:
- """
- ``get_view_of_file`` opens and returns the first available :py:class:`BinaryView`, excluding a Raw :py:class:`BinaryViewType` unless no other view is available
-
- .. warning:: The recommended code pattern for opening a BinaryView is to use the \
- :py:func:`~binaryninja.open_view` API as a context manager like ``with open_view('/bin/ls') as bv:`` \
- which will automatically clean up when done with the view. If using this API directly \
- you will need to call `bv.file.close()` before the BinaryView leaves scope to ensure the \
- reference is properly removed and prevents memory leaks.
-
- :param str filename: path to filename or bndb to open
- :param bool update_analysis: whether or not to run :py:func:`~BinaryView.update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
- :param callback progress_func: optional function to be called with the current progress and total count
- :return: returns a :py:class:`BinaryView` object for the given filename
- :rtype: :py:class:`BinaryView` or ``None``
- """
- sqlite = b"SQLite format 3"
- if not isinstance(filename, str):
- filename = str(filename)
-
- is_database = filename.endswith(".bndb")
- if is_database:
- f = open(filename, 'rb')
- if f is None or f.read(len(sqlite)) != sqlite:
- return None
- f.close()
- view = filemetadata.FileMetadata().open_existing_database(filename, progress_func)
- else:
- view = BinaryView.open(filename)
-
- if view is None:
- return None
- for available in view.available_view_types:
- if available.name != "Raw":
- if is_database:
- bv = view.get_view_of_type(available.name)
- else:
- bv = available.open(filename)
- break
- else:
- if is_database:
- bv = view.get_view_of_type("Raw")
- else:
- bv = cls["Raw"].open(filename) # type: ignore
-
- if bv is not None and update_analysis:
- bv.update_analysis_and_wait()
- return bv
+ return BinaryViewType.load(filename, update_analysis, progress_func)
@classmethod
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
def get_view_of_file_with_options(
cls, filename: Union[str, 'os.PathLike'], update_analysis: Optional[bool] = True, progress_func: Optional[ProgressFuncType] = None,
options: Mapping[str, Any] = {}
) -> Optional['BinaryView']:
- """
- ``get_view_of_file_with_options`` opens, generates default load options (which are overridable), and returns the first available \
- :py:class:`BinaryView`. If no :py:class:`BinaryViewType` is available, then a ``Mapped`` :py:class:`BinaryViewType` is used to load \
- the :py:class:`BinaryView` with the specified load options. The ``Mapped`` view type attempts to auto-detect the architecture of the \
- file during initialization. If no architecture is detected or specified in the load options, then the ``Mapped`` view type fails to \
- initialize and returns ``None``.
-
- .. note:: Calling this method without providing options is not necessarily equivalent to simply calling :py:func:`get_view_of_file`. This is because \
- a :py:class:`BinaryViewType` is in control of generating load options, this method allows an alternative default way to open a file. For \
- example, opening a relocatable object file with :py:func:`get_view_of_file` sets **'loader.imageBase'** to `0`, whereas enabling the **`'files.pic.autoRebase'`** \
- setting and opening with :py:func:`get_view_of_file_with_options` sets **'loader.imageBase'** to ``0x400000`` for 64-bit binaries, or ``0x10000`` for 32-bit binaries.
-
- .. note:: Although general container file support is not complete, support for Universal archives exists. It's possible to control the architecture preference \
- with the **'files.universal.architecturePreference'** setting. This setting is scoped to SettingsUserScope and can be modified as follows ::
-
- >>> Settings().set_string_list("files.universal.architecturePreference", ["arm64"])
-
- It's also possible to override the **'files.universal.architecturePreference'** user setting by specifying it directly with :py:func:`get_view_of_file_with_options`.
- This specific usage of this setting is experimental and may change in the future ::
-
- >>> bv = BinaryViewType.get_view_of_file_with_options('/bin/ls', options={'files.universal.architecturePreference': ['arm64']})
-
- .. warning:: The recommended code pattern for opening a BinaryView is to use the \
- :py:func:`~binaryninja.open_view` API as a context manager like ``with open_view('/bin/ls') as bv:`` \
- which will automatically clean up when done with the view. If using this API directly \
- you will need to call `bv.file.close()` before the BinaryView leaves scope to ensure the \
- reference is properly removed and prevents memory leaks.
-
- :param Union[str, 'os.PathLike'] filename: path to filename or bndb to open
- :param bool update_analysis: whether or not to run :py:func:`~BinaryView.update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
- :param callback progress_func: optional function to be called with the current progress and total count
- :param dict options: a dictionary in the form {setting identifier string : object value}
- :return: returns a :py:class:`BinaryView` object for the given filename or ``None``
- :rtype: :py:class:`BinaryView` or ``None``
-
- :Example:
-
- >>> BinaryViewType.get_view_of_file_with_options('/bin/ls', options={'loader.imageBase': 0xfffffff0000, 'loader.macho.processFunctionStarts' : False})
- <BinaryView: '/bin/ls', start 0xfffffff0000, len 0xa290>
- >>>
- """
return BinaryViewType.load(filename, update_analysis, progress_func, options)
@classmethod
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
def load_raw_view_with_options(
cls, raw_view: Optional['BinaryView'], update_analysis: Optional[bool] = True, progress_func: Optional[ProgressFuncType] = None,
options: Mapping[str, Any] = {}
) -> Optional['BinaryView']:
- """
- ``load_raw_view_with_options`` opens, generates default load options (which are overridable), and returns the first available \
- :py:class:`BinaryView`. If no :py:class:`BinaryViewType` is available, then a ``Mapped`` :py:class:`BinaryViewType` is used to load \
- the :py:class:`BinaryView` with the specified load options. The ``Mapped`` view type attempts to auto-detect the architecture of the \
- file during initialization. If no architecture is detected or specified in the load options, then the ``Mapped`` view type fails to \
- initialize and returns ``None``.
-
- .. note:: Calling this method without providing options is not necessarily equivalent to simply calling :py:func:`get_view_of_file`. This is because \
- a :py:class:`BinaryViewType` is in control of generating load options, this method allows an alternative default way to open a file. For \
- example, opening a relocatable object file with :py:func:`get_view_of_file` sets 'loader.imageBase' to `0`, whereas enabling the **'files.pic.autoRebase'** \
- setting and opening with :py:func:`load_raw_view_with_options` sets **'loader.imageBase'** to ``0x400000`` for 64-bit binaries, or ``0x10000`` for 32-bit binaries.
-
- .. note:: Although general container file support is not complete, support for Universal archives exists. It's possible to control the architecture preference \
- with the **'files.universal.architecturePreference'** setting. This setting is scoped to SettingsUserScope and can be modified as follows ::
-
- >>> Settings().set_string_list("files.universal.architecturePreference", ["arm64"])
-
- It's also possible to override the **'files.universal.architecturePreference'** user setting by specifying it directly with :py:func:`load_raw_view_with_options`.
- This specific usage of this setting is experimental and may change in the future ::
-
- >>> bv = BinaryViewType.load_raw_view_with_options('/bin/ls', options={'files.universal.architecturePreference': ['arm64']})
-
- .. warning:: The recommended code pattern for opening a BinaryView is to use the \
- :py:func:`~binaryninja.open_view` API as a context manager like ``with open_view('/bin/ls') as bv:`` \
- which will automatically clean up when done with the view. If using this API directly \
- you will need to call `bv.file.close()` before the BinaryView leaves scope to ensure the \
- reference is properly removed and prevents memory leaks.
-
- :param BinaryView raw_view: an existing 'Raw' BinaryView object
- :param bool update_analysis: whether or not to run :py:func:`~BinaryView.update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
- :param callback progress_func: optional function to be called with the current progress and total count
- :param dict options: a dictionary in the form {setting identifier string : object value}
- :return: returns a :py:class:`BinaryView` object for the given filename or ``None``
- :rtype: :py:class:`BinaryView` or ``None``
-
- :Example:
-
- >>> raw_view = BinaryView.open('/bin/ls')
- >>> BinaryViewType.load_raw_view_with_options(raw_view, options={'loader.imageBase': 0xfffffff0000, 'loader.macho.processFunctionStarts' : False})
- <BinaryView: '/bin/ls', start 0xfffffff0000, len 0xa290>
- >>>
- """
if raw_view is None:
return None
- elif raw_view.view_type != 'Raw':
- return None
- is_database = raw_view.file.has_database
- bvt = None
- universal_bvt = None
- for available in raw_view.available_view_types:
- if available.name == "Universal":
- universal_bvt = available
- continue
- if bvt is None and available.name not in ["Raw", "Debugger"]:
- bvt = available
-
- if bvt is None:
- bvt = cls["Mapped"] # type: ignore
-
- default_settings = settings.Settings(bvt.name + "_settings")
- default_settings.deserialize_schema(settings.Settings().serialize_schema())
- default_settings.set_resource_id(bvt.name)
-
- load_settings = None
- if is_database:
- load_settings = raw_view.get_load_settings(bvt.name)
- if options is None:
- options = {}
- if load_settings is None:
- if universal_bvt is not None and "files.universal.architecturePreference" in options:
- load_settings = universal_bvt.get_load_settings_for_data(raw_view)
- if load_settings is None:
- raise Exception(f"Could not load entry from Universal image. No load settings!")
- arch_list = json.loads(load_settings.get_string('loader.universal.architectures'))
- arch_entry = None
- for arch_pref in options['files.universal.architecturePreference']:
- arch_entry = [entry for entry in arch_list if entry['architecture'] == arch_pref]
- if arch_entry:
- break
- if not arch_entry:
- arch_names = [entry['architecture'] for entry in arch_list if entry['architecture']]
- raise Exception(
- f"Could not load any of: {options['files.universal.architecturePreference']} from Universal image. Entry not found! Available entries: {arch_names}"
- )
-
- load_settings = settings.Settings(core.BNGetUniqueIdentifierString())
- load_settings.deserialize_schema(arch_entry[0]['loadSchema'])
- else:
- load_settings = bvt.get_load_settings_for_data(raw_view)
- if load_settings is None:
- raise Exception(f"Could not get load settings for binary view of type '{bvt.name}'")
- load_settings.set_resource_id(bvt.name)
- raw_view.set_load_settings(bvt.name, load_settings)
-
- for key, value in options.items():
- if load_settings.contains(key):
- if not load_settings.set_json(key, json.dumps(value), raw_view):
- raise ValueError("Setting: {} set operation failed!".format(key))
- elif default_settings.contains(key):
- if not default_settings.set_json(key, json.dumps(value), raw_view):
- raise ValueError("Setting: {} set operation failed!".format(key))
- else:
- raise NotImplementedError("Setting: {} not available!".format(key))
-
- if is_database:
- view = raw_view.file.open_existing_database(raw_view.file.filename, progress_func)
- if view is None:
- raise Exception(f"Unable to open_existing_database with filename {raw_view.file.filename}")
- bv = view.get_view_of_type(bvt.name)
- else:
- bv = bvt.create(raw_view)
-
- if bv is None:
- return raw_view
- elif update_analysis:
- bv.update_analysis_and_wait()
- return bv
+ return BinaryViewType.load(raw_view, update_analysis, progress_func, options)
@classmethod
- def load(cls, source: Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike'], *args, **kwargs) -> Optional['BinaryView']:
- """
- `load` is a convenience wrapper for :py:func:`load_raw_view_with_options` that opens a BinaryView object.
-
- :param Union[str, bytes, bytearray, 'databuffer.DataBuffer', os.PathLike] source: a file or byte stream from which to load data into a virtual memory space
- :param bool update_analysis: whether or not to run :py:func:`~BinaryView.update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
- :param callback progress_func: optional function to be called with the current progress and total count
- :param dict options: a dictionary in the form {setting identifier string : object value}
- :return: returns a :py:class:`BinaryView` object for the given filename or ``None``
- :rtype: :py:class:`BinaryView` or ``None``
-
- .. note:: The progress_func callback **must** return True to continue the load operation, False will abort the load operation.
-
- :Example:
- >>> from binaryninja import *
- >>> with load("/bin/ls") as bv:
- ... print(len(list(bv.functions)))
- ...
- 134
-
- >>> with load(bytes.fromhex('5054ebfe'), options={'loader.architecture' : 'x86'}) as bv:
- ... print(len(list(bv.functions)))
- ...
- 1
- """
- if isinstance(source, os.PathLike):
- source = str(source)
- if isinstance(source, str):
- if source.endswith(".bndb"):
- sqlite = b"SQLite format 3"
- f = open(source, 'rb')
- if f is None or f.read(len(sqlite)) != sqlite:
- return None
- f.close()
- raw_view = filemetadata.FileMetadata(source).open_database_for_configuration(source)
- else:
- raw_view = BinaryView.open(source)
- elif isinstance(source, bytes) or isinstance(source, bytearray) or isinstance(source, databuffer.DataBuffer):
- raw_view = BinaryView.new(source)
- else:
- raise NotImplementedError
-
- return BinaryViewType.load_raw_view_with_options(raw_view, *args, **kwargs)
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
+ def load(
+ cls, source: Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike', 'BinaryView'], update_analysis: Optional[bool] = True,
+ progress_func: Optional[ProgressFuncType] = None, options: Mapping[str, Any] = {}) -> Optional['BinaryView']:
+ BinaryView.load(source, update_analysis, progress_func, options)
def parse(self, data: 'BinaryView') -> Optional['BinaryView']:
view = core.BNParseBinaryViewOfType(self.handle, data.handle)
@@ -1238,6 +996,7 @@ class BinaryViewType(metaclass=_BinaryViewTypeMetaclass):
def is_valid_for_data(self, data: 'BinaryView') -> bool:
return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle)
+ @deprecation.deprecated(deprecated_in="3.5.4378")
def get_default_load_settings_for_data(self, data: 'BinaryView') -> Optional['settings.Settings']:
load_settings = core.BNGetBinaryViewDefaultLoadSettingsForData(self.handle, data.handle)
if load_settings is None:
@@ -1968,7 +1727,7 @@ class BinaryView:
To open a file with a given BinaryView the following code is recommended:
- >>> with open_view("/bin/ls") as bv:
+ >>> with load("/bin/ls") as bv:
... bv
<BinaryView: '/bin/ls', start 0x100000000, len 0x142c8>
@@ -2278,6 +2037,7 @@ class BinaryView:
return None
@staticmethod
+ @deprecation.deprecated(deprecated_in="3.5.4378", details="Use `binaryninja.load` instead")
def open(src, file_metadata=None) -> Optional['BinaryView']:
binaryninja._init_plugins()
if isinstance(src, fileaccessor.FileAccessor):
@@ -2294,6 +2054,21 @@ class BinaryView:
@staticmethod
def new(data: Optional[Union[bytes, bytearray, 'databuffer.DataBuffer']] = None, file_metadata: Optional['filemetadata.FileMetadata'] = None) -> Optional['BinaryView']:
+ """
+ ``new`` creates a new, Raw :py:class:`BinaryView` for the provided data.
+
+ :param Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike', 'BinaryView'] data: path to file/bndb, raw bytes, or raw view to load
+ :param :py:class:`~binaryninja.filemetadata.FileMetadata` file_metadata: Optional FileMetadata object for this new view
+ :return: returns a :py:class:`BinaryView` object for the given filename or ``None``
+ :rtype: :py:class:`BinaryView` or ``None``
+
+ :Example:
+
+ >>> binaryninja.load('/bin/ls', options={'loader.imageBase': 0xfffffff0000, 'loader.macho.processFunctionStarts' : False})
+ <BinaryView: '/bin/ls', start 0xfffffff0000, len 0xa290>
+ >>>
+ """
+
binaryninja._init_plugins()
if file_metadata is None:
file_metadata = filemetadata.FileMetadata()
@@ -2308,6 +2083,65 @@ class BinaryView:
return None
return BinaryView(file_metadata=file_metadata, handle=view)
+ @staticmethod
+ def load(source: Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike', 'BinaryView'], update_analysis: Optional[bool] = True,
+ progress_func: Optional[ProgressFuncType] = None, options: Mapping[str, Any] = {}) -> Optional['BinaryView']:
+ """
+ ``load`` opens, generates default load options (which are overridable), and returns the first available \
+ :py:class:`BinaryView`. If no :py:class:`BinaryViewType` is available, then a ``Mapped`` :py:class:`BinaryViewType` is used to load \
+ the :py:class:`BinaryView` with the specified load options. The ``Mapped`` view type attempts to auto-detect the architecture of the \
+ file during initialization. If no architecture is detected or specified in the load options, then the ``Mapped`` view type fails to \
+ initialize and returns ``None``.
+
+ .. note:: Although general container file support is not complete, support for Universal archives exists. It's possible to control the architecture preference \
+ with the **'files.universal.architecturePreference'** setting. This setting is scoped to SettingsUserScope and can be modified as follows ::
+
+ >>> Settings().set_string_list("files.universal.architecturePreference", ["arm64"])
+
+ It's also possible to override the **'files.universal.architecturePreference'** user setting by specifying it directly with :py:func:`load`.
+ This specific usage of this setting is experimental and may change in the future ::
+
+ >>> bv = binaryninja.load('/bin/ls', options={'files.universal.architecturePreference': ['arm64']})
+
+ .. warning:: The recommended code pattern for opening a BinaryView is to use the \
+ :py:func:`~binaryninja.load` API as a context manager like ``with load('/bin/ls') as bv:`` \
+ which will automatically clean up when done with the view. If using this API directly \
+ you will need to call `bv.file.close()` before the BinaryView leaves scope to ensure the \
+ reference is properly removed and prevents memory leaks.
+
+ :param Union[str, bytes, bytearray, 'databuffer.DataBuffer', 'os.PathLike', 'BinaryView'] source: path to file/bndb, raw bytes, or raw view to load
+ :param bool update_analysis: whether or not to run :py:func:`~BinaryView.update_analysis_and_wait` after opening a :py:class:`BinaryView`, defaults to ``True``
+ :param callback progress_func: optional function to be called with the current progress and total count
+ :param dict options: a dictionary in the form {setting identifier string : object value}
+ :return: returns a :py:class:`BinaryView` object for the given filename or ``None``
+ :rtype: :py:class:`BinaryView` or ``None``
+
+ :Example:
+
+ >>> binaryninja.load('/bin/ls', options={'loader.imageBase': 0xfffffff0000, 'loader.macho.processFunctionStarts' : False})
+ <BinaryView: '/bin/ls', start 0xfffffff0000, len 0xa290>
+ >>>
+ """
+ binaryninja._init_plugins()
+
+ if progress_func is None:
+ progress_cfunc = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_ulonglong, ctypes.c_ulonglong)(lambda cur, total: True)
+ else:
+ progress_cfunc = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_ulonglong, ctypes.c_ulonglong)(lambda cur, total: progress_func(cur, total))
+
+ if isinstance(source, os.PathLike):
+ source = str(source)
+ if isinstance(source, BinaryView):
+ handle = core.BNLoadBinaryView(source.handle, update_analysis, progress_cfunc, metadata.Metadata(options).handle, source.file.has_database)
+ elif isinstance(source, str):
+ handle = core.BNLoadFilename(source, update_analysis, progress_cfunc, metadata.Metadata(options).handle)
+ elif isinstance(source, bytes) or isinstance(source, bytearray) or isinstance(source, databuffer.DataBuffer):
+ raw_view = BinaryView.new(source)
+ handle = core.BNLoadBinaryView(raw_view.handle, update_analysis, progress_cfunc, metadata.Metadata(options).handle)
+ else:
+ raise NotImplementedError
+ return BinaryView(handle=handle)
+
@classmethod
def _unregister(cls, view: core.BNBinaryView) -> None:
handle = ctypes.cast(view, ctypes.c_void_p)
@@ -3583,7 +3417,7 @@ class BinaryView:
:Example:
>>> #Opening a x86_64 Mach-O binary
- >>> bv = BinaryViewType['Raw'].open("/bin/ls") #note that we are using open instead of get_view_of_file to get the raw view
+ >>> bv = BinaryView.new("/bin/ls") # note that we are using `new` instead of `load` to get the raw view
>>> bv.read(0,4)
b\'\\xcf\\xfa\\xed\\xfe\'
"""
@@ -8246,7 +8080,7 @@ class BinaryReader:
BinaryReader can be instantiated as follows and the rest of the document will start from this context ::
>>> from binaryninja import *
- >>> bv = BinaryViewType.get_view_of_file("/bin/ls")
+ >>> bv = load("/bin/ls")
>>> br = BinaryReader(bv)
>>> hex(br.read32())
'0xfeedfacfL'
@@ -8630,7 +8464,7 @@ class BinaryWriter:
BinaryWriter can be instantiated as follows and the rest of the document will start from this context ::
>>> from binaryninja import *
- >>> bv = BinaryViewType.get_view_of_file("/bin/ls")
+ >>> bv = load("/bin/ls")
>>> br = BinaryReader(bv)
>>> br.offset
4294967296
@@ -8640,7 +8474,7 @@ class BinaryWriter:
Or using the optional endian parameter ::
>>> from binaryninja import *
- >>> bv = BinaryViewType.get_view_of_file("/bin/ls")
+ >>> bv = load("/bin/ls")
>>> br = BinaryReader(bv, Endianness.BigEndian)
>>> bw = BinaryWriter(bv, Endianness.BigEndian)
>>>
@@ -8984,7 +8818,7 @@ class StructuredDataView(object):
StructuredDataView can be instantiated as follows::
>>> from binaryninja import *
- >>> bv = BinaryViewType.get_view_of_file("/bin/ls")
+ >>> bv = load("/bin/ls")
>>> structure = "Elf64_Header"
>>> address = bv.start
>>> elf = StructuredDataView(bv, structure, address)
diff --git a/python/enterprise.py b/python/enterprise.py
index 915f6c30..d398bdf9 100644
--- a/python/enterprise.py
+++ b/python/enterprise.py
@@ -325,7 +325,7 @@ class LicenseCheckout:
>>> enterprise.authenticate_with_credentials("username", "password")
>>> with enterprise.LicenseCheckout():
... # Do some operation
- ... with open_view("/bin/ls") as bv: # e.g.
+ ... with load("/bin/ls") as bv: # e.g.
... print(hex(bv.start))
# License is released at end of scope
"""
diff --git a/python/examples/bin_info.py b/python/examples/bin_info.py
index 8d43a999..8aaf2a38 100644
--- a/python/examples/bin_info.py
+++ b/python/examples/bin_info.py
@@ -23,10 +23,9 @@ import sys
import os
from binaryninja.log import log_warn, log_to_stdout
-from binaryninja.binaryview import BinaryViewType
import binaryninja.interaction as interaction
from binaryninja.plugin import PluginCommand
-from binaryninja import Settings
+from binaryninja import load
def get_bininfo(bv):
@@ -40,7 +39,7 @@ def get_bininfo(bv):
log_warn("No file specified")
sys.exit(1)
- bv = BinaryViewType.get_view_of_file(filename)
+ bv = load(filename)
log_to_stdout(True)
contents = "## %s ##\n" % os.path.basename(bv.file.filename)
diff --git a/python/examples/debug_info.py b/python/examples/debug_info.py
index a060e465..4f4328d3 100755
--- a/python/examples/debug_info.py
+++ b/python/examples/debug_info.py
@@ -222,7 +222,7 @@ for p in bn.debuginfo.DebugInfoParser:
print(f" {bn.debuginfo.DebugInfoParser[p.name].name}")
# Test calling our `is_valid` callback
-bv = bn.open_view(filename, options={"analysis.debugInfo.internal": False})
+bv = bn.load(filename, options={"analysis.debugInfo.internal": False})
if parser.is_valid_for_view(bv):
print("Parser is valid")
else:
diff --git a/python/examples/feature_map.py b/python/examples/feature_map.py
index 9884b510..e12508af 100644
--- a/python/examples/feature_map.py
+++ b/python/examples/feature_map.py
@@ -18,7 +18,7 @@ FeatureMapImportColor = (237, 189, 129)
FeatureMapExternColor = (237, 189, 129)
FeatureMapLibraryColor = (237, 189, 129)
-bv = binaryninja.open_view(sys.argv[1], update_analysis=True)
+bv = binaryninja.load(sys.argv[1], update_analysis=True)
imgdata = [FeatureMapBaseColor]*(WIDTH*HEIGHT)
diff --git a/python/examples/instruction_iterator.py b/python/examples/instruction_iterator.py
index 741f03c4..62329f02 100644
--- a/python/examples/instruction_iterator.py
+++ b/python/examples/instruction_iterator.py
@@ -21,7 +21,7 @@
import sys
from binaryninja.log import log_info, log_to_stdout
-from binaryninja import open_view, BinaryView
+from binaryninja import load, BinaryView
from binaryninja import PluginCommand, LogLevel
@@ -53,7 +53,7 @@ if __name__ == "__main__":
if len(sys.argv) > 1:
target = sys.argv[1]
log_to_stdout(LogLevel.WarningLog)
- with open_view(target) as bv:
+ with load(target) as bv:
log_to_stdout(LogLevel.InfoLog)
iterate(bv)
else:
diff --git a/python/examples/mappedview.py b/python/examples/mappedview.py
index 0fbf159c..30c0edfd 100644
--- a/python/examples/mappedview.py
+++ b/python/examples/mappedview.py
@@ -97,7 +97,7 @@ class MappedView(BinaryView):
def init(self):
# The BinaryView init method is invoked as part of the BinaryView creation process. This method is called under several different conditions:
# 1) When opening a file/bndb and no load options are provided.
- # 2) When opening a file/bndb and load options are provided. e.g. 'Open with Options' in the UI, or get_view_of_file_with_options
+ # 2) When opening a file/bndb and load options are provided. e.g. 'Open with Options' in the UI, or load
# 3) When parsing a file to create an ephemeral BinaryView (self.parse_only == True) for the purpose of extracting header information.
# Note: The get_load_settings_for_data classmethod is optional. If provided, it's used to generate load options for the BinaryViewType.
# If not provided, then the default load options are automatically generated by the core, extracting information automatically from a parsed BinaryView.
diff --git a/python/examples/pe_stat.py b/python/examples/pe_stat.py
index 08dd43e0..bc3a3992 100755
--- a/python/examples/pe_stat.py
+++ b/python/examples/pe_stat.py
@@ -31,7 +31,7 @@ opc2count = defaultdict(lambda: 0)
target = sys.argv[1]
print('opening %s' % target)
-bv = binaryninja.BinaryViewType.get_view_of_file(target)
+bv = binaryninja.load(target)
print('analyzing')
bv.update_analysis_and_wait()
diff --git a/python/examples/print_syscalls.py b/python/examples/print_syscalls.py
index a16cd8f9..7f10fdd0 100644
--- a/python/examples/print_syscalls.py
+++ b/python/examples/print_syscalls.py
@@ -25,13 +25,13 @@
import sys
from itertools import chain
-from binaryninja.binaryview import BinaryViewType
+from binaryninja import load
from binaryninja.enums import LowLevelILOperation
def print_syscalls(fileName):
""" Print Syscall numbers for a provided file """
- bv = BinaryViewType.get_view_of_file(fileName)
+ bv = load(fileName)
calling_convention = bv.platform.system_call_convention
if calling_convention is None:
print('Error: No syscall convention available for {:s}'.format(bv.platform))
diff --git a/python/filemetadata.py b/python/filemetadata.py
index f0d9391f..873c36d1 100644
--- a/python/filemetadata.py
+++ b/python/filemetadata.py
@@ -30,6 +30,7 @@ from . import associateddatastore #required for _FileMetadataAssociatedDataStor
from .log import log_error
from . import binaryview
from . import database
+from . import deprecation
ProgressFuncType = Callable[[int, int], bool]
ViewName = str
@@ -525,6 +526,8 @@ class FileMetadata:
ctypes.c_ulonglong)(lambda ctxt, cur, total: _progress_func(cur, total)), _settings
)
+ # TODO : When this is removed, you can probably remove `BNOpenExistingDatabase` and `BNOpenExistingDatabaseWithProgress` too
+ @deprecation.deprecated(deprecated_in="3.5.4378")
def open_existing_database(self, filename: str, progress_func: Optional[Callable[[int, int], bool]] = None):
if progress_func is None:
view = core.BNOpenExistingDatabase(self.handle, str(filename))
@@ -538,6 +541,8 @@ class FileMetadata:
return None
return binaryview.BinaryView(file_metadata=self, handle=view)
+ # TODO : When this is removed, you can probably remove `BNOpenDatabaseForConfiguration` too
+ @deprecation.deprecated(deprecated_in="3.5.4378")
def open_database_for_configuration(self, filename: str) -> Optional['binaryview.BinaryView']:
view = core.BNOpenDatabaseForConfiguration(self.handle, str(filename))
if view is None:
diff --git a/python/function.py b/python/function.py
index 97655e41..5df6f62a 100644
--- a/python/function.py
+++ b/python/function.py
@@ -337,7 +337,7 @@ class Function:
The examples in the following code will use the following variables
>>> from binaryninja import *
- >>> bv = binaryninja.binaryview.BinaryViewType.get_view_of_file("/bin/ls")
+ >>> bv = load("/bin/ls")
>>> current_function = bv.functions[0]
>>> here = current_function.start
"""
diff --git a/python/settings.py b/python/settings.py
index 03f55845..fee8a755 100644
--- a/python/settings.py
+++ b/python/settings.py
@@ -97,7 +97,7 @@ class Settings:
True
>>> my_settings.register_setting("myPlugin.enablePreAnalysis", properties)
True
- >>> my_bv = open_view("/bin/ls", options={'myPlugin.enablePreAnalysis' : True})
+ >>> my_bv = load("/bin/ls", options={'myPlugin.enablePreAnalysis' : True})
>>> Settings().get_bool("myPlugin.enablePreAnalysis")
False
>>> Settings().get_bool("myPlugin.enablePreAnalysis", my_bv)
@@ -113,7 +113,7 @@ class Settings:
True
>>> my_settings.register_setting("myPlugin.enableTableView", properties)
True
- >>> my_bv = open_view("/bin/ls", options={'myPlugin.enableTableView' : True})
+ >>> my_bv = load("/bin/ls", options={'myPlugin.enableTableView' : True})
>>> Settings().get_bool("myPlugin.enableTableView")
True
diff --git a/rust/examples/basic_script/src/main.rs b/rust/examples/basic_script/src/main.rs
index e535f15f..85187747 100644
--- a/rust/examples/basic_script/src/main.rs
+++ b/rust/examples/basic_script/src/main.rs
@@ -6,7 +6,7 @@ fn main() {
binaryninja::headless::init();
println!("Loading binary...");
- let bv = binaryninja::open_view("/bin/cat").expect("Couldn't open `/bin/cat`");
+ let bv = binaryninja::load("/bin/cat").expect("Couldn't open `/bin/cat`");
println!("Filename: `{}`", bv.file().filename());
println!("File size: `{:#x}`", bv.len());
diff --git a/rust/examples/decompile/src/main.rs b/rust/examples/decompile/src/main.rs
index acd3e28b..0865538d 100644
--- a/rust/examples/decompile/src/main.rs
+++ b/rust/examples/decompile/src/main.rs
@@ -40,7 +40,7 @@ fn main() {
binaryninja::headless::init();
eprintln!("Loading binary...");
- let bv = binaryninja::open_view(args.filename).expect("Couldn't open file");
+ let bv = binaryninja::load(args.filename).expect("Couldn't open file");
eprintln!("Filename: `{}`", bv.file().filename());
eprintln!("File size: `{:#x}`", bv.len());
diff --git a/rust/examples/template/src/main.rs b/rust/examples/template/src/main.rs
index 0c27b6d2..20e082f2 100644
--- a/rust/examples/template/src/main.rs
+++ b/rust/examples/template/src/main.rs
@@ -11,7 +11,7 @@ fn main() {
// Your code here...
println!("Loading binary...");
- let bv = binaryninja::open_view("/bin/cat").expect("Couldn't open `/bin/cat`");
+ let bv = binaryninja::load("/bin/cat").expect("Couldn't open `/bin/cat`");
println!("Filename: `{}`", bv.file().filename());
println!("File size: `{:#x}`", bv.len());
diff --git a/rust/src/headless.rs b/rust/src/headless.rs
index c54e3ec9..0ce24cb3 100644
--- a/rust/src/headless.rs
+++ b/rust/src/headless.rs
@@ -90,7 +90,7 @@ pub fn shutdown() {
/// Prelued-postlued helper function (calls [`init`] and [`shutdown`] for you)
/// ```rust
/// binaryninja::headless::script_helper(|| {
-/// binaryninja::open_view("/bin/cat")
+/// binaryninja::load("/bin/cat")
/// .expect("Couldn't open `/bin/cat`")
/// .iter()
/// .for_each(|func| println!(" `{}`", func.symbol().full_name()));
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 06591236..f5d96592 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -80,7 +80,7 @@
//! binaryninja::headless::init();
//!
//! println!("Loading binary...");
-//! let bv = binaryninja::open_view("/bin/cat").expect("Couldn't open `/bin/cat`");
+//! let bv = binaryninja::load("/bin/cat").expect("Couldn't open `/bin/cat`");
//!
//! // Your code here...
//!
@@ -164,13 +164,15 @@ pub mod symbol;
pub mod tags;
pub mod types;
-use std::collections::HashMap;
-use std::fs::File;
-use std::io::Read;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
+use std::ptr::null_mut;
pub use binaryninjacore_sys::BNBranchType as BranchType;
pub use binaryninjacore_sys::BNEndianness as Endianness;
+use binaryview::BinaryView;
+use metadata::Metadata;
+use rc::Ref;
+use string::BnStrCompatible;
// Commented out to suppress unused warnings
// const BN_MAX_INSTRUCTION_LENGTH: u64 = 256;
@@ -192,198 +194,56 @@ pub use binaryninjacore_sys::BNEndianness as Endianness;
const BN_FULL_CONFIDENCE: u8 = 255;
const BN_INVALID_EXPR: usize = usize::MAX;
-fn open_binary_file(
- metadata: &mut filemetadata::FileMetadata,
- is_bndb: bool,
- with_options: bool,
-) -> Result<rc::Ref<binaryview::BinaryView>, String> {
- let filename = metadata.filename();
- let path = Path::new(filename.as_str());
- if is_bndb {
- let mut file = File::open(path).map_err(|_| "Could not open file".to_string())?;
- let mut buf = [0; 15];
- file.read_exact(&mut buf)
- .map_err(|_| "Not a valid BNDB (too small)".to_string())?;
+pub fn load<S: BnStrCompatible>(filename: S) -> Option<rc::Ref<binaryview::BinaryView>> {
+ let filename = filename.into_bytes_with_nul();
- if buf.as_slice() != b"SQLite format 3" {
- return Err("Not a valid BNDB (invalid magic)".to_string());
- }
- if with_options {
- metadata.open_database_for_configuration(filename)
- } else {
- metadata.open_database(filename)
- }
- } else {
- binaryview::BinaryView::from_filename(metadata, filename)
- }
- .map_err(|_| "Unable to open file".to_string())
-}
-
-pub fn open_view<F: AsRef<Path>>(filename: F) -> Result<rc::Ref<binaryview::BinaryView>, String> {
- use crate::binaryview::BinaryViewExt;
- use crate::custombinaryview::BinaryViewTypeExt;
-
- let filename = filename.as_ref();
- let is_bndb = filename.extension().map_or(false, |ext| ext == "bndb");
-
- let mut metadata = filemetadata::FileMetadata::with_filename(filename.to_str().unwrap());
-
- let view = open_binary_file(&mut metadata, is_bndb, false)?;
- let bv = custombinaryview::BinaryViewType::list_valid_types_for(&view)
- .iter()
- .find_map(|available_view| {
- if available_view.name().as_str() == "Raw" {
- None
- } else if is_bndb {
- match view.file().get_view_of_type(available_view.name()) {
- Ok(view) => Some(view),
- _ => None,
- }
- } else {
- // TODO : add log prints
- println!("Opening view of type: `{}`", available_view.name());
- match available_view.open(&view) {
- Ok(view) => Some(view),
- _ => None,
- }
- }
- });
-
- let bv = match bv {
- Some(bv) => bv,
- None => {
- if is_bndb {
- view.file()
- .get_view_of_type("Raw")
- .map_err(|_| "Could not get raw view from bndb".to_string())?
- } else {
- custombinaryview::BinaryViewType::by_name("Raw")
- .unwrap()
- .open(&view)
- .map_err(|_| "Could not open raw view".to_string())?
- }
- }
+ let handle = unsafe {
+ binaryninjacore_sys::BNLoadFilename(
+ filename.as_ref().as_ptr() as *mut _,
+ true,
+ None,
+ null_mut() as *mut _,
+ )
};
- bv.update_analysis_and_wait();
- Ok(bv)
+ if handle.is_null() {
+ None
+ } else {
+ Some(unsafe { BinaryView::from_raw(handle) })
+ }
}
-/// This is incomplete, but should work in most cases:
/// ```rust
-/// let settings = [("analysis.linearSweep.autorun", "false")]
-/// .iter()
-/// .cloned()
-/// .collect();
+/// let settings = [("analysis.linearSweep.autorun", false)].into();
///
-/// let bv = binaryninja::open_view_with_options("/bin/cat", true, Some(settings))
+/// let bv = binaryninja::load_with_options("/bin/cat", true, Some(settings))
/// .expect("Couldn't open `/bin/cat`");
/// ```
-pub fn open_view_with_options<F: AsRef<Path>>(
- filename: F,
+pub fn load_with_options<S: BnStrCompatible>(
+ filename: S,
update_analysis_and_wait: bool,
- options: Option<HashMap<&str, &str>>,
-) -> Result<rc::Ref<binaryview::BinaryView>, String> {
- use crate::binaryview::BinaryViewExt;
- use crate::custombinaryview::{BinaryViewTypeBase, BinaryViewTypeExt};
-
- let filename = filename.as_ref();
- let is_bndb = filename.extension().map_or(false, |ext| ext == "bndb");
-
- let mut metadata = filemetadata::FileMetadata::with_filename(filename.to_str().unwrap());
+ options: Option<Ref<Metadata>>,
+) -> Option<rc::Ref<binaryview::BinaryView>> {
+ let filename = filename.into_bytes_with_nul();
- let view = open_binary_file(&mut metadata, is_bndb, true)?;
- let mut universal_view_type = None;
- let mut view_type = None;
- for available_view in custombinaryview::BinaryViewType::list_valid_types_for(&view).iter() {
- if available_view.name().as_ref() == b"Universal" {
- universal_view_type = Some(available_view);
- } else if view_type.is_none() && available_view.name().as_ref() != b"Raw" {
- view_type = Some(available_view);
- }
- }
-
- let view_type =
- view_type.unwrap_or_else(|| custombinaryview::BinaryViewType::by_name("Mapped").unwrap());
-
- let setting_id = format!("{}{}", view_type.name(), "_settings");
- let default_settings = settings::Settings::new(setting_id);
- default_settings.deserialize_schema(settings::Settings::new("").serialize_schema());
- default_settings.set_resource_id(view_type.name());
-
- let load_settings = match (is_bndb, view.load_settings(view_type.name())) {
- (true, Ok(settings)) => settings,
- _ => {
- if let (Some(universal_view_type), Some(options)) = (universal_view_type, &options) {
- if options.contains_key("files.universal.architecturePreference") {
- universal_view_type
- .load_settings_for_data(view.as_ref())
- .map_err(|_| {
- "Could not load settings for universal view_data".to_string()
- })?
-
- // let arch_list =
- // settings.get_string("loader.universal.architectures", None, None);
-
- // TODO : Need json support
- // let arch_list = arch_list.as_str();
- // let arch_list = arch_list[1..arch_list.len()].split("'");
- // arch_entry = [entry for entry in arch_list if entry['architecture'] == options['files.universal.architecturePreference'][0]]
- // if not arch_entry:
- // log.log_error(f"Could not load {options['files.universal.architecturePreference'][0]} from Universal image. Entry not found!")
- // return None
-
- // let settings = settings::Settings::new(BNGetUniqueIdentifierString());
- // settings.deserialize_schema(arch_entry[0]['loadSchema']);
- } else {
- match view_type.load_settings_for_data(view.as_ref()) {
- Ok(settings) => settings,
- _ => return Ok(view),
- }
- }
+ let handle = unsafe {
+ binaryninjacore_sys::BNLoadFilename(
+ filename.as_ref().as_ptr() as *mut _,
+ update_analysis_and_wait,
+ None,
+ if let Some(options) = options {
+ options.as_ref().handle
} else {
- match view_type.load_settings_for_data(view.as_ref()) {
- Ok(settings) => settings,
- _ => return Ok(view),
- }
- }
- }
+ null_mut() as *mut _
+ },
+ )
};
- load_settings.set_resource_id(view_type.name());
- view.set_load_settings(view_type.name(), load_settings.as_ref());
-
- if let Some(options) = options {
- for (setting, value) in options {
- if load_settings.contains(setting) {
- if !load_settings.set_json(setting, value, Some(view.as_ref()), None) {
- return Err(format!("Setting: {} set operation failed!", setting));
- }
- } else if default_settings.contains(setting) {
- if !default_settings.set_json(setting, value, Some(view.as_ref()), None) {
- return Err(format!("Setting: {} set operation failed!", setting));
- }
- } else {
- return Err(format!("Setting: {} not available!", setting));
- }
- }
- }
-
- let bv = if is_bndb {
- let view = view
- .file()
- .open_database(metadata.filename())
- .expect("Couldn't open database");
- let view_type_name = view_type.name();
- view.file().get_view_of_type(view_type_name).unwrap_or(view)
+ if handle.is_null() {
+ None
} else {
- view_type.open(&view).unwrap_or(view)
- };
-
- if update_analysis_and_wait {
- bv.update_analysis_and_wait();
+ Some(unsafe { BinaryView::from_raw(handle) })
}
- Ok(bv)
}
pub fn install_directory() -> Result<PathBuf, ()> {
diff --git a/rust/src/metadata.rs b/rust/src/metadata.rs
index 09c21ec9..1ea8225d 100644
--- a/rust/src/metadata.rs
+++ b/rust/src/metadata.rs
@@ -379,16 +379,32 @@ impl From<f64> for Ref<Metadata> {
}
}
-impl<S: BnStrCompatible> From<S> for Ref<Metadata> {
- fn from(value: S) -> Self {
+impl From<String> for Ref<Metadata> {
+ fn from(value: String) -> Self {
unsafe {
Metadata::ref_from_raw(BNCreateMetadataStringData(
- value.into_bytes_with_nul().as_ref().as_ptr() as *const c_char,
+ value.into_bytes_with_nul().as_ptr() as *const c_char,
))
}
}
}
+impl From<&str> for Ref<Metadata> {
+ fn from(value: &str) -> Self {
+ unsafe {
+ Metadata::ref_from_raw(BNCreateMetadataStringData(
+ value.into_bytes_with_nul().as_ptr() as *const c_char,
+ ))
+ }
+ }
+}
+
+impl<T: Into<Ref<Metadata>>> From<&T> for Ref<Metadata> {
+ fn from(value: &T) -> Self {
+ value.into()
+ }
+}
+
impl From<&Vec<u8>> for Ref<Metadata> {
fn from(value: &Vec<u8>) -> Self {
unsafe { Metadata::ref_from_raw(BNCreateMetadataRawData(value.as_ptr(), value.len())) }
@@ -442,6 +458,56 @@ impl<S: BnStrCompatible> From<HashMap<S, Ref<Metadata>>> for Ref<Metadata> {
}
}
+impl<S: BnStrCompatible + Copy, T: Into<Ref<Metadata>>> From<&[(S, T)]> for Ref<Metadata> {
+ fn from(value: &[(S, T)]) -> Self {
+ let mut key_refs: Vec<S::Result> = vec![];
+ let mut keys: Vec<*const c_char> = vec![];
+ let mut values: Vec<*mut BNMetadata> = vec![];
+ for (k, v) in value.iter() {
+ key_refs.push(k.into_bytes_with_nul());
+ let value_metadata: Ref<Metadata> = v.into();
+ values.push(value_metadata.handle);
+ }
+ for k in &key_refs {
+ keys.push(k.as_ref().as_ptr() as *const c_char);
+ }
+
+ unsafe {
+ Metadata::ref_from_raw(BNCreateMetadataValueStore(
+ keys.as_mut_ptr(),
+ values.as_mut_ptr(),
+ keys.len(),
+ ))
+ }
+ }
+}
+
+impl<S: BnStrCompatible + Copy, T: Into<Ref<Metadata>>, const N: usize> From<[(S, T); N]>
+ for Ref<Metadata>
+{
+ fn from(value: [(S, T); N]) -> Self {
+ let mut key_refs: Vec<S::Result> = vec![];
+ let mut keys: Vec<*const c_char> = vec![];
+ let mut values: Vec<*mut BNMetadata> = vec![];
+ for (k, v) in value.into_iter() {
+ key_refs.push(k.into_bytes_with_nul());
+ let value_metadata: Ref<Metadata> = v.into();
+ values.push(value_metadata.handle);
+ }
+ for k in &key_refs {
+ keys.push(k.as_ref().as_ptr() as *const c_char);
+ }
+
+ unsafe {
+ Metadata::ref_from_raw(BNCreateMetadataValueStore(
+ keys.as_mut_ptr(),
+ values.as_mut_ptr(),
+ keys.len(),
+ ))
+ }
+ }
+}
+
impl From<&Vec<bool>> for Ref<Metadata> {
fn from(value: &Vec<bool>) -> Self {
unsafe {
diff --git a/suite/api_test.py b/suite/api_test.py
index 0d32584b..ec63cfb0 100644
--- a/suite/api_test.py
+++ b/suite/api_test.py
@@ -60,7 +60,7 @@ class FileApparatus:
class Apparatus:
def __init__(self, filename):
with FileApparatus(filename) as path:
- bv = BinaryViewType.get_view_of_file(os.path.relpath(path))
+ bv = bn.load(os.path.relpath(path))
assert bv is not None
self.bv = bv
@@ -3092,7 +3092,7 @@ class TestBinaryViewType(unittest.TestCase):
assert bvt2.get_arch(3, Endianness.LittleEndian) == Architecture["x86"]
assert bvt2.get_platform(0, Architecture["x86"]) == Platform["linux-x86"]
with FileApparatus("helloworld") as filename:
- with BinaryViewType.get_view_of_file(filename) as bv:
+ with bn.load(filename) as bv:
assert bvt2.is_valid_for_data(bv.parent_view)
assert isinstance(bvt2.parse(bv.parent_view), BinaryView)
@@ -3523,7 +3523,7 @@ class LowLevelILTests(TestWithBinaryView):
# class TestObjectiveCPlugin(unittest.TestCase):
# def setUp(self):
# with FileApparatus("calculator_macOS12_arm64e") as path:
-# bv = BinaryViewType.get_view_of_file_with_options(
+# bv = load(
# os.path.relpath(path),
# options={"workflows.enable": True, "workflows.functionWorkflow": "core.function.objectiveC"}
# )
diff --git a/suite/testcommon.py b/suite/testcommon.py
index f77d3cf6..d0271588 100644
--- a/suite/testcommon.py
+++ b/suite/testcommon.py
@@ -11,8 +11,7 @@ from binaryninja.datarender import DataRenderer
from binaryninja.function import InstructionTextToken, DisassemblyTextLine
from binaryninja.enums import InstructionTextTokenType, FindFlag,\
FunctionGraphType, NamedTypeReferenceClass, ReferenceType, SegmentFlag, SectionSemantics
-from binaryninja.types import (Type, BoolWithConfidence, EnumerationBuilder, NamedTypeReferenceBuilder,
- IntegerBuilder, CharBuilder, FloatBuilder, WideCharBuilder, PointerBuilder, ArrayBuilder, FunctionBuilder, StructureBuilder,
+from binaryninja.types import (Type, BoolWithConfidence, EnumerationBuilder, NamedTypeReferenceBuilder
EnumerationBuilder, NamedTypeReferenceBuilder)
import subprocess
import re
@@ -81,10 +80,7 @@ class BinaryViewTestBuilder(Builder):
"""
def __init__(self, filename, options=None):
self.filename = os.path.join(os.path.dirname(__file__), filename)
- if options:
- _bv = BinaryViewType.get_view_of_file_with_options(self.filename, options=options)
- else:
- _bv = BinaryViewType.get_view_of_file(self.filename)
+ _bv = binja.load(self.filename, options=options)
assert _bv is not None, f"{filename} is not an executable format"
self.bv = _bv
@@ -853,7 +849,7 @@ class TestBuilder(Builder):
"""Types produced different result"""
file_name = self.unpackage_file("helloworld")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
preprocessed = binja.preprocess_source("""
#ifdef nonexistant
@@ -885,7 +881,7 @@ class TestBuilder(Builder):
"""Test TypeBuilders"""
file_name = self.unpackage_file("helloworld")
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
with binja.StructureBuilder.builder(bv, 'Foo') as s:
s.packed = True
s.append(Type.int(2))
@@ -996,7 +992,7 @@ class TestBuilder(Builder):
# file_name = self.unpackage_file("partial_register_dataflow")
# result = []
# reg_list = ['ch', 'cl', 'ah', 'edi', 'al', 'cx', 'ebp', 'ax', 'edx', 'ebx', 'esp', 'esi', 'dl', 'dh', 'di', 'bl', 'bh', 'eax', 'dx', 'bx', 'ecx', 'sp', 'si']
- # bv = binja.BinaryViewType.get_view_of_file(file_name)
+ # bv = binja.load(file_name)
# for func in bv.functions:
# llil = func.low_level_il
# for i in range(0, llil.__len__()-1):
@@ -1014,7 +1010,7 @@ class TestBuilder(Builder):
"""LLIL stack produced different output"""
file_name = self.unpackage_file("jumptable_reordered")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
# reg_list = ['ch', 'cl', 'ah', 'edi', 'al', 'cx', 'ebp', 'ax', 'edx', 'ebx', 'esp', 'esi', 'dl', 'dh', 'di', 'bl', 'bh', 'eax', 'dx', 'bx', 'ecx', 'sp', 'si']
flag_list = ['c', 'p', 'a', 'z', 's', 'o']
retinfo = []
@@ -1038,7 +1034,7 @@ class TestBuilder(Builder):
"""MLIL stack produced different output"""
file_name = self.unpackage_file("jumptable_reordered")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
reg_list = ['ch', 'cl', 'ah', 'edi', 'al', 'cx', 'ebp', 'ax', 'edx', 'ebx', 'esp', 'esi', 'dl', 'dh', 'di', 'bl', 'bh', 'eax', 'dx', 'bx', 'ecx', 'sp', 'si']
flag_list = ['c', 'p', 'a', 'z', 's', 'o']
retinfo = []
@@ -1071,7 +1067,7 @@ class TestBuilder(Builder):
"""Event failure"""
file_name = self.unpackage_file("helloworld")
try:
- with binja.BinaryViewType['ELF'].get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
bv.update_analysis_and_wait()
results = []
@@ -1235,7 +1231,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1275,7 +1271,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1308,7 +1304,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1354,7 +1350,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1391,7 +1387,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1410,7 +1406,7 @@ class TestBuilder(Builder):
if not os.path.exists(file_name):
return retinfo
- with BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
return retinfo
@@ -1451,7 +1447,7 @@ class TestBuilder(Builder):
"""Variable merging produced different output"""
file_name = self.unpackage_file("array_test.bndb")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
func = bv.get_function_at(0x100003920)
target = None
sources = []
@@ -1481,7 +1477,7 @@ class TestBuilder(Builder):
"""Live instructions for variable produced different output"""
file_name = self.unpackage_file("array_test.bndb")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
func = bv.get_function_at(0x100003920)
retinfo = []
for var in func.vars:
@@ -1515,7 +1511,7 @@ class VerifyBuilder(Builder):
""" Failed to parse PossibleValueSet from string"""
file_name = self.unpackage_file("helloworld")
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
# ConstantValue
lhs = bv.parse_possiblevalueset("0", binja.RegisterValueType.ConstantValue)
rhs = binja.PossibleValueSet.constant(0)
@@ -1564,7 +1560,7 @@ class VerifyBuilder(Builder):
def test_expression_parse(self):
file_name = self.unpackage_file("helloworld")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
assert bv.parse_expression("1 + 1") == 2
assert bv.parse_expression("-1 + 1") == 0
assert bv.parse_expression("1 - 1") == 0
@@ -1585,7 +1581,7 @@ class VerifyBuilder(Builder):
def test_get_il_vars(self):
file_name = self.unpackage_file("helloworld")
try:
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
main_func = bv.get_functions_by_name("main")[0]
value = sorted(list(map(lambda v: str(v), main_func.vars)))
oracle = ['__saved_r11', 'arg_0', 'argc', 'argv', 'envp', 'r0', 'r3', 'var_10', 'var_4', 'var_c']
@@ -1681,7 +1677,7 @@ class VerifyBuilder(Builder):
# - Validate that the modifications are present
file_name = self.unpackage_file("helloworld")
try:
- with binja.BinaryViewType['ELF'].get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
bv.update_analysis_and_wait()
# Make some modifications to the binary view
@@ -1715,7 +1711,7 @@ class VerifyBuilder(Builder):
try:
temp_name = next(tempfile._get_candidate_names()) + ".bndb"
- with binja.BinaryViewType['ELF'].get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
bv.update_analysis_and_wait()
@@ -1806,7 +1802,7 @@ class VerifyBuilder(Builder):
binja.Settings().reset("files.universal.architecturePreference")
try:
# test with default arch preference
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86")
assert(bv.start == 0x1000)
@@ -1823,9 +1819,9 @@ class VerifyBuilder(Builder):
temp_name = next(tempfile._get_candidate_names()) + ".bndb"
bv.create_database(temp_name)
- # test get_view_of_file open path
+ # test binja.load open path
binja.Settings().reset("files.universal.architecturePreference")
- with BinaryViewType.get_view_of_file(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86")
assert(bv.start == 0x1000)
@@ -1833,9 +1829,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file_with_options open path
+ # test binja.load open path
binja.Settings().reset("files.universal.architecturePreference")
- with BinaryViewType.get_view_of_file_with_options(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86")
assert(bv.start == 0x1000)
@@ -1843,9 +1839,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file open path (modified architecture preference)
+ # test binja.load open path (modified architecture preference)
binja.Settings().set_string_list("files.universal.architecturePreference", ["arm64"])
- with BinaryViewType.get_view_of_file(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86")
assert(bv.start == 0x1000)
@@ -1853,9 +1849,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file_with_options open path (modified architecture preference)
+ # test binja.load open path (modified architecture preference)
binja.Settings().set_string_list("files.universal.architecturePreference", ["x86_64", "arm64"])
- with BinaryViewType.get_view_of_file_with_options(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86")
assert(bv.start == 0x1000)
@@ -1866,7 +1862,7 @@ class VerifyBuilder(Builder):
# test with overridden arch preference
binja.Settings().set_string_list("files.universal.architecturePreference", ["arm64"])
- with binja.BinaryViewType.get_view_of_file(file_name) as bv:
+ with binja.load(file_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "aarch64")
assert(bv.start == 0x100000000)
@@ -1883,9 +1879,9 @@ class VerifyBuilder(Builder):
temp_name = next(tempfile._get_candidate_names()) + ".bndb"
bv.create_database(temp_name)
- # test get_view_of_file open path
+ # test binja.load open path
binja.Settings().reset("files.universal.architecturePreference")
- with BinaryViewType.get_view_of_file(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "aarch64")
assert(bv.start == 0x100000000)
@@ -1893,9 +1889,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file_with_options open path
+ # test binja.load open path
binja.Settings().reset("files.universal.architecturePreference")
- with BinaryViewType.get_view_of_file_with_options(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "aarch64")
assert(bv.start == 0x100000000)
@@ -1903,9 +1899,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file open path (modified architecture preference)
+ # test binja.load open path (modified architecture preference)
binja.Settings().set_string_list("files.universal.architecturePreference", ["x86"])
- with BinaryViewType.get_view_of_file(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "aarch64")
assert(bv.start == 0x100000000)
@@ -1913,9 +1909,9 @@ class VerifyBuilder(Builder):
bndb_comments = self.get_comments(bv)
assert([str(functions == bndb_functions and comments == bndb_comments)])
- # test get_view_of_file_with_options open path (modified architecture preference)
+ # test binja.load open path (modified architecture preference)
binja.Settings().set_string_list("files.universal.architecturePreference", ["x86_64", "arm64"])
- with BinaryViewType.get_view_of_file_with_options(temp_name) as bv:
+ with binja.load(temp_name) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "aarch64")
assert(bv.start == 0x100000000)
@@ -1927,7 +1923,7 @@ class VerifyBuilder(Builder):
binja.Settings().set_string_list("files.universal.architecturePreference", ["x86_64", "arm64"])
- with binja.BinaryViewType.get_view_of_file_with_options(file_name, options={'loader.imageBase': 0xfffffff0000}) as bv:
+ with binja.load(file_name, options={'loader.imageBase': 0xfffffff0000}) as bv:
assert(bv.view_type == "Mach-O")
assert(bv.arch.name == "x86_64")
assert(bv.start == 0xfffffff0000)
@@ -1947,7 +1943,7 @@ class VerifyBuilder(Builder):
"""User-informed dataflow tests"""
file_name = self.unpackage_file("helloworld")
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
func = bv.get_function_at(0x00008440)
ins_idx = func.mlil.get_instruction_start(0x845c)
@@ -2011,7 +2007,7 @@ class VerifyBuilder(Builder):
temp_name = next(tempfile._get_candidate_names()) + ".bndb"
bv.create_database(temp_name)
- with binja.open_view(temp_name) as bv:
+ with binja.load(temp_name) as bv:
func = bv.get_function_at(0x00008440)
ins_idx = func.mlil.get_instruction_start(0x845c)
@@ -2053,7 +2049,7 @@ class VerifyBuilder(Builder):
def test_helper(value):
file_name = self.unpackage_file("helloworld")
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
func = bv.get_function_at(0x00008440)
ins_idx = func.mlil.get_instruction_start(0x845c)
@@ -2074,7 +2070,7 @@ class VerifyBuilder(Builder):
temp_name = next(tempfile._get_candidate_names()) + ".bndb"
bv.create_database(temp_name)
- with binja.open_view(temp_name) as bv:
+ with binja.load(temp_name) as bv:
func = bv.get_function_at(0x00008440)
ins_idx = func.mlil.get_instruction_start(0x845c)
@@ -2124,7 +2120,7 @@ class VerifyBuilder(Builder):
BinaryViewType.add_binaryview_initial_analysis_completion_event(bv_analysis_completion_callback)
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
finalized = bv.query_metadata('finalized') == 'yes'
finalized_2 = bv.query_metadata('finalized_2') == 'yes'
analysis_completion = bv.query_metadata('analysis_completion') == 'yes'
@@ -2143,7 +2139,7 @@ class VerifyBuilder(Builder):
binja.Settings().set_bool("analysis.database.suppressReanalysis", True)
ret = None
- with BinaryViewType.get_view_of_file_with_options(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
ret = False
if bv.file.snapshot_data_applied_without_error:
@@ -2165,7 +2161,7 @@ class VerifyBuilder(Builder):
ret = True
try:
- with binja.open_view(file_name) as bv:
+ with binja.load(file_name) as bv:
# struct A { uint64_t a; uint64_t b; };
with binja.StructureBuilder.builder(bv, "A") as s:
s.width = 0x10
@@ -2207,10 +2203,10 @@ class VerifyBuilder(Builder):
ret = True
try:
binja.Settings().set_bool("analysis.database.suppressReanalysis", True)
- with BinaryViewType.get_view_of_file_with_options(file_name) as bv:
+ with binja.load(file_name) as bv:
if bv is None:
ret = False
- raise Exception("File load error")
+ raise Exception("File binja.load error")
if not bv.file.snapshot_data_applied_without_error:
ret = False
raise Exception("Snapshot apply error")