summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2020-02-16 15:38:36 -0500
committerBrian Potchik <brian@vector35.com>2020-02-16 15:38:36 -0500
commit5dde4481ed477dd67f3ef35364153f8243dbeb99 (patch)
tree33732e8813ac346837e6a1a43f3ab74886614bd5
parent4842373127779da2471960cfb25a5d549c30f099 (diff)
Add parse-only BinaryView creation to the API.
-rw-r--r--binaryninjaapi.h3
-rw-r--r--binaryninjacore.h4
-rw-r--r--binaryviewtype.cpp21
-rw-r--r--python/binaryview.py23
4 files changed, 50 insertions, 1 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 9c10b80b..922d2798 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1784,6 +1784,7 @@ __attribute__ ((format (printf, 1, 2)))
std::string m_nameForRegister, m_longNameForRegister;
static BNBinaryView* CreateCallback(void* ctxt, BNBinaryView* data);
+ static BNBinaryView* ParseCallback(void* ctxt, BNBinaryView* data);
static bool IsValidCallback(void* ctxt, BNBinaryView* data);
static BNSettings* GetSettingsCallback(void* ctxt, BNBinaryView* data);
@@ -1812,6 +1813,7 @@ __attribute__ ((format (printf, 1, 2)))
std::string GetLongName();
virtual BinaryView* Create(BinaryView* data) = 0;
+ virtual BinaryView* Parse(BinaryView* data) = 0;
virtual bool IsTypeValidForData(BinaryView* data) = 0;
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) = 0;
};
@@ -1821,6 +1823,7 @@ __attribute__ ((format (printf, 1, 2)))
public:
CoreBinaryViewType(BNBinaryViewType* type);
virtual BinaryView* Create(BinaryView* data) override;
+ virtual BinaryView* Parse(BinaryView* data) override;
virtual bool IsTypeValidForData(BinaryView* data) override;
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) override;
};
diff --git a/binaryninjacore.h b/binaryninjacore.h
index a2bc9b75..b19af253 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1145,6 +1145,7 @@ extern "C"
{
void* context;
BNBinaryView* (*create)(void* ctxt, BNBinaryView* data);
+ BNBinaryView* (*parse)(void* ctxt, BNBinaryView* data);
bool (*isValidForData)(void* ctxt, BNBinaryView* data);
BNSettings* (*getLoadSettingsForData)(void* ctxt, BNBinaryView* data);
};
@@ -2385,6 +2386,7 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI char* BNGetBinaryViewTypeName(BNBinaryViewType* type);
BINARYNINJACOREAPI char* BNGetBinaryViewTypeLongName(BNBinaryViewType* type);
BINARYNINJACOREAPI BNBinaryView* BNCreateBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
+ BINARYNINJACOREAPI BNBinaryView* BNParseBinaryViewOfType(BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI bool BNIsBinaryViewTypeValidForData(BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewDefaultLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data);
BINARYNINJACOREAPI BNSettings* BNGetBinaryViewLoadSettingsForData(BNBinaryViewType* type, BNBinaryView* data);
@@ -2861,7 +2863,7 @@ __attribute__ ((format (printf, 1, 2)))
uint64_t addr, size_t* count);
BINARYNINJACOREAPI void BNFreeIndirectBranchList(BNIndirectBranchInfo* branches);
- BINARYNINJACOREAPI void BNSetAutoCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
+ BINARYNINJACOREAPI void BNSetAutoCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
BNTypeWithConfidence* type);
BINARYNINJACOREAPI void BNSetUserCallTypeAdjustment(BNFunction* func, BNArchitecture* arch, uint64_t addr,
BNTypeWithConfidence* type);
diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp
index 4c7504d6..f8f58da0 100644
--- a/binaryviewtype.cpp
+++ b/binaryviewtype.cpp
@@ -35,6 +35,17 @@ BNBinaryView* BinaryViewType::CreateCallback(void* ctxt, BNBinaryView* data)
}
+BNBinaryView* BinaryViewType::ParseCallback(void* ctxt, BNBinaryView* data)
+{
+ BinaryViewType* type = (BinaryViewType*)ctxt;
+ Ref<BinaryView> view = new BinaryView(BNNewViewReference(data));
+ Ref<BinaryView> result = type->Parse(view);
+ if (!result)
+ return nullptr;
+ return BNNewViewReference(result->GetObject());
+}
+
+
bool BinaryViewType::IsValidCallback(void* ctxt, BNBinaryView* data)
{
BinaryViewType* type = (BinaryViewType*)ctxt;
@@ -72,6 +83,7 @@ void BinaryViewType::Register(BinaryViewType* type)
BNCustomBinaryViewType callbacks;
callbacks.context = type;
callbacks.create = CreateCallback;
+ callbacks.parse = ParseCallback;
callbacks.isValidForData = IsValidCallback;
callbacks.getLoadSettingsForData = GetSettingsCallback;
@@ -217,6 +229,15 @@ BinaryView* CoreBinaryViewType::Create(BinaryView* data)
}
+BinaryView* CoreBinaryViewType::Parse(BinaryView* data)
+{
+ BNBinaryView* view = BNParseBinaryViewOfType(m_object, data->GetObject());
+ if (!view)
+ return nullptr;
+ return new BinaryView(view);
+}
+
+
bool CoreBinaryViewType::IsTypeValidForData(BinaryView* data)
{
return BNIsBinaryViewTypeValidForData(m_object, data->GetObject());
diff --git a/python/binaryview.py b/python/binaryview.py
index 5589adfa..5fb1c6fa 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -747,6 +747,12 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
bv.update_analysis_and_wait()
return bv
+ def parse(self, data):
+ view = core.BNParseBinaryViewOfType(self.handle, data.handle)
+ if view is None:
+ return None
+ return BinaryView(file_metadata=data.file, handle=view)
+
def is_valid_for_data(self, data):
return core.BNIsBinaryViewTypeValidForData(self.handle, data.handle)
@@ -1211,6 +1217,7 @@ class BinaryView(object):
cls._registered_cb = core.BNCustomBinaryViewType()
cls._registered_cb.context = 0
cls._registered_cb.create = cls._registered_cb.create.__class__(cls._create)
+ cls._registered_cb.parse = cls._registered_cb.parse.__class__(cls._parse)
cls._registered_cb.isValidForData = cls._registered_cb.isValidForData.__class__(cls._is_valid_for_data)
cls._registered_cb.getLoadSettingsForData = cls._registered_cb.getLoadSettingsForData.__class__(cls._get_load_settings_for_data)
cls.registered_view_type = BinaryViewType(core.BNRegisterBinaryViewType(cls.name, cls.long_name, cls._registered_cb))
@@ -1223,6 +1230,22 @@ class BinaryView(object):
view = cls(BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(data)))
if view is None:
return None
+ # FIXME: There is probably a better way to convey this information...
+ view.__dict__.update({'parse_only' : False})
+ return ctypes.cast(core.BNNewViewReference(view.handle), ctypes.c_void_p).value
+ except:
+ log.log_error(traceback.format_exc())
+ return None
+
+ @classmethod
+ def _parse(cls, ctxt, data):
+ try:
+ file_metadata = binaryninja.filemetadata.FileMetadata(handle=core.BNGetFileForView(data))
+ view = cls(BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(data)))
+ if view is None:
+ return None
+ # FIXME: There is probably a better way to convey this information...
+ view.__dict__.update({'parse_only' : True})
return ctypes.cast(core.BNNewViewReference(view.handle), ctypes.c_void_p).value
except:
log.log_error(traceback.format_exc())