From 990cface5a0b9b814f423e45449a7d5f3cb6c19d Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 1 Dec 2016 17:22:22 -0500 Subject: Adding APIs to manipulate structures --- binaryninjaapi.h | 10 ++++++++++ binaryninjacore.h | 11 +++++++++++ binaryview.cpp | 20 ++++++++++++++++++++ python/__init__.py | 32 ++++++++++++++++++++++++++++++-- type.cpp | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a918fc42..1d46bdc5 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -590,6 +590,8 @@ namespace BinaryNinja static void DataVariableUpdatedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var); static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); + static void TypeDefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type); + static void TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type); public: BinaryDataNotification(); @@ -608,6 +610,8 @@ namespace BinaryNinja virtual void OnDataVariableUpdated(BinaryView* view, const DataVariable& var) { (void)view; (void)var; } virtual void OnStringFound(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } virtual void OnStringRemoved(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } + virtual void OnTypeDefined(BinaryView* data, const std::string& name, Type* type) { (void)data; (void)name; (void)type; } + virtual void OnTypeUndefined(BinaryView* data, const std::string& name, Type* type) { (void)data; (void)name; (void)type; } }; class FileAccessor @@ -1570,13 +1574,16 @@ namespace BinaryNinja class Structure: public CoreRefCountObject { public: + Structure(); Structure(BNStructure* s); std::vector GetName() const; void SetName(const std::vector& name); std::vector GetMembers() const; uint64_t GetWidth() const; + void SetWidth(size_t width); size_t GetAlignment() const; + void SetAlignment(size_t align); bool IsPacked() const; void SetPacked(bool packed); bool IsUnion() const; @@ -1585,6 +1592,7 @@ namespace BinaryNinja void AddMember(Type* type, const std::string& name); void AddMemberAtOffset(Type* type, const std::string& name, uint64_t offset); void RemoveMember(size_t idx); + void ReplaceMember(size_t idx, Type* type, const std::string& name); }; struct EnumerationMember @@ -1606,6 +1614,8 @@ namespace BinaryNinja void AddMember(const std::string& name); void AddMemberWithValue(const std::string& name, uint64_t value); + void RemoveMember(size_t idx); + void ReplaceMember(size_t idx, const std::string& name, uint64_t value); }; class DisassemblySettings: public CoreRefCountObject view = new BinaryView(BNNewViewReference(data)); + Ref typeObj = new Type(BNNewTypeReference(type)); + notify->OnTypeDefined(view, name, typeObj); +} + + +void BinaryDataNotification::TypeUndefinedCallback(void* ctxt, BNBinaryView* data, const char* name, BNType* type) +{ + BinaryDataNotification* notify = (BinaryDataNotification*)ctxt; + Ref view = new BinaryView(BNNewViewReference(data)); + Ref typeObj = new Type(BNNewTypeReference(type)); + notify->OnTypeUndefined(view, name, typeObj); +} + + BinaryDataNotification::BinaryDataNotification() { m_callbacks.context = this; @@ -143,6 +161,8 @@ BinaryDataNotification::BinaryDataNotification() m_callbacks.dataVariableUpdated = DataVariableUpdatedCallback; m_callbacks.stringFound = StringFoundCallback; m_callbacks.stringRemoved = StringRemovedCallback; + m_callbacks.typeDefined = TypeDefinedCallback; + m_callbacks.typeUndefined = TypeUndefinedCallback; } diff --git a/python/__init__.py b/python/__init__.py index 1751fefa..cc138009 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -576,6 +576,12 @@ class BinaryDataNotification: def string_removed(self, view, string_type, offset, length): pass + def type_defined(self, view, name, type): + pass + + def type_undefined(self, view, name, type): + pass + class UndoAction: name = None action_type = None @@ -671,6 +677,8 @@ class BinaryDataNotificationCallbacks(object): self._cb.dataVariableUpdated = self._cb.dataVariableUpdated.__class__(self._data_var_updated) self._cb.stringFound = self._cb.stringFound.__class__(self._string_found) self._cb.stringRemoved = self._cb.stringRemoved.__class__(self._string_removed) + self._cb.typeDefined = self._cb.typeDefined.__class__(self._type_defined) + self._cb.typeUndefined = self._cb.typeUndefined.__class__(self._type_undefined) def _register(self): core.BNRegisterDataNotification(self.view.handle, self._cb) @@ -753,6 +761,18 @@ class BinaryDataNotificationCallbacks(object): except: log_error(traceback.format_exc()) + def _type_defined(self, ctxt, name, type_obj): + try: + self.notify.type_defined(self.view, name, Type(core.BNNewTypeReference(type_obj))) + except: + log_error(traceback.format_exc()) + + def _type_undefined(self, ctxt, name, type_obj): + try: + self.notify.type_undefined(self.view, name, Type(core.BNNewTypeReference(type_obj))) + except: + log_error(traceback.format_exc()) + class _BinaryViewTypeMetaclass(type): @property def list(self): @@ -4447,14 +4467,22 @@ class Structure(object): @property def width(self): - """Structure width (read-only)""" + """Structure width""" return core.BNGetStructureWidth(self.handle) + @width.setter + def width(self, new_width): + core.BNSetStructureWidth(self.handle, new_width) + @property def alignment(self): - """Structure alignment (read-only)""" + """Structure alignment""" return core.BNGetStructureAlignment(self.handle) + @alignment.setter + def alignment(self, align): + core.BNSetStructureAlignment(self.handle, align) + @property def packed(self): return core.BNIsStructurePacked(self.handle) diff --git a/type.cpp b/type.cpp index e0235664..7cc2757a 100644 --- a/type.cpp +++ b/type.cpp @@ -323,6 +323,12 @@ vector UnknownType::GetName() const } +Structure::Structure() +{ + m_object = BNCreateStructure(); +} + + Structure::Structure(BNStructure* s) { m_object = s; @@ -382,12 +388,24 @@ uint64_t Structure::GetWidth() const } +void Structure::SetWidth(size_t width) +{ + BNSetStructureWidth(m_object, width); +} + + size_t Structure::GetAlignment() const { return BNGetStructureAlignment(m_object); } +void Structure::SetAlignment(size_t align) +{ + BNSetStructureAlignment(m_object, align); +} + + bool Structure::IsPacked() const { return BNIsStructurePacked(m_object); @@ -430,6 +448,12 @@ void Structure::RemoveMember(size_t idx) } +void Structure::ReplaceMember(size_t idx, Type* type, const std::string& name) +{ + BNReplaceStructureMember(m_object, idx, type->GetObject(), name.c_str()); +} + + Enumeration::Enumeration(BNEnumeration* e) { m_object = e; @@ -494,6 +518,18 @@ void Enumeration::AddMemberWithValue(const string& name, uint64_t value) } +void Enumeration::RemoveMember(size_t idx) +{ + BNRemoveEnumerationMember(m_object, idx); +} + + +void Enumeration::ReplaceMember(size_t idx, const string& name, uint64_t value) +{ + BNReplaceEnumerationMember(m_object, idx, name.c_str(), value); +} + + bool BinaryNinja::PreprocessSource(const string& source, const string& fileName, string& output, string& errors, const vector& includeDirs) { -- cgit v1.3.1