diff options
| -rw-r--r-- | binaryninjaapi.h | 14 | ||||
| -rw-r--r-- | binaryninjacore.h | 28 | ||||
| -rw-r--r-- | python/types.py | 49 | ||||
| -rw-r--r-- | type.cpp | 40 | ||||
| -rw-r--r-- | ui/typeview.h | 37 |
5 files changed, 134 insertions, 34 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f6a3ab51..e89a572a 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1461,6 +1461,18 @@ namespace BinaryNinja { static LinearDisassemblyLine FromAPIObject(BNLinearDisassemblyLine* line); }; + struct TypeDefinitionLine + { + BNTypeDefinitionLineType lineType; + std::vector<InstructionTextToken> tokens; + Ref<Type> type, rootType; + std::string rootTypeName; + uint64_t offset; + size_t fieldIndex; + + static TypeDefinitionLine FromAPIObject(BNTypeDefinitionLine* line); + }; + class DisassemblySettings; class AnalysisCompletionEvent : @@ -3001,6 +3013,8 @@ namespace BinaryNinja { bool AddTypeMemberTokens(BinaryView* data, std::vector<InstructionTextToken>& tokens, int64_t offset, std::vector<std::string>& nameList, size_t size = 0, bool indirect = false); + std::vector<TypeDefinitionLine> GetLines(Ref<BinaryView> data, const std::string& name, + int lineWidth = 80, bool collapsed = false); static std::string GetSizeSuffix(size_t size); }; diff --git a/binaryninjacore.h b/binaryninjacore.h index 1062a244..25500d0b 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1481,6 +1481,32 @@ extern "C" size_t count; }; + enum BNTypeDefinitionLineType + { + TypedefLineType, + StructDefinitionLineType, + StructFieldLineType, + StructDefinitionEndLineType, + EnumDefinitionLineType, + EnumMemberLineType, + EnumDefinitionEndLineType, + PaddingLineType, + UndefinedXrefLineType + }; + + struct BNTypeDefinitionLine + { + BNTypeDefinitionLineType lineType; + BNInstructionTextToken* tokens; + size_t count; + BNType* type; + BNType* rootType; + char* rootTypeName; + uint64_t offset; + size_t fieldIndex; + }; + + struct BNFlagConditionForSemanticClass { uint32_t semanticClass; @@ -5003,6 +5029,8 @@ extern "C" BINARYNINJACOREAPI bool BNAddTypeMemberTokens(BNType* type, BNBinaryView* data, BNInstructionTextToken** tokens, size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect); + BINARYNINJACOREAPI BNTypeDefinitionLine* BNGetTypeLines(BNType* type, BNBinaryView* data, const char* name, int lineWidth, bool collapsed, size_t* count); + BINARYNINJACOREAPI void BNFreeTypeDefinitionLineList(BNTypeDefinitionLine* list, size_t count); BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetTypeName(BNTypeBuilder* nt); BINARYNINJACOREAPI void BNTypeBuilderSetTypeName(BNTypeBuilder* type, BNQualifiedName* name); diff --git a/python/types.py b/python/types.py index 055bf8d4..7538bcd5 100644 --- a/python/types.py +++ b/python/types.py @@ -28,7 +28,7 @@ from abc import abstractmethod from . import _binaryninjacore as core from .enums import ( StructureVariant, SymbolType, SymbolBinding, TypeClass, NamedTypeReferenceClass, ReferenceType, VariableSourceType, - TypeReferenceType, MemberAccess, MemberScope + TypeReferenceType, MemberAccess, MemberScope, TypeDefinitionLineType ) from . import callingconvention from . import function as _function @@ -199,6 +199,23 @@ class NameSpace(QualifiedName): return NameSpace(name)._to_core_struct() +@dataclass(frozen=True) +class TypeDefinitionLine: + line_type: TypeDefinitionLineType + tokens: List['_function.InstructionTextToken'] + type: 'Type' + root_type: 'Type' + root_type_name: str + offset: int + field_index: int + + def __str__(self): + return "".join(map(str, self.tokens)) + + def __repr__(self): + return f"<typeDefinitionLine {self.type}: {self}>" + + class CoreSymbol: def __init__(self, handle: core.BNSymbolHandle): self._handle = handle @@ -1590,6 +1607,36 @@ class Type: core.BNFreeInstructionText(tokens, count.value) return result + def get_lines( + self, bv: 'binaryview.BinaryView', name: str, line_width: int = 80, collapsed: bool = False + ) -> List['TypeDefinitionLine']: + """ + Get a list of :py:class:`TypeDefinitionLine` structures for representing a Type in a structured form. + This structure uses the same logic as Types View and will expand structures and enumerations + unless `collapsed` is set. + + :param BinaryView bv: BinaryView object owning this Type + :param str name: Displayed name of the Type + :param int line_width: Maximum width of lines (in characters) + :param bool collapsed: If the type should be collapsed, and not show fields/members + :return: Returns a list of :py:class:`TypeDefinitionLine` structures + :rtype: :py:class:`TypeDefinitionLine` + """ + count = ctypes.c_ulonglong() + core_lines = core.BNGetTypeLines(self._handle, bv.handle, name, line_width, collapsed, count) + assert core_lines is not None, "core.BNGetTypeLines returned None" + lines = [] + for i in range(count.value): + tokens = _function.InstructionTextToken._from_core_struct(core_lines[i].tokens, core_lines[i].count) + type_ = Type.create(handle=core.BNNewTypeReference(core_lines[i].type), platform=self._platform) + root_type = Type.create(handle=core.BNNewTypeReference(core_lines[i].rootType), platform=self._platform) + root_type_name = core.pyNativeStr(core_lines[i].rootTypeName) + line = TypeDefinitionLine(core_lines[i].lineType, tokens, type_, root_type, root_type_name, + core_lines[i].offset, core_lines[i].fieldIndex) + lines.append(line) + core.BNFreeTypeDefinitionLineList(core_lines, count.value) + return lines + def with_confidence(self, confidence) -> 'Type': return Type.create(handle=core.BNNewTypeReference(self._handle), platform=self._platform, confidence=confidence) @@ -419,6 +419,20 @@ NameSpace NameSpace::FromAPIObject(const BNNameSpace* name) } +TypeDefinitionLine TypeDefinitionLine::FromAPIObject(BNTypeDefinitionLine* line) +{ + TypeDefinitionLine result; + result.lineType = line->lineType; + result.tokens = InstructionTextToken::ConvertInstructionTextTokenList(line->tokens, line->count); + result.type = new Type(BNNewTypeReference(line->type)); + result.rootType = new Type(BNNewTypeReference(line->rootType)); + result.rootTypeName = line->rootTypeName; + result.offset = line->offset; + result.fieldIndex = line->fieldIndex; + return result; +} + + Type::Type(BNType* type) { m_object = type; @@ -989,6 +1003,32 @@ bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& t } +std::vector<TypeDefinitionLine> Type::GetLines(Ref<BinaryView> data, const std::string& name, + int lineWidth, bool collapsed) +{ + size_t count; + BNTypeDefinitionLine* list = + BNGetTypeLines(m_object, data->m_object, name.c_str(), lineWidth, collapsed, &count); + + std::vector<TypeDefinitionLine> results; + for (size_t i = 0; i < count; i++) + { + TypeDefinitionLine line; + line.lineType = list[i].lineType; + line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(list[i].tokens, list[i].count); + line.type = new Type(BNNewTypeReference(list[i].type)); + line.rootType = list[i].rootType ? new Type(BNNewTypeReference(list[i].rootType)) : nullptr; + line.rootTypeName = list[i].rootTypeName; + line.offset = list[i].offset; + line.fieldIndex = list[i].fieldIndex; + results.push_back(line); + } + + BNFreeTypeDefinitionLineList(list, count); + return results; +} + + string Type::GetSizeSuffix(size_t size) { char sizeStr[32]; diff --git a/ui/typeview.h b/ui/typeview.h index 3a7e744b..834cb7d8 100644 --- a/ui/typeview.h +++ b/ui/typeview.h @@ -21,20 +21,6 @@ #define TYPE_VIEW_UPDATE_CHECK_INTERVAL 200 -enum BINARYNINJAUIAPI TypeDefinitionLineType -{ - TypedefLineType, - StructDefinitionLineType, - StructFieldLineType, - StructDefinitionEndLineType, - EnumDefinitionLineType, - EnumMemberLineType, - EnumDefinitionEndLineType, - PaddingLineType, - UndefinedXrefLineType -}; - - enum TypeLinesFilteredReason { TypeLinesFilterNotApplied, @@ -45,20 +31,9 @@ enum TypeLinesFilteredReason }; -struct BINARYNINJAUIAPI TypeDefinitionLine -{ - TypeDefinitionLineType lineType; - std::vector<BinaryNinja::InstructionTextToken> tokens; - TypeRef type, rootType; - std::string rootTypeName; - uint64_t offset; - size_t fieldIndex; -}; - - struct BINARYNINJAUIAPI TypeDefinitionLinesAndFilterStatus { - std::vector<TypeDefinitionLine> lines; + std::vector<BinaryNinja::TypeDefinitionLine> lines; TypeLinesFilteredReason reason; }; @@ -141,7 +116,7 @@ class BINARYNINJAUIAPI TypeView : public QAbstractScrollArea, public View, publi // m_typeLines are the types being displayed in the typeview (with filter applied) // m_allTypeLines are the lines and filter status of all types in the data - std::map<BinaryNinja::QualifiedName, std::vector<TypeDefinitionLine>> m_typeLines; + std::map<BinaryNinja::QualifiedName, std::vector<BinaryNinja::TypeDefinitionLine>> m_typeLines; std::map<BinaryNinja::QualifiedName, TypeDefinitionLinesAndFilterStatus> m_allTypeLines; std::vector<TypeLineIndex> m_types; @@ -195,8 +170,6 @@ class BINARYNINJAUIAPI TypeView : public QAbstractScrollArea, public View, publi void checkForValidSelection(); - static TypeDefinitionLine getTypeDefinitionHeaderLine(PlatformRef platform, const std::string& name, TypeRef type); - public: explicit TypeView(BinaryViewRef data, ViewFrame* view, TypesContainer* container, bool compact = false); virtual ~TypeView(); @@ -266,8 +239,6 @@ class BINARYNINJAUIAPI TypeView : public QAbstractScrollArea, public View, publi { return m_collapsedTypes.find(name) != m_collapsedTypes.end(); } - static std::vector<TypeDefinitionLine> getLinesForType(const std::string& name, const std::string& varName, - size_t index, TypeRef type, TypeRef parent, BinaryViewRef data, int paddingCols, bool collapsed = false); void showContextMenu(Menu* source = nullptr); @@ -363,7 +334,7 @@ class BINARYNINJAUIAPI TypeFilter : public QWidget TypeFilterEdit* m_textFilter; bool MatchesAutoFilter(BinaryViewRef data, const BinaryNinja::QualifiedName& name); - bool MatchesTextFilter(const std::vector<TypeDefinitionLine>& lines); + bool MatchesTextFilter(const std::vector<BinaryNinja::TypeDefinitionLine>& lines); Q_SIGNALS: void filterChanged(); @@ -376,7 +347,7 @@ class BINARYNINJAUIAPI TypeFilter : public QWidget void setContainer(TypesContainer* container) { m_container = container; } TypeLinesFilteredReason checkTypeLinesForFilter( - BinaryViewRef data, const BinaryNinja::QualifiedName& name, const std::vector<TypeDefinitionLine>& lines); + BinaryViewRef data, const BinaryNinja::QualifiedName& name, const std::vector<BinaryNinja::TypeDefinitionLine>& lines); void showAndFocus(); bool areAutoTypesVisible(); void setShowAutoTypes(bool showAutoTypes); |
