Skip to content

Commit 5dde448

Browse files
committed
Add parse-only BinaryView creation to the API.
1 parent 4842373 commit 5dde448

4 files changed

Lines changed: 50 additions & 1 deletion

File tree

binaryninjaapi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,7 @@ __attribute__ ((format (printf, 1, 2)))
17841784
std::string m_nameForRegister, m_longNameForRegister;
17851785

17861786
static BNBinaryView* CreateCallback(void* ctxt, BNBinaryView* data);
1787+
static BNBinaryView* ParseCallback(void* ctxt, BNBinaryView* data);
17871788
static bool IsValidCallback(void* ctxt, BNBinaryView* data);
17881789
static BNSettings* GetSettingsCallback(void* ctxt, BNBinaryView* data);
17891790

@@ -1812,6 +1813,7 @@ __attribute__ ((format (printf, 1, 2)))
18121813
std::string GetLongName();
18131814

18141815
virtual BinaryView* Create(BinaryView* data) = 0;
1816+
virtual BinaryView* Parse(BinaryView* data) = 0;
18151817
virtual bool IsTypeValidForData(BinaryView* data) = 0;
18161818
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) = 0;
18171819
};
@@ -1821,6 +1823,7 @@ __attribute__ ((format (printf, 1, 2)))
18211823
public:
18221824
CoreBinaryViewType(BNBinaryViewType* type);
18231825
virtual BinaryView* Create(BinaryView* data) override;
1826+
virtual BinaryView* Parse(BinaryView* data) override;
18241827
virtual bool IsTypeValidForData(BinaryView* data) override;
18251828
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) override;
18261829
};

binaryninjacore.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,7 @@ extern "C"
11451145
{
11461146
void* context;
11471147
BNBinaryView* (*create)(void* ctxt, BNBinaryView* data);
1148+
BNBinaryView* (*parse)(void* ctxt, BNBinaryView* data);
11481149
bool (*isValidForData)(void* ctxt, BNBinaryView* data);
11491150
BNSettings* (*getLoadSettingsForData)(void* ctxt, BNBinaryView* data);
11501151
};
@@ -2385,6 +2386,7 @@ __attribute__ ((format (printf, 1, 2)))
23852386
BINARYNINJACOREAPI char* BNGetBinaryViewTypeName(BNBinaryViewType* type);
23862387
BINARYNINJACOREAPI char* BNGetBinaryViewTypeLongName(BNBinaryViewType* type);
23872388
BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
2389+
BINARYNINJACOREAPI BNBinaryView* BNParseBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
23882390
BINARYNINJACOREAPI bool BNIsBinaryViewTypeValidForData(BNBinaryViewType* type, BNBinaryView* data);
23892391
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewDefaultLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data);
23902392
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data);
@@ -2861,7 +2863,7 @@ __attribute__ ((format (printf, 1, 2)))
28612863
uint64_t addr, size_t* count);
28622864
BINARYNINJACOREAPI void BNFreeIndirectBranchList(BNIndirectBranchInfo* branches);
28632865

2864-
BINARYNINJACOREAPI void BNSetAutoCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
2866+
BINARYNINJACOREAPI void BNSetAutoCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
28652867
BNTypeWithConfidence* type);
28662868
BINARYNINJACOREAPI void BNSetUserCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
28672869
BNTypeWithConfidence* type);

binaryviewtype.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ BNBinaryView* BinaryViewType::CreateCallback(void* ctxt, BNBinaryView* data)
3535
}
3636

3737

38+
BNBinaryView* BinaryViewType::ParseCallback(void* ctxt, BNBinaryView* data)
39+
{
40+
BinaryViewType* type = (BinaryViewType*)ctxt;
41+
Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
42+
Ref<BinaryView> result = type->Parse(view);
43+
if (!result)
44+
return nullptr;
45+
return BNNewViewReference(result->GetObject());
46+
}
47+
48+
3849
bool BinaryViewType::IsValidCallback(void* ctxt, BNBinaryView* data)
3950
{
4051
BinaryViewType* type = (BinaryViewType*)ctxt;
@@ -72,6 +83,7 @@ void BinaryViewType::Register(BinaryViewType* type)
7283
BNCustomBinaryViewType callbacks;
7384
callbacks.context = type;
7485
callbacks.create = CreateCallback;
86+
callbacks.parse = ParseCallback;
7587
callbacks.isValidForData = IsValidCallback;
7688
callbacks.getLoadSettingsForData = GetSettingsCallback;
7789

@@ -217,6 +229,15 @@ BinaryView* CoreBinaryViewType::Create(BinaryView* data)
217229
}
218230

219231

232+
BinaryView* CoreBinaryViewType::Parse(BinaryView* data)
233+
{
234+
BNBinaryView* view = BNParseBinaryViewOfType(m_object, data->GetObject());
235+
if (!view)
236+
return nullptr;
237+
return new BinaryView(view);
238+
}
239+
240+
220241
bool CoreBinaryViewType::IsTypeValidForData(BinaryView* data)
221242
{
222243
return BNIsBinaryViewTypeValidForData(m_object, data->GetObject());

python/binaryview.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,12 @@ def get_view_of_file_with_options(cls, filename, update_analysis=True, progress_
747747
bv.update_analysis_and_wait()
748748
return bv
749749

750+
def parse(self, data):
751+
view = core.BNParseBinaryViewOfType(self.handle, data.handle)
752+
if view is None:
753+
return None
754+
return BinaryView(file_metadata=data.file, handle=view)
755+
750756
def is_valid_for_data(self, data):
751757
return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle)
752758

@@ -1211,6 +1217,7 @@ def register(cls):
12111217
cls._registered_cb = core.BNCustomBinaryViewType()
12121218
cls._registered_cb.context = 0
12131219
cls._registered_cb.create = cls._registered_cb.create.__class__(cls._create)
1220+
cls._registered_cb.parse = cls._registered_cb.parse.__class__(cls._parse)
12141221
cls._registered_cb.isValidForData = cls._registered_cb.isValidForData.__class__(cls._is_valid_for_data)
12151222
cls._registered_cb.getLoadSettingsForData = cls._registered_cb.getLoadSettingsForData.__class__(cls._get_load_settings_for_data)
12161223
cls.registered_view_type = BinaryViewType(core.BNRegisterBinaryViewType(cls.name, cls.long_name, cls._registered_cb))
@@ -1223,6 +1230,22 @@ def _create(cls, ctxt, data):
12231230
view = cls(BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(data)))
12241231
if view is None:
12251232
return None
1233+
# FIXME: There is probably a better way to convey this information...
1234+
view.__dict__.update({'parse_only' : False})
1235+
return ctypes.cast(core.BNNewViewReference(view.handle), ctypes.c_void_p).value
1236+
except:
1237+
log.log_error(traceback.format_exc())
1238+
return None
1239+
1240+
@classmethod
1241+
def _parse(cls, ctxt, data):
1242+
try:
1243+
file_metadata = binaryninja.filemetadata.FileMetadata(handle=core.BNGetFileForView(data))
1244+
view = cls(BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(data)))
1245+
if view is None:
1246+
return None
1247+
# FIXME: There is probably a better way to convey this information...
1248+
view.__dict__.update({'parse_only' : True})
12261249
return ctypes.cast(core.BNNewViewReference(view.handle), ctypes.c_void_p).value
12271250
except:
12281251
log.log_error(traceback.format_exc())

0 commit comments

Comments
 (0)