diff options
| -rw-r--r-- | binaryninjaapi.h | 3 | ||||
| -rw-r--r-- | binaryninjacore.h | 4 | ||||
| -rw-r--r-- | binaryviewtype.cpp | 21 | ||||
| -rw-r--r-- | python/binaryview.py | 23 |
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()) |
