From 9969e70ed879fbfa2bf9fdecf2d9012795bed1a3 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 22 Apr 2019 15:37:37 -0400 Subject: Add BNGetStructureMemberByName API and add __getitem__ to python Structure API --- binaryninjaapi.h | 1 + binaryninjacore.h | 2 ++ python/types.py | 20 +++++++++++++++----- type.cpp | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 275a8370..6a4b1bc1 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2333,6 +2333,7 @@ namespace BinaryNinja Structure(BNStructureType type, bool packed = false); std::vector GetMembers() const; + bool GetMemberByName(const std::string& name, StructureMember& result) const; uint64_t GetWidth() const; void SetWidth(size_t width); size_t GetAlignment() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index cc92ec8a..1a60badc 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3327,6 +3327,8 @@ extern "C" BINARYNINJACOREAPI BNStructure* BNNewStructureReference(BNStructure* s); BINARYNINJACOREAPI void BNFreeStructure(BNStructure* s); + BINARYNINJACOREAPI BNStructureMember* BNGetStructureMemberByName(BNStructure* s, const char* name); + BINARYNINJACOREAPI void BNFreeStructureMember(BNStructureMember* s); BINARYNINJACOREAPI BNStructureMember* BNGetStructureMembers(BNStructure* s, size_t* count); BINARYNINJACOREAPI void BNFreeStructureMemberList(BNStructureMember* members, size_t count); BINARYNINJACOREAPI uint64_t BNGetStructureWidth(BNStructure* s); diff --git a/python/types.py b/python/types.py index 70a9d6cc..68d20997 100644 --- a/python/types.py +++ b/python/types.py @@ -880,16 +880,26 @@ class Structure(object): return True return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + def __getitem__(self, name): + try: + member = core.BNGetStructureMemberByName(self.handle, name) + return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence), + member.contents.name, member.contents.offset) + finally: + core.BNFreeStructureMember(member) + @property def members(self): """Structure member list (read-only)""" count = ctypes.c_ulonglong() members = core.BNGetStructureMembers(self.handle, count) - result = [] - for i in range(0, count.value): - result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type), confidence = members[i].typeConfidence), - members[i].name, members[i].offset)) - core.BNFreeStructureMemberList(members, count.value) + try: + result = [] + for i in range(0, count.value): + result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type), confidence=members[i].typeConfidence), + members[i].name, members[i].offset)) + finally: + core.BNFreeStructureMemberList(members, count.value) return result @property diff --git a/type.cpp b/type.cpp index 8d0ec587..a2075103 100644 --- a/type.cpp +++ b/type.cpp @@ -1092,6 +1092,21 @@ vector Structure::GetMembers() const } +bool Structure::GetMemberByName(const string& name, StructureMember& result) const +{ + BNStructureMember* member = BNGetStructureMemberByName(m_object, name.c_str()); + if (member) + { + result.type = new Type(BNNewTypeReference(member->type)); + result.name = member->name; + result.offset = member->offset; + BNFreeStructureMember(member); + return true; + } + return false; +} + + uint64_t Structure::GetWidth() const { return BNGetStructureWidth(m_object); -- cgit v1.3.1