From 1f6c09e54ab53403fe0236c46f69b896713abddc Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 16 Jan 2017 17:53:34 -0500 Subject: Fix lint issues --- python/binaryview.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'python/binaryview.py') diff --git a/python/binaryview.py b/python/binaryview.py index 34be139d..cf30d78d 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -250,16 +250,16 @@ class BinaryDataNotificationCallbacks(object): def _type_defined(self, ctxt, name, type_obj): try: qualified_name = types.QualifiedName._from_core_struct(name[0]) - self.notify.type_defined(self.view, qualified_name, Type(core.BNNewTypeReference(type_obj))) + self.notify.type_defined(self.view, qualified_name, types.Type(core.BNNewTypeReference(type_obj))) except: - log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _type_undefined(self, ctxt, name, type_obj): try: qualified_name = types.QualifiedName._from_core_struct(name[0]) - self.notify.type_undefined(self.view, qualified_name, Type(core.BNNewTypeReference(type_obj))) + self.notify.type_undefined(self.view, qualified_name, types.Type(core.BNNewTypeReference(type_obj))) except: - log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) class _BinaryViewTypeMetaclass(type): -- cgit v1.3.1 From ded271158000d7fa509f513b425d95390a7f2058 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 17 Jan 2017 18:44:51 -0500 Subject: Add missing Python APIs --- python/architecture.py | 6 ++++- python/basicblock.py | 4 +++- python/binaryview.py | 6 +++-- python/function.py | 19 ++++++++++++---- python/lowlevelil.py | 4 +++- python/types.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 90 insertions(+), 11 deletions(-) (limited to 'python/binaryview.py') diff --git a/python/architecture.py b/python/architecture.py index 32d97b09..ea97f605 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -467,6 +467,8 @@ class Architecture(object): token_buf[i].value = tokens[i].value token_buf[i].size = tokens[i].size token_buf[i].operand = tokens[i].operand + token_buf[i].context = tokens[i].context + token_buf[i].address = tokens[i].address result[0] = token_buf ptr = ctypes.cast(token_buf, ctypes.c_void_p) self._pending_token_lists[ptr.value] = (ptr.value, token_buf) @@ -1148,7 +1150,9 @@ class Architecture(object): value = tokens[i].value size = tokens[i].size operand = tokens[i].operand - result.append(function.InstructionTextToken(token_type, text, value, size, operand)) + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) core.BNFreeInstructionText(tokens, count.value) return result, length.value diff --git a/python/basicblock.py b/python/basicblock.py index ae9889fc..ffbcd217 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -200,7 +200,9 @@ class BasicBlock(object): value = lines[i].tokens[j].value size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand - tokens.append(function.InstructionTextToken(token_type, text, value, size, operand)) + context = lines[i].tokens[j].context + address = lines[i].tokens[j].address + tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) result.append(function.DisassemblyTextLine(addr, tokens)) core.BNFreeDisassemblyTextLines(lines, count.value) return result diff --git a/python/binaryview.py b/python/binaryview.py index cf30d78d..f8fe1fde 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -1886,7 +1886,7 @@ class BinaryView(object): var = core.BNDataVariable() if not core.BNGetDataVariableAtAddress(self.handle, addr, var): return None - return DataVariable(var.address, type.Type(var.type), var.autoDiscovered) + return DataVariable(var.address, types.Type(var.type), var.autoDiscovered) def get_function_at(self, addr, plat=None): """ @@ -2750,7 +2750,9 @@ class BinaryView(object): value = lines[i].contents.tokens[j].value size = lines[i].contents.tokens[j].size operand = lines[i].contents.tokens[j].operand - tokens.append(function.InstructionTextToken(token_type, text, value, size, operand)) + context = lines[i].contents.tokens[j].context + address = lines[i].contents.tokens[j].address + tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) contents = function.DisassemblyTextLine(addr, tokens) result.append(lineardisassembly.LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents)) diff --git a/python/function.py b/python/function.py index 7d03585c..5f9f475a 100644 --- a/python/function.py +++ b/python/function.py @@ -26,7 +26,7 @@ import ctypes import _binaryninjacore as core from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType, HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend, - DisassemblyOption, IntegerDisplayType) + DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext) import architecture import highlight import associateddatastore @@ -669,7 +669,9 @@ class Function(object): value = lines[i].tokens[j].value size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand - tokens.append(InstructionTextToken(token_type, text, value, size, operand)) + context = lines[i].tokens[j].context + address = lines[i].tokens[j].address + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) result.append(tokens) core.BNFreeInstructionTextLines(lines, count.value) return result @@ -916,7 +918,9 @@ class FunctionGraphBlock(object): value = lines[i].tokens[j].value size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand - tokens.append(InstructionTextToken(token_type, text, value, size, operand)) + context = lines[i].tokens[j].context + address = lines[i].tokens[j].address + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) result.append(DisassemblyTextLine(addr, tokens)) core.BNFreeDisassemblyTextLines(lines, count.value) return result @@ -966,7 +970,9 @@ class FunctionGraphBlock(object): value = lines[i].tokens[j].value size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand - tokens.append(InstructionTextToken(token_type, text, value, size, operand)) + context = lines[i].tokens[j].context + address = lines[i].tokens[j].address + tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address)) yield DisassemblyTextLine(addr, tokens) finally: core.BNFreeDisassemblyTextLines(lines, count.value) @@ -1237,12 +1243,15 @@ class InstructionTextToken(object): ========================== ============================================ """ - def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff): + def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff, + context = InstructionTextTokenContext.NoTokenContext, address = 0): self.type = InstructionTextTokenType(token_type) self.text = text self.value = value self.size = size self.operand = operand + self.context = InstructionTextTokenContext(context) + self.address = address def __str__(self): return self.text diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 419e8513..29b46b65 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -187,7 +187,9 @@ class LowLevelILInstruction(object): value = tokens[i].value size = tokens[i].size operand = tokens[i].operand - result.append(function.InstructionTextToken(token_type, text, value, size, operand)) + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) core.BNFreeInstructionText(tokens, count.value) return result diff --git a/python/types.py b/python/types.py index 0470ea73..1dd2157e 100644 --- a/python/types.py +++ b/python/types.py @@ -22,8 +22,9 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from enums import SymbolType, TypeClass, NamedTypeReferenceClass +from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType import callingconvention +import function class QualifiedName(object): @@ -317,6 +318,56 @@ class Type(object): def get_string_after_name(self): return core.BNGetTypeStringAfterName(self.handle) + @property + def tokens(self): + """Type string as a list of tokens (read-only)""" + count = ctypes.c_ulonglong() + tokens = core.BNGetTypeTokens(self.handle, count) + result = [] + for i in xrange(0, count.value): + token_type = InstructionTextTokenType(tokens[i].type) + text = tokens[i].text + value = tokens[i].value + size = tokens[i].size + operand = tokens[i].operand + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) + core.BNFreeTokenList(tokens, count.value) + return result + + def get_tokens_before_name(self): + count = ctypes.c_ulonglong() + tokens = core.BNGetTypeTokensBeforeName(self.handle, count) + result = [] + for i in xrange(0, count.value): + token_type = InstructionTextTokenType(tokens[i].type) + text = tokens[i].text + value = tokens[i].value + size = tokens[i].size + operand = tokens[i].operand + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) + core.BNFreeTokenList(tokens, count.value) + return result + + def get_tokens_after_name(self): + count = ctypes.c_ulonglong() + tokens = core.BNGetTypeTokensAfterName(self.handle, count) + result = [] + for i in xrange(0, count.value): + token_type = InstructionTextTokenType(tokens[i].type) + text = tokens[i].text + value = tokens[i].value + size = tokens[i].size + operand = tokens[i].operand + context = tokens[i].context + address = tokens[i].address + result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address)) + core.BNFreeTokenList(tokens, count.value) + return result + @classmethod def void(cls): return Type(core.BNCreateVoidType()) @@ -518,6 +569,9 @@ class Structure(object): def remove(self, i): core.BNRemoveStructureMember(self.handle, i) + def replace(self, i, t, name = ""): + core.BNReplaceStructureMember(self.handle, i, t.handle, name) + class EnumerationMember(object): def __init__(self, name, value, default): @@ -565,6 +619,12 @@ class Enumeration(object): else: core.BNAddEnumerationMemberWithValue(self.handle, name, value) + def remove(self, i): + core.BNRemoveEnumerationMember(self.handle, i) + + def replace(self, i, name, value): + core.BNReplaceEnumerationMember(self.handle, i, name, value) + class TypeParserResult(object): def __init__(self, types, variables, functions): -- cgit v1.3.1 From c6ed1dd374515d0e23a9d627a7dfb659c7981d16 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 19 Jan 2017 21:15:32 -0500 Subject: Add API to find virtual address from file offset --- binaryninjaapi.h | 1 + binaryninjacore.h | 1 + binaryview.cpp | 6 ++++++ python/binaryview.py | 6 ++++++ 4 files changed, 14 insertions(+) (limited to 'python/binaryview.py') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index afbff4da..4e3f3d57 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1050,6 +1050,7 @@ namespace BinaryNinja void RemoveUserSegment(uint64_t start, uint64_t length); std::vector GetSegments(); bool GetSegmentAt(uint64_t addr, Segment& result); + bool GetAddressForDataOffset(uint64_t offset, uint64_t& addr); void AddAutoSection(const std::string& name, uint64_t start, uint64_t length, const std::string& type = "", uint64_t align = 1, uint64_t entrySize = 0, const std::string& linkedSection = "", diff --git a/binaryninjacore.h b/binaryninjacore.h index 02f753cf..7d3bc14c 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1420,6 +1420,7 @@ extern "C" BINARYNINJACOREAPI BNSegment* BNGetSegments(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI void BNFreeSegmentList(BNSegment* segments); BINARYNINJACOREAPI bool BNGetSegmentAt(BNBinaryView* view, uint64_t addr, BNSegment* result); + BINARYNINJACOREAPI bool BNGetAddressForDataOffset(BNBinaryView* view, uint64_t offset, uint64_t* addr); BINARYNINJACOREAPI void BNAddAutoSection(BNBinaryView* view, const char* name, uint64_t start, uint64_t length, const char* type, uint64_t align, uint64_t entrySize, const char* linkedSection, const char* infoSection, diff --git a/binaryview.cpp b/binaryview.cpp index bef23750..cc8bb733 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1645,6 +1645,12 @@ bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result) } +bool BinaryView::GetAddressForDataOffset(uint64_t offset, uint64_t& addr) +{ + return BNGetAddressForDataOffset(m_object, offset, &addr); +} + + void BinaryView::AddAutoSection(const string& name, uint64_t start, uint64_t length, const string& type, uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection, uint64_t infoData) { diff --git a/python/binaryview.py b/python/binaryview.py index f8fe1fde..ba706fe5 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -3052,6 +3052,12 @@ class BinaryView(object): segment.flags) return result + def get_address_for_data_offset(self, offset): + address = ctypes.c_ulonglong() + if not core.BNGetAddressForDataOffset(self.handle, offset, address): + return None + return address.value + def add_auto_section(self, name, start, length, type = "", align = 1, entry_size = 1, linked_section = "", info_section = "", info_data = 0): core.BNAddAutoSection(self.handle, name, start, length, type, align, entry_size, linked_section, -- cgit v1.3.1 From 8df9a34dd67c852626432c84a5007be3173c33e0 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 6 Feb 2017 22:27:42 -0500 Subject: Add type IDs for types to track across renames --- binaryninjaapi.cpp | 9 ++++ binaryninjaapi.h | 27 +++++++++-- binaryninjacore.h | 19 ++++++-- binaryview.cpp | 54 +++++++++++++++++++--- python/__init__.py | 4 ++ python/binaryview.py | 126 ++++++++++++++++++++++++++++++++++++++++++++------- python/types.py | 63 +++++++++++++++++++++++--- type.cpp | 90 +++++++++++++++++++++++++++++++++++- 8 files changed, 354 insertions(+), 38 deletions(-) (limited to 'python/binaryview.py') diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index e1dab528..099f35eb 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -237,3 +237,12 @@ void BinaryNinja::SetWorkerThreadCount(size_t count) { BNSetWorkerThreadCount(count); } + + +string BinaryNinja::GetUniqueIdentifierString() +{ + char* str = BNGetUniqueIdentifierString(); + string result = str; + BNFreeString(str); + return result; +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 4e3f3d57..92eeba30 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -409,6 +409,8 @@ namespace BinaryNinja BNMessageBoxButtonResult ShowMessageBox(const std::string& title, const std::string& text, BNMessageBoxButtonSet buttons = OKButtonSet, BNMessageBoxIcon icon = InformationIcon); + std::string GetUniqueIdentifierString(); + class QualifiedName { std::vector m_name; @@ -1027,11 +1029,15 @@ namespace BinaryNinja std::map> GetTypes(); Ref GetTypeByName(const QualifiedName& name); + Ref GetTypeById(const std::string& id); + std::string GetTypeId(const QualifiedName& name); + QualifiedName GetTypeNameById(const std::string& id); bool IsTypeAutoDefined(const QualifiedName& name); - void DefineType(const QualifiedName& name, Ref type); + QualifiedName DefineType(const std::string& id, const QualifiedName& defaultName, Ref type); void DefineUserType(const QualifiedName& name, Ref type); - void UndefineType(const QualifiedName& name); + void UndefineType(const std::string& id); void UndefineUserType(const QualifiedName& name); + void RenameType(const QualifiedName& oldName, const QualifiedName& newName); bool FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = NoFindFlags); @@ -1611,12 +1617,18 @@ namespace BinaryNinja static Ref StructureType(Structure* strct); static Ref NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1); static Ref NamedType(const QualifiedName& name, Type* type); + static Ref NamedType(const std::string& id, const QualifiedName& name, Type* type); + static Ref NamedType(BinaryView* view, const QualifiedName& name); static Ref EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0, bool issigned = false); static Ref PointerType(Architecture* arch, Type* type, bool cnst = false, bool vltl = false, BNReferenceType refType = PointerReferenceType); static Ref ArrayType(Type* type, uint64_t elem); static Ref FunctionType(Type* returnValue, CallingConvention* callingConvention, const std::vector& params, bool varArg = false); + + static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name); + static std::string GenerateAutoPlatformTypeId(const QualifiedName& name); + static std::string GenerateAutoDemangledTypeId(const QualifiedName& name); }; class NamedTypeReference: public CoreRefCountObject GenerateAutoTypeReference(BNNamedTypeReferenceClass cls, + const std::string& source, const QualifiedName& name); + static Ref GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name); + static Ref GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name); }; struct StructureMember diff --git a/binaryninjacore.h b/binaryninjacore.h index 7d3bc14c..b454da64 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1234,6 +1234,8 @@ extern "C" BINARYNINJACOREAPI void BNRegisterObjectDestructionCallbacks(BNObjectDestructionCallbacks* callbacks); BINARYNINJACOREAPI void BNUnregisterObjectDestructionCallbacks(BNObjectDestructionCallbacks* callbacks); + BINARYNINJACOREAPI char* BNGetUniqueIdentifierString(void); + // Plugin initialization BINARYNINJACOREAPI void BNInitCorePlugins(void); BINARYNINJACOREAPI void BNInitUserPlugins(void); @@ -1807,11 +1809,19 @@ extern "C" BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI void BNFreeTypeList(BNQualifiedNameAndType* types, size_t count); BINARYNINJACOREAPI BNType* BNGetAnalysisTypeByName(BNBinaryView* view, BNQualifiedName* name); + BINARYNINJACOREAPI BNType* BNGetAnalysisTypeById(BNBinaryView* view, const char* id); + BINARYNINJACOREAPI char* BNGetAnalysisTypeId(BNBinaryView* view, BNQualifiedName* name); + BINARYNINJACOREAPI BNQualifiedName BNGetAnalysisTypeNameById(BNBinaryView* view, const char* id); BINARYNINJACOREAPI bool BNIsAnalysisTypeAutoDefined(BNBinaryView* view, BNQualifiedName* name); - BINARYNINJACOREAPI void BNDefineAnalysisType(BNBinaryView* view, BNQualifiedName* name, BNType* type); + BINARYNINJACOREAPI BNQualifiedName BNDefineAnalysisType(BNBinaryView* view, const char* id, + BNQualifiedName* defaultName, BNType* type); BINARYNINJACOREAPI void BNDefineUserAnalysisType(BNBinaryView* view, BNQualifiedName* name, BNType* type); - BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, BNQualifiedName* name); + BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char* id); BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, BNQualifiedName* name); + BINARYNINJACOREAPI void BNRenameAnalysisType(BNBinaryView* view, BNQualifiedName* oldName, BNQualifiedName* newName); + BINARYNINJACOREAPI char* BNGenerateAutoTypeId(const char* source, BNQualifiedName* name); + BINARYNINJACOREAPI char* BNGenerateAutoPlatformTypeId(BNQualifiedName* name); + BINARYNINJACOREAPI char* BNGenerateAutoDemangledTypeId(BNQualifiedName* name); BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view); BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func); @@ -2006,10 +2016,13 @@ extern "C" BINARYNINJACOREAPI void BNFreeTokenList(BNInstructionTextToken* tokens, size_t count); BINARYNINJACOREAPI BNType* BNCreateNamedTypeReference(BNNamedTypeReference* nt, size_t width, size_t align); - BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromType(BNQualifiedName* name, BNType* type); + BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromTypeAndId(const char* id, BNQualifiedName* name, BNType* type); + BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromType(BNBinaryView* view, BNQualifiedName* name); BINARYNINJACOREAPI BNNamedTypeReference* BNCreateNamedType(void); BINARYNINJACOREAPI void BNSetTypeReferenceClass(BNNamedTypeReference* nt, BNNamedTypeReferenceClass cls); BINARYNINJACOREAPI BNNamedTypeReferenceClass BNGetTypeReferenceClass(BNNamedTypeReference* nt); + BINARYNINJACOREAPI void BNSetTypeReferenceId(BNNamedTypeReference* nt, const char* id); + BINARYNINJACOREAPI char* BNGetTypeReferenceId(BNNamedTypeReference* nt); BINARYNINJACOREAPI void BNSetTypeReferenceName(BNNamedTypeReference* nt, BNQualifiedName* name); BINARYNINJACOREAPI BNQualifiedName BNGetTypeReferenceName(BNNamedTypeReference* nt); BINARYNINJACOREAPI void BNFreeQualifiedName(BNQualifiedName* name); diff --git a/binaryview.cpp b/binaryview.cpp index cc8bb733..1b1574e1 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1496,6 +1496,35 @@ Ref BinaryView::GetTypeByName(const QualifiedName& name) } +Ref BinaryView::GetTypeById(const string& id) +{ + BNType* type = BNGetAnalysisTypeById(m_object, id.c_str()); + if (!type) + return nullptr; + return new Type(type); +} + + +QualifiedName BinaryView::GetTypeNameById(const string& id) +{ + BNQualifiedName name = BNGetAnalysisTypeNameById(m_object, id.c_str()); + QualifiedName result = QualifiedName::FromAPIObject(&name); + BNFreeQualifiedName(&name); + return result; +} + + +string BinaryView::GetTypeId(const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + char* id = BNGetAnalysisTypeId(m_object, &nameObj); + QualifiedName::FreeAPIObject(&nameObj); + string result = id; + BNFreeString(id); + return result; +} + + bool BinaryView::IsTypeAutoDefined(const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); @@ -1505,11 +1534,14 @@ bool BinaryView::IsTypeAutoDefined(const QualifiedName& name) } -void BinaryView::DefineType(const QualifiedName& name, Ref type) +QualifiedName BinaryView::DefineType(const string& id, const QualifiedName& defaultName, Ref type) { - BNQualifiedName nameObj = name.GetAPIObject(); - BNDefineAnalysisType(m_object, &nameObj, type->GetObject()); + BNQualifiedName nameObj = defaultName.GetAPIObject(); + BNQualifiedName regName = BNDefineAnalysisType(m_object, id.c_str(), &nameObj, type->GetObject()); QualifiedName::FreeAPIObject(&nameObj); + QualifiedName result = QualifiedName::FromAPIObject(®Name); + BNFreeQualifiedName(®Name); + return result; } @@ -1521,11 +1553,9 @@ void BinaryView::DefineUserType(const QualifiedName& name, Ref type) } -void BinaryView::UndefineType(const QualifiedName& name) +void BinaryView::UndefineType(const string& id) { - BNQualifiedName nameObj = name.GetAPIObject(); - BNUndefineAnalysisType(m_object, &nameObj); - QualifiedName::FreeAPIObject(&nameObj); + BNUndefineAnalysisType(m_object, id.c_str()); } @@ -1537,6 +1567,16 @@ void BinaryView::UndefineUserType(const QualifiedName& name) } +void BinaryView::RenameType(const QualifiedName& oldName, const QualifiedName& newName) +{ + BNQualifiedName oldNameObj = oldName.GetAPIObject(); + BNQualifiedName newNameObj = newName.GetAPIObject(); + BNRenameAnalysisType(m_object, &oldNameObj, &newNameObj); + QualifiedName::FreeAPIObject(&oldNameObj); + QualifiedName::FreeAPIObject(&newNameObj); +} + + bool BinaryView::FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags) { return BNFindNextData(m_object, start, data.GetBufferObject(), &result, flags); diff --git a/python/__init__.py b/python/__init__.py index a1ea02f5..9b87aa47 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -51,6 +51,10 @@ def shutdown(): core.BNShutdown() +def get_unique_identifier(): + return core.BNGetUniqueIdentifierString() + + class _DestructionCallbackHandler(object): def __init__(self): self._cb = core.BNObjectDestructionCallbacks() diff --git a/python/binaryview.py b/python/binaryview.py index ba706fe5..2cdacb4c 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -2881,7 +2881,7 @@ class BinaryView(object): :Example: >>> type, name = bv.parse_type_string("int foo") - >>> bv.define_type(name, type) + >>> bv.define_user_type(name, type) >>> bv.get_type_by_name(name) >>> @@ -2892,6 +2892,71 @@ class BinaryView(object): return None return types.Type(obj) + def get_type_by_id(self, id): + """ + ``get_type_by_id`` returns the defined type whose unique identifier corresponds with the provided ``id`` + + :param str id: Unique identifier to lookup + :return: A :py:Class:`Type` or None if the type does not exist + :rtype: Type or None + :Example: + + >>> type, name = bv.parse_type_string("int foo") + >>> type_id = Type.generate_auto_type_id("source", name) + >>> bv.define_type(type_id, name, type) + >>> bv.get_type_by_id(type_id) + + >>> + """ + obj = core.BNGetAnalysisTypeById(self.handle, id) + if not obj: + return None + return types.Type(obj) + + def get_type_name_by_id(self, id): + """ + ``get_type_name_by_id`` returns the defined type name whose unique identifier corresponds with the provided ``id`` + + :param str id: Unique identifier to lookup + :return: A QualifiedName or None if the type does not exist + :rtype: QualifiedName or None + :Example: + + >>> type, name = bv.parse_type_string("int foo") + >>> type_id = Type.generate_auto_type_id("source", name) + >>> bv.define_type(type_id, name, type) + 'foo' + >>> bv.get_type_name_by_id(type_id) + 'foo' + >>> + """ + name = core.BNGetAnalysisTypeNameById(self.handle, id) + result = types.QualifiedName._from_core_struct(name) + core.BNFreeQualifiedName(name) + if len(result) == 0: + return None + return result + + def get_type_id(self, name): + """ + ``get_type_id`` returns the unique indentifier of the defined type whose name corresponds with the + provided ``name`` + + :param QualifiedName name: Type name to lookup + :return: The unique identifier of the type + :rtype: str + :Example: + + >>> type, name = bv.parse_type_string("int foo") + >>> type_id = Type.generate_auto_type_id("source", name) + >>> registered_name = bv.define_type(type_id, name, type) + >>> bv.get_type_id(registered_name) == type_id + True + >>> + """ + name = types.QualifiedName(name)._get_core_struct() + return core.BNGetAnalysisTypeId(self.handle, name) + def is_type_auto_defined(self, name): """ ``is_type_auto_defined`` queries the user type list of name. If name is not in the *user* type list then the name @@ -2910,23 +2975,28 @@ class BinaryView(object): name = types.QualifiedName(name)._get_core_struct() return core.BNIsAnalysisTypeAutoDefined(self.handle, name) - def define_type(self, name, type_obj): + def define_type(self, type_id, default_name, type_obj): """ ``define_type`` registers a :py:Class:`Type` ``type_obj`` of the given ``name`` in the global list of types for - the current :py:Class:`BinaryView`. + the current :py:Class:`BinaryView`. This method should only be used for automatically generated types. - :param QualifiedName name: Name of the type to be registered + :param str type_id: Unique identifier for the automatically generated type + :param QualifiedName default_name: Name of the type to be registered :param Type type_obj: Type object to be registered - :rtype: None + :return: Registered name of the type. May not be the same as the requested name if the user has renamed types. + :rtype: QualifiedName :Example: >>> type, name = bv.parse_type_string("int foo") - >>> bv.define_type(name, type) - >>> bv.get_type_by_name(name) + >>> registered_name = bv.define_type(Type.generate_auto_type_id("source", name), name, type) + >>> bv.get_type_by_name(registered_name) """ - name = types.QualifiedName(name)._get_core_struct() - core.BNDefineAnalysisType(self.handle, name, type_obj.handle) + name = types.QualifiedName(default_name)._get_core_struct() + reg_name = core.BNDefineAnalysisType(self.handle, type_id, name, type_obj.handle) + result = types.QualifiedName._from_core_struct(reg_name) + core.BNFreeQualifiedName(reg_name) + return result def define_user_type(self, name, type_obj): """ @@ -2946,24 +3016,24 @@ class BinaryView(object): name = types.QualifiedName(name)._get_core_struct() core.BNDefineUserAnalysisType(self.handle, name, type_obj.handle) - def undefine_type(self, name): + def undefine_type(self, type_id): """ ``undefine_type`` removes a :py:Class:`Type` from the global list of types for the current :py:Class:`BinaryView` - :param QualifiedName name: Name of type to be undefined + :param str type_id: Unique identifier of type to be undefined :rtype: None :Example: >>> type, name = bv.parse_type_string("int foo") - >>> bv.define_type(name, type) + >>> type_id = Type.generate_auto_type_id("source", name) + >>> bv.define_type(type_id, name, type) >>> bv.get_type_by_name(name) - >>> bv.undefine_type(name) + >>> bv.undefine_type(type_id) >>> bv.get_type_by_name(name) >>> """ - name = types.QualifiedName(name)._get_core_struct() - core.BNUndefineAnalysisType(self.handle, name) + core.BNUndefineAnalysisType(self.handle, type_id) def undefine_user_type(self, name): """ @@ -2975,16 +3045,38 @@ class BinaryView(object): :Example: >>> type, name = bv.parse_type_string("int foo") - >>> bv.define_type(name, type) + >>> bv.define_user_type(name, type) >>> bv.get_type_by_name(name) - >>> bv.undefine_type(name) + >>> bv.undefine_user_type(name) >>> bv.get_type_by_name(name) >>> """ name = types.QualifiedName(name)._get_core_struct() core.BNUndefineUserAnalysisType(self.handle, name) + def rename_type(self, old_name, new_name): + """ + ``rename_type`` renames a type in the global list of types for the current :py:Class:`BinaryView` + + :param QualifiedName old_name: Existing name of type to be renamed + :param QualifiedName new_name: New name of type to be renamed + :rtype: None + :Example: + + >>> type, name = bv.parse_type_string("int foo") + >>> bv.define_user_type(name, type) + >>> bv.get_type_by_name("foo") + + >>> bv.rename_type("foo", "bar") + >>> bv.get_type_by_name("bar") + + >>> + """ + old_name = types.QualifiedName(old_name)._get_core_struct() + new_name = types.QualifiedName(new_name)._get_core_struct() + core.BNRenameAnalysisType(self.handle, old_name, new_name) + def find_next_data(self, start, data, flags = 0): """ ``find_next_data`` searchs for the bytes in data starting at the virtual address ``start`` either, case-sensitive, diff --git a/python/types.py b/python/types.py index 1dd2157e..1cc02691 100644 --- a/python/types.py +++ b/python/types.py @@ -299,7 +299,7 @@ class Type(object): result = core.BNGetTypeNamedTypeReference(self.handle) if result is None: return None - return NamedTypeReference(result) + return NamedTypeReference(handle = result) @property def count(self): @@ -392,12 +392,24 @@ class Type(object): def named_type(self, named_type, width = 0, align = 1): return Type(core.BNCreateNamedTypeReference(named_type.handle, width, align)) + @classmethod + def named_type_from_type_and_id(self, type_id, name, t): + name = QualifiedName(name)._get_core_struct() + if t is not None: + t = t.handle + return Type(core.BNCreateNamedTypeReferenceFromTypeAndId(type_id, name, t)) + @classmethod def named_type_from_type(self, name, t): name = QualifiedName(name)._get_core_struct() if t is not None: t = t.handle - return Type(core.BNCreateNamedTypeReferenceFromType(name, t)) + return Type(core.BNCreateNamedTypeReferenceFromTypeAndId("", name, t)) + + @classmethod + def named_type_from_registered_type(self, view, name): + name = QualifiedName(name)._get_core_struct() + return Type(core.BNCreateNamedTypeReferenceFromType(view.handle, name)) @classmethod def enumeration_type(self, arch, e, width=None): @@ -428,6 +440,21 @@ class Type(object): return Type(core.BNCreateFunctionType(ret.handle, calling_convention, param_buf, len(params), variable_arguments)) + @classmethod + def generate_auto_type_id(self, source, name): + name = QualifiedName(name)._get_core_struct() + return core.BNGenerateAutoTypeId(source, name) + + @classmethod + def generate_auto_platform_type_id(self, name): + name = QualifiedName(name)._get_core_struct() + return core.BNGenerateAutoTypeId(name) + + @classmethod + def generate_auto_demangled_type_id(self, name): + name = QualifiedName(name)._get_core_struct() + return core.BNGenerateAutoTypeId(name) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -436,10 +463,12 @@ class Type(object): class NamedTypeReference(object): - def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, name = None, handle = None): + def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, type_id = None, name = None, handle = None): if handle is None: self.handle = core.BNCreateNamedType() core.BNSetTypeReferenceClass(self.handle, type_class) + if type_id is not None: + core.BNSetTypeReferenceId(self.handle, type_id) if name is not None: name = QualifiedName(name)._get_core_struct() core.BNSetTypeReferenceName(self.handle, name) @@ -451,16 +480,23 @@ class NamedTypeReference(object): @property def type_class(self): - return core.BNGetTypeReferenceClass(self.handle) + return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.handle)) @type_class.setter def type_class(self, value): core.BNSetTypeReferenceClass(self.handle, value) + @property + def type_id(self): + return core.BNGetTypeReferenceId(self.handle) + + @type_id.setter + def type_id(self, value): + core.BNSetTypeReferenceId(self.handle, value) + @property def name(self): - count = ctypes.c_ulonglong() - name = core.BNGetTypeReferenceName(self.handle, count) + name = core.BNGetTypeReferenceName(self.handle) result = QualifiedName._from_core_struct(name) core.BNFreeQualifiedName(name) return result @@ -481,6 +517,21 @@ class NamedTypeReference(object): return "" % str(self.name) return "" % str(self.name) + @classmethod + def generate_auto_type_ref(self, type_class, source, name): + type_id = Type.generate_auto_type_id(source, name) + return NamedTypeReference(type_class, type_id, name) + + @classmethod + def generate_auto_platform_type_ref(self, type_class, source, name): + type_id = Type.generate_auto_platform_type_id(source, name) + return NamedTypeReference(type_class, type_id, name) + + @classmethod + def generate_auto_demangled_type_ref(self, type_class, source, name): + type_id = Type.generate_auto_demangled_type_id(source, name) + return NamedTypeReference(type_class, type_id, name) + class StructureMember(object): def __init__(self, t, name, offset): diff --git a/type.cpp b/type.cpp index e71077e6..dd1fb8d6 100644 --- a/type.cpp +++ b/type.cpp @@ -511,9 +511,25 @@ Ref Type::NamedType(NamedTypeReference* ref, size_t width, size_t align) Ref Type::NamedType(const QualifiedName& name, Type* type) +{ + return NamedType("", name, type); +} + + +Ref Type::NamedType(const string& id, const QualifiedName& name, Type* type) { BNQualifiedName nameObj = name.GetAPIObject(); - Type* result = new Type(BNCreateNamedTypeReferenceFromType(&nameObj, type ? type->GetObject() : nullptr)); + Type* result = new Type(BNCreateNamedTypeReferenceFromTypeAndId(id.c_str(), &nameObj, + type ? type->GetObject() : nullptr)); + QualifiedName::FreeAPIObject(&nameObj); + return result; +} + + +Ref Type::NamedType(BinaryView* view, const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + Type* result = new Type(BNCreateNamedTypeReferenceFromType(view->GetObject(), &nameObj)); QualifiedName::FreeAPIObject(&nameObj); return result; } @@ -561,16 +577,47 @@ void Type::SetFunctionCanReturn(bool canReturn) } +string Type::GenerateAutoTypeId(const string& source, const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + string result = BNGenerateAutoTypeId(source.c_str(), &nameObj); + QualifiedName::FreeAPIObject(&nameObj); + return result; +} + + +string Type::GenerateAutoPlatformTypeId(const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + string result = BNGenerateAutoPlatformTypeId(&nameObj); + QualifiedName::FreeAPIObject(&nameObj); + return result; +} + + +string Type::GenerateAutoDemangledTypeId(const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + string result = BNGenerateAutoDemangledTypeId(&nameObj); + QualifiedName::FreeAPIObject(&nameObj); + return result; +} + + NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt) { m_object = nt; } -NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const QualifiedName& names) +NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const string& id, const QualifiedName& names) { m_object = BNCreateNamedType(); BNSetTypeReferenceClass(m_object, cls); + if (id.size() != 0) + { + BNSetTypeReferenceId(m_object, id.c_str()); + } if (names.size() != 0) { BNQualifiedName nameObj = names.GetAPIObject(); @@ -592,6 +639,21 @@ BNNamedTypeReferenceClass NamedTypeReference::GetTypeClass() const } +string NamedTypeReference::GetTypeId() const +{ + char* str = BNGetTypeReferenceId(m_object); + string result = str; + BNFreeString(str); + return result; +} + + +void NamedTypeReference::SetTypeId(const string& id) +{ + BNSetTypeReferenceId(m_object, id.c_str()); +} + + void NamedTypeReference::SetName(const QualifiedName& names) { BNQualifiedName nameObj = names.GetAPIObject(); @@ -609,6 +671,30 @@ QualifiedName NamedTypeReference::GetName() const } +Ref NamedTypeReference::GenerateAutoTypeReference(BNNamedTypeReferenceClass cls, + const string& source, const QualifiedName& name) +{ + string id = Type::GenerateAutoTypeId(source, name); + return new NamedTypeReference(cls, id, name); +} + + +Ref NamedTypeReference::GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name) +{ + string id = Type::GenerateAutoPlatformTypeId(name); + return new NamedTypeReference(cls, id, name); +} + + +Ref NamedTypeReference::GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name) +{ + string id = Type::GenerateAutoDemangledTypeId(name); + return new NamedTypeReference(cls, id, name); +} + + Structure::Structure() { m_object = BNCreateStructure(); -- cgit v1.3.1 From 898ec98d9858ddec7fb431ba304d996cec12ff68 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 9 Feb 2017 19:06:07 -0500 Subject: APIs for handling platform types --- architecture.cpp | 9 +++++---- binaryninjaapi.h | 17 ++++++++++++----- binaryninjacore.h | 16 ++++++++++------ binaryview.cpp | 6 ++++++ platform.cpp | 28 ++++++++++++++++++++++++++++ python/architecture.py | 12 ++++++++---- python/binaryview.py | 16 ++++++++++++++++ python/platform.py | 12 ++++++++++++ python/types.py | 18 ++++++------------ type.cpp | 26 +++++++++++--------------- 10 files changed, 114 insertions(+), 46 deletions(-) (limited to 'python/binaryview.py') diff --git a/architecture.cpp b/architecture.cpp index 0e25fa85..d72e7f42 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -747,7 +747,8 @@ void Architecture::SetBinaryViewTypeConstant(const string& type, const string& n bool Architecture::ParseTypesFromSource(const string& source, const string& fileName, map>& types, map>& variables, - map>& functions, string& errors, const vector& includeDirs) + map>& functions, string& errors, const vector& includeDirs, + const string& autoTypeSource) { BNTypeParserResult result; char* errorStr; @@ -761,7 +762,7 @@ bool Architecture::ParseTypesFromSource(const string& source, const string& file functions.clear(); bool ok = BNParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), &result, - &errorStr, includeDirList, includeDirs.size()); + &errorStr, includeDirList, includeDirs.size(), autoTypeSource.c_str()); errors = errorStr; BNFreeString(errorStr); if (!ok) @@ -789,7 +790,7 @@ bool Architecture::ParseTypesFromSource(const string& source, const string& file bool Architecture::ParseTypesFromSourceFile(const string& fileName, map>& types, map>& variables, map>& functions, - string& errors, const vector& includeDirs) + string& errors, const vector& includeDirs, const string& autoTypeSource) { BNTypeParserResult result; char* errorStr; @@ -803,7 +804,7 @@ bool Architecture::ParseTypesFromSourceFile(const string& fileName, map>& types, std::map>& variables, std::map>& functions, std::string& errors, - const std::vector& includeDirs = std::vector()); + const std::vector& includeDirs = std::vector(), + const std::string& autoTypeSource = ""); bool ParseTypesFromSourceFile(const std::string& fileName, std::map>& types, std::map>& variables, std::map>& functions, std::string& errors, - const std::vector& includeDirs = std::vector()); + const std::vector& includeDirs = std::vector(), + const std::string& autoTypeSource = ""); void RegisterCallingConvention(CallingConvention* cc); std::vector> GetCallingConventions(); @@ -1627,8 +1631,8 @@ namespace BinaryNinja const std::vector& params, bool varArg = false); static std::string GenerateAutoTypeId(const std::string& source, const QualifiedName& name); - static std::string GenerateAutoPlatformTypeId(const QualifiedName& name); static std::string GenerateAutoDemangledTypeId(const QualifiedName& name); + static std::string GetAutoDemangledTypeIdSource(); }; class NamedTypeReference: public CoreRefCountObject GenerateAutoTypeReference(BNNamedTypeReferenceClass cls, const std::string& source, const QualifiedName& name); - static Ref GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, - const QualifiedName& name); static Ref GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls, const QualifiedName& name); }; @@ -2339,6 +2341,11 @@ namespace BinaryNinja Ref GetRelatedPlatform(Architecture* arch); void AddRelatedPlatform(Architecture* arch, Platform* platform); Ref GetAssociatedPlatformByAddress(uint64_t& addr); + + std::string GenerateAutoPlatformTypeId(const QualifiedName& name); + Ref GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name); + std::string GetAutoPlatformTypeIdSource(); }; class ScriptingOutputListener diff --git a/binaryninjacore.h b/binaryninjacore.h index b454da64..4b810002 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1820,8 +1820,12 @@ extern "C" BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, BNQualifiedName* name); BINARYNINJACOREAPI void BNRenameAnalysisType(BNBinaryView* view, BNQualifiedName* oldName, BNQualifiedName* newName); BINARYNINJACOREAPI char* BNGenerateAutoTypeId(const char* source, BNQualifiedName* name); - BINARYNINJACOREAPI char* BNGenerateAutoPlatformTypeId(BNQualifiedName* name); + BINARYNINJACOREAPI char* BNGenerateAutoPlatformTypeId(BNPlatform* platform, BNQualifiedName* name); BINARYNINJACOREAPI char* BNGenerateAutoDemangledTypeId(BNQualifiedName* name); + BINARYNINJACOREAPI char* BNGetAutoPlatformTypeIdSource(BNPlatform* platform); + BINARYNINJACOREAPI char* BNGetAutoDemangledTypeIdSource(void); + + BINARYNINJACOREAPI void BNRegisterPlatformTypes(BNBinaryView* view, BNPlatform* platform); BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view); BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func); @@ -2063,13 +2067,13 @@ extern "C" // Source code processing BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors, - const char** includeDirs, size_t includeDirCount); + const char** includeDirs, size_t includeDirCount); BINARYNINJACOREAPI bool BNParseTypesFromSource(BNArchitecture* arch, const char* source, const char* fileName, - BNTypeParserResult* result, char** errors, - const char** includeDirs, size_t includeDirCount); + BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount, + const char* autoTypeSource); BINARYNINJACOREAPI bool BNParseTypesFromSourceFile(BNArchitecture* arch, const char* fileName, - BNTypeParserResult* result, char** errors, - const char** includeDirs, size_t includeDirCount); + BNTypeParserResult* result, char** errors, const char** includeDirs, size_t includeDirCount, + const char* autoTypeSource); BINARYNINJACOREAPI void BNFreeTypeParserResult(BNTypeParserResult* result); // Updates diff --git a/binaryview.cpp b/binaryview.cpp index 1b1574e1..8edbc2bf 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1577,6 +1577,12 @@ void BinaryView::RenameType(const QualifiedName& oldName, const QualifiedName& n } +void BinaryView::RegisterPlatformTypes(Platform* platform) +{ + BNRegisterPlatformTypes(m_object, platform->GetObject()); +} + + bool BinaryView::FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags) { return BNFindNextData(m_object, start, data.GetBufferObject(), &result, flags); diff --git a/platform.cpp b/platform.cpp index 7a6571cc..3bf4c0a4 100644 --- a/platform.cpp +++ b/platform.cpp @@ -253,3 +253,31 @@ Ref Platform::GetAssociatedPlatformByAddress(uint64_t& addr) return nullptr; return new Platform(platform); } + + +string Platform::GenerateAutoPlatformTypeId(const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + char* str = BNGenerateAutoPlatformTypeId(m_object, &nameObj); + string result = str; + QualifiedName::FreeAPIObject(&nameObj); + BNFreeString(str); + return result; +} + + +Ref Platform::GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, + const QualifiedName& name) +{ + string id = GenerateAutoPlatformTypeId(name); + return new NamedTypeReference(cls, id, name); +} + + +string Platform::GetAutoPlatformTypeIdSource() +{ + char* str = BNGetAutoPlatformTypeIdSource(m_object); + string result = str; + BNFreeString(str); + return result; +} diff --git a/python/architecture.py b/python/architecture.py index ea97f605..4cd0c597 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -1585,7 +1585,7 @@ class Architecture(object): """ core.BNSetBinaryViewTypeArchitectureConstant(self.handle, type_name, const_name, value) - def parse_types_from_source(self, source, filename=None, include_dirs=[]): + def parse_types_from_source(self, source, filename=None, include_dirs=[], auto_type_source=None): """ ``parse_types_from_source`` parses the source string and any needed headers searching for them in the optional list of directories provided in ``include_dirs``. @@ -1593,6 +1593,7 @@ class Architecture(object): :param str source: source string to be parsed :param str filename: optional source filename :param list(str) include_dirs: optional list of string filename include directories + :param str auto_type_source: optional source of types if used for automatically generated types :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error) :rtype: TypeParserResult :Example: @@ -1610,7 +1611,8 @@ class Architecture(object): dir_buf[i] = str(include_dirs[i]) parse = core.BNTypeParserResult() errors = ctypes.c_char_p() - result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf, len(include_dirs)) + result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf, + len(include_dirs), auto_type_source) error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) if not result: @@ -1630,13 +1632,14 @@ class Architecture(object): core.BNFreeTypeParserResult(parse) return types.TypeParserResult(type_dict, variables, functions) - def parse_types_from_source_file(self, filename, include_dirs=[]): + def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None): """ ``parse_types_from_source_file`` parses the source file ``filename`` and any needed headers searching for them in the optional list of directories provided in ``include_dirs``. :param str filename: filename of file to be parsed :param list(str) include_dirs: optional list of string filename include directories + :param str auto_type_source: optional source of types if used for automatically generated types :return: py:class:`TypeParserResult` (a SyntaxError is thrown on parse error) :rtype: TypeParserResult :Example: @@ -1654,7 +1657,8 @@ class Architecture(object): dir_buf[i] = str(include_dirs[i]) parse = core.BNTypeParserResult() errors = ctypes.c_char_p() - result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf, len(include_dirs)) + result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf, + len(include_dirs), auto_type_source) error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) if not result: diff --git a/python/binaryview.py b/python/binaryview.py index 2cdacb4c..caa5d780 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -3077,6 +3077,22 @@ class BinaryView(object): new_name = types.QualifiedName(new_name)._get_core_struct() core.BNRenameAnalysisType(self.handle, old_name, new_name) + def register_platform_types(self, platform): + """ + ``register_platform_types`` ensures that the platform-specific types for a :py:Class:`Platform` are available + for the current :py:Class:`BinaryView`. This is automatically performed when adding a new function or setting + the default platform. + + :param Platform platform: Platform containing types to be registered + :rtype: None + :Example: + + >>> platform = Platform["linux-x86"] + >>> bv.register_platform_types(platform) + >>> + """ + core.BNRegisterPlatformTypes(self.handle, platform.handle) + def find_next_data(self, start, data, flags = 0): """ ``find_next_data`` searchs for the bytes in data starting at the virtual address ``start`` either, case-sensitive, diff --git a/python/platform.py b/python/platform.py index 04dce587..5d90997d 100644 --- a/python/platform.py +++ b/python/platform.py @@ -25,6 +25,7 @@ import _binaryninjacore as core import startup import architecture import callingconvention +import types class _PlatformMetaClass(type): @@ -259,3 +260,14 @@ class Platform(object): new_addr.value = addr result = core.BNGetAssociatedPlatformByAddress(self.handle, new_addr) return Platform(None, handle = result), new_addr.value + + def generate_auto_platform_type_id(self, name): + name = types.QualifiedName(name)._get_core_struct() + return core.BNGenerateAutoPlatformTypeId(self.handle, name) + + def generate_auto_platform_type_ref(self, type_class, name): + type_id = self.generate_auto_platform_type_id(name) + return types.NamedTypeReference(type_class, type_id, name) + + def get_auto_platform_type_id_source(self): + return core.BNGetAutoPlatformTypeIdSource(self.handle) diff --git a/python/types.py b/python/types.py index 1cc02691..f66625f8 100644 --- a/python/types.py +++ b/python/types.py @@ -446,14 +446,13 @@ class Type(object): return core.BNGenerateAutoTypeId(source, name) @classmethod - def generate_auto_platform_type_id(self, name): + def generate_auto_demangled_type_id(self, name): name = QualifiedName(name)._get_core_struct() - return core.BNGenerateAutoTypeId(name) + return core.BNGenerateAutoDemangledTypeId(name) @classmethod - def generate_auto_demangled_type_id(self, name): - name = QualifiedName(name)._get_core_struct() - return core.BNGenerateAutoTypeId(name) + def get_auto_demanged_type_id_source(self): + return core.BNGetAutoDemangledTypeIdSource() def __setattr__(self, name, value): try: @@ -523,13 +522,8 @@ class NamedTypeReference(object): return NamedTypeReference(type_class, type_id, name) @classmethod - def generate_auto_platform_type_ref(self, type_class, source, name): - type_id = Type.generate_auto_platform_type_id(source, name) - return NamedTypeReference(type_class, type_id, name) - - @classmethod - def generate_auto_demangled_type_ref(self, type_class, source, name): - type_id = Type.generate_auto_demangled_type_id(source, name) + def generate_auto_demangled_type_ref(self, type_class, name): + type_id = Type.generate_auto_demangled_type_id(name) return NamedTypeReference(type_class, type_id, name) diff --git a/type.cpp b/type.cpp index dd1fb8d6..66138001 100644 --- a/type.cpp +++ b/type.cpp @@ -580,26 +580,30 @@ void Type::SetFunctionCanReturn(bool canReturn) string Type::GenerateAutoTypeId(const string& source, const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); - string result = BNGenerateAutoTypeId(source.c_str(), &nameObj); + char* str = BNGenerateAutoTypeId(source.c_str(), &nameObj); + string result = str; QualifiedName::FreeAPIObject(&nameObj); + BNFreeString(str); return result; } -string Type::GenerateAutoPlatformTypeId(const QualifiedName& name) +string Type::GenerateAutoDemangledTypeId(const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); - string result = BNGenerateAutoPlatformTypeId(&nameObj); + char* str = BNGenerateAutoDemangledTypeId(&nameObj); + string result = str; QualifiedName::FreeAPIObject(&nameObj); + BNFreeString(str); return result; } -string Type::GenerateAutoDemangledTypeId(const QualifiedName& name) +string Type::GetAutoDemangledTypeIdSource() { - BNQualifiedName nameObj = name.GetAPIObject(); - string result = BNGenerateAutoDemangledTypeId(&nameObj); - QualifiedName::FreeAPIObject(&nameObj); + char* str = BNGetAutoDemangledTypeIdSource(); + string result = str; + BNFreeString(str); return result; } @@ -679,14 +683,6 @@ Ref NamedTypeReference::GenerateAutoTypeReference(BNNamedTyp } -Ref NamedTypeReference::GenerateAutoPlatformTypeReference(BNNamedTypeReferenceClass cls, - const QualifiedName& name) -{ - string id = Type::GenerateAutoPlatformTypeId(name); - return new NamedTypeReference(cls, id, name); -} - - Ref NamedTypeReference::GenerateAutoDemangledTypeReference(BNNamedTypeReferenceClass cls, const QualifiedName& name) { -- cgit v1.3.1