File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -3384,6 +3384,8 @@ namespace BinaryNinja {
33843384 public:
33853385 Database(BNDatabase* database);
33863386
3387+ static Ref<Database> OpenExisting(const std::string& path);
3388+
33873389 bool SnapshotHasData(int64_t id);
33883390 Ref<Snapshot> GetSnapshot(int64_t id);
33893391 std::vector<Ref<Snapshot>> GetSnapshots();
Original file line number Diff line number Diff line change @@ -4639,6 +4639,8 @@ extern "C"
46394639 // Database object
46404640 BINARYNINJACOREAPI BNDatabase* BNNewDatabaseReference(BNDatabase* database);
46414641 BINARYNINJACOREAPI void BNFreeDatabase(BNDatabase* database);
4642+ BINARYNINJACOREAPI BNDatabase* BNCreateDatabaseInstance(void);
4643+ BINARYNINJACOREAPI bool BNDatabaseOpenExisting(BNDatabase* database, const char* path);
46424644 BINARYNINJACOREAPI void BNSetDatabaseCurrentSnapshot(BNDatabase* database, int64_t id);
46434645 BINARYNINJACOREAPI BNSnapshot* BNGetDatabaseCurrentSnapshot(BNDatabase* database);
46444646 BINARYNINJACOREAPI BNSnapshot** BNGetDatabaseSnapshots(BNDatabase* database, size_t* count);
Original file line number Diff line number Diff line change @@ -380,6 +380,15 @@ Database::Database(BNDatabase* database)
380380}
381381
382382
383+ Ref<Database> Database::OpenExisting (const std::string& path)
384+ {
385+ Ref<Database> db = new Database (BNCreateDatabaseInstance ());
386+ if (!BNDatabaseOpenExisting (db->GetObject (), path.c_str ()))
387+ throw DatabaseException (" BNDatabaseOpenExisting" );
388+ return db;
389+ }
390+
391+
383392Ref<Snapshot> Database::GetSnapshot (int64_t id)
384393{
385394 BNSnapshot* snap = BNGetDatabaseSnapshot (m_object, id);
Original file line number Diff line number Diff line change @@ -246,6 +246,18 @@ def __init__(self, handle):
246246 def __del__ (self ):
247247 core .BNFreeDatabase (self .handle )
248248
249+ @classmethod
250+ def open_existing (cls , path : str ) -> 'Database' :
251+ """
252+ Open a Database from a file
253+ :param path: Path to file containing database
254+ :return: Database instance
255+ """
256+ db = Database (handle = core .BNCreateDatabaseInstance ())
257+ if not core .BNDatabaseOpenExisting (db .handle , path ):
258+ raise RuntimeError ("BNDatabaseOpenExisting returned False" )
259+ return db
260+
249261 def __getitem__ (self , item : int ) -> Optional [Snapshot ]:
250262 return self .get_snapshot (item )
251263
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ use binaryninjacore_sys::*;
66use std:: collections:: HashMap ;
77use std:: ffi:: c_void;
88use std:: fmt:: Debug ;
9+ use std:: path:: Path ;
910use std:: ptr:: NonNull ;
1011
1112use crate :: binary_view:: BinaryView ;
@@ -29,6 +30,17 @@ impl Database {
2930 Ref :: new ( Self { handle } )
3031 }
3132
33+ /// Open a database with the given file path
34+ pub fn open_existing ( path : impl AsRef < Path > ) -> Result < Ref < Self > , ( ) > {
35+ let db = unsafe { Self :: ref_from_raw ( NonNull :: new ( BNCreateDatabaseInstance ( ) ) . ok_or ( ( ) ) ?) } ;
36+ let path_raw = path. as_ref ( ) . to_cstr ( ) ;
37+ if unsafe { BNDatabaseOpenExisting ( db. handle . as_ptr ( ) , path_raw. as_ptr ( ) ) } {
38+ Ok ( db)
39+ } else {
40+ Err ( ( ) )
41+ }
42+ }
43+
3244 /// Get a [`Snapshot`] by its `id`, or `None` if no snapshot with that `id` exists.
3345 pub fn snapshot_by_id ( & self , id : SnapshotId ) -> Option < Ref < Snapshot > > {
3446 let result = unsafe { BNGetDatabaseSnapshot ( self . handle . as_ptr ( ) , id. 0 ) } ;
Original file line number Diff line number Diff line change 1+ use binaryninja:: database:: Database ;
2+ use binaryninja:: file_metadata:: SaveSettings ;
3+ use binaryninja:: headless:: Session ;
4+ use std:: path:: PathBuf ;
5+
6+ #[ test]
7+ fn test_open_existing ( ) {
8+ let _session = Session :: new ( ) . expect ( "Failed to initialize session" ) ;
9+ let out_dir = env ! ( "OUT_DIR" ) . parse :: < PathBuf > ( ) . unwrap ( ) ;
10+ let view = binaryninja:: load ( out_dir. join ( "atox.obj" ) ) . expect ( "Failed to create view" ) ;
11+ // Save the modified database.
12+ let temp_dir = tempfile:: tempdir ( ) . expect ( "Failed to create temporary directory" ) ;
13+ let temp_path = temp_dir. path ( ) . join ( "atox.obj.bndb" ) ;
14+ assert ! ( view
15+ . file( )
16+ . create_database( & temp_path, & SaveSettings :: new( ) ) ) ;
17+ // Verify that the file exists and is modified.
18+ drop ( view) ;
19+ let db = Database :: open_existing ( & temp_path) . unwrap ( ) ;
20+ // Make sure the database has data
21+ assert ! ( db. snapshots( ) . len( ) > 0 ) ;
22+ }
You can’t perform that action at this time.
0 commit comments