From c3693b77c1fa9c1b5c45483045eeab929cf7bd16 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 23 Aug 2016 22:52:32 -0400 Subject: Fix some memory leaks --- function.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'function.cpp') diff --git a/function.cpp b/function.cpp index 7c188e72..c5033276 100644 --- a/function.cpp +++ b/function.cpp @@ -406,13 +406,13 @@ map Function::GetStackLayout() } -void Function::CreateAutoStackVariable(int64_t offset, Type* type, const string& name) +void Function::CreateAutoStackVariable(int64_t offset, Ref type, const string& name) { BNCreateAutoStackVariable(m_object, offset, type->GetObject(), name.c_str()); } -void Function::CreateUserStackVariable(int64_t offset, Type* type, const string& name) +void Function::CreateUserStackVariable(int64_t offset, Ref type, const string& name) { BNCreateUserStackVariable(m_object, offset, type->GetObject(), name.c_str()); } -- cgit v1.3.1 From e878199be4a74c880acd5d38c33965b47d7630d0 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Thu, 25 Aug 2016 20:42:33 -0400 Subject: Adding APIs for database save/load progress and constant references --- binaryninjaapi.h | 10 ++++++++++ binaryninjacore.h | 15 +++++++++++++++ binaryview.cpp | 13 +++++++++++++ filemetadata.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++ function.cpp | 13 +++++++++++++ python/__init__.py | 55 ++++++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 139 insertions(+), 10 deletions(-) (limited to 'function.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f79e9d75..7c951dee 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -511,8 +511,14 @@ namespace BinaryNinja bool IsBackedByDatabase() const; bool CreateDatabase(const std::string& name, BinaryView* data); + bool CreateDatabase(const std::string& name, BinaryView* data, + const std::function& progressCallback); Ref OpenExistingDatabase(const std::string& path); + Ref OpenExistingDatabase(const std::string& path, + const std::function& progressCallback); bool SaveAutoSnapshot(BinaryView* data); + bool SaveAutoSnapshot(BinaryView* data, + const std::function& progressCallback); void BeginUndoActions(); void CommitUndoActions(); @@ -766,7 +772,10 @@ namespace BinaryNinja bool IsAnalysisChanged() const; bool IsBackedByDatabase() const; bool CreateDatabase(const std::string& path); + bool CreateDatabase(const std::string& path, + const std::function& progressCallback); bool SaveAutoSnapshot(); + bool SaveAutoSnapshot(const std::function& progressCallback); void BeginUndoActions(); void AddUndoAction(UndoAction* action); @@ -1626,6 +1635,7 @@ namespace BinaryNinja std::vector GetRegistersReadByInstruction(Architecture* arch, uint64_t addr); std::vector GetRegistersWrittenByInstruction(Architecture* arch, uint64_t addr); std::vector GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr); + std::vector GetConstantsReferencedByInstruction(Architecture* arch, uint64_t addr); Ref GetLiftedIL() const; size_t GetLiftedILForInstruction(Architecture* arch, uint64_t addr); diff --git a/binaryninjacore.h b/binaryninjacore.h index 2ba6f7e6..4d8c31d9 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1013,6 +1013,12 @@ extern "C" void (*addAction)(void* ctxt, BNMainThreadAction* action); }; + struct BNConstantReference + { + int64_t value; + size_t size; + }; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); @@ -1105,8 +1111,14 @@ extern "C" BINARYNINJACOREAPI bool BNIsBackedByDatabase(BNFileMetadata* file); BINARYNINJACOREAPI bool BNCreateDatabase(BNBinaryView* data, const char* path); + BINARYNINJACOREAPI bool BNCreateDatabaseWithProgress(BNBinaryView* data, const char* path, + void* ctxt, void (*progress)(void* ctxt, size_t progress, size_t total)); BINARYNINJACOREAPI BNBinaryView* BNOpenExistingDatabase(BNFileMetadata* file, const char* path); + BINARYNINJACOREAPI BNBinaryView* BNOpenExistingDatabaseWithProgress(BNFileMetadata* file, const char* path, + void* ctxt, void (*progress)(void* ctxt, size_t progress, size_t total)); BINARYNINJACOREAPI bool BNSaveAutoSnapshot(BNBinaryView* data); + BINARYNINJACOREAPI bool BNSaveAutoSnapshotWithProgress(BNBinaryView* data, void* ctxt, + void (*progress)(void* ctxt, size_t progress, size_t total)); BINARYNINJACOREAPI char* BNGetFilename(BNFileMetadata* file); BINARYNINJACOREAPI void BNSetFilename(BNFileMetadata* file, const char* name); @@ -1433,6 +1445,9 @@ extern "C" BINARYNINJACOREAPI BNStackVariableReference* BNGetStackVariablesReferencedByInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count); BINARYNINJACOREAPI void BNFreeStackVariableReferenceList(BNStackVariableReference* refs, size_t count); + BINARYNINJACOREAPI BNConstantReference* BNGetConstantsReferencedByInstruction(BNFunction* func, + BNArchitecture* arch, uint64_t addr, size_t* count); + BINARYNINJACOREAPI void BNFreeConstantReferenceList(BNConstantReference* refs); BINARYNINJACOREAPI BNLowLevelILFunction* BNGetFunctionLiftedIL(BNFunction* func); BINARYNINJACOREAPI size_t BNGetLiftedILForInstruction(BNFunction* func, BNArchitecture* arch, uint64_t addr); diff --git a/binaryview.cpp b/binaryview.cpp index cff3ed10..14393930 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -518,12 +518,25 @@ bool BinaryView::CreateDatabase(const string& path) } +bool BinaryView::CreateDatabase(const string& path, + const function& progressCallback) +{ + return m_file->CreateDatabase(path, this, progressCallback); +} + + bool BinaryView::SaveAutoSnapshot() { return m_file->SaveAutoSnapshot(this); } +bool BinaryView::SaveAutoSnapshot(const function& progressCallback) +{ + return m_file->SaveAutoSnapshot(this, progressCallback); +} + + void BinaryView::BeginUndoActions() { m_file->BeginUndoActions(); diff --git a/filemetadata.cpp b/filemetadata.cpp index 51e152bf..b3764167 100644 --- a/filemetadata.cpp +++ b/filemetadata.cpp @@ -25,6 +25,19 @@ using namespace Json; using namespace std; +struct DatabaseProgressCallbackContext +{ + std::function func; +}; + + +static void DatabaseProgressCallback(void* ctxt, size_t progress, size_t total) +{ + DatabaseProgressCallbackContext* cb = (DatabaseProgressCallbackContext*)ctxt; + cb->func(progress, total); +} + + char* NavigationHandler::GetCurrentViewCallback(void* ctxt) { NavigationHandler* handler = (NavigationHandler*)ctxt; @@ -246,6 +259,15 @@ bool FileMetadata::CreateDatabase(const string& name, BinaryView* data) } +bool FileMetadata::CreateDatabase(const string& name, BinaryView* data, + const function& progressCallback) +{ + DatabaseProgressCallbackContext cb; + cb.func = progressCallback; + return BNCreateDatabaseWithProgress(data->GetObject(), name.c_str(), &cb, DatabaseProgressCallback); +} + + Ref FileMetadata::OpenExistingDatabase(const string& path) { BNBinaryView* data = BNOpenExistingDatabase(m_object, path.c_str()); @@ -255,12 +277,33 @@ Ref FileMetadata::OpenExistingDatabase(const string& path) } +Ref FileMetadata::OpenExistingDatabase(const string& path, + const function& progressCallback) +{ + DatabaseProgressCallbackContext cb; + cb.func = progressCallback; + BNBinaryView* data = BNOpenExistingDatabaseWithProgress(m_object, path.c_str(), &cb, DatabaseProgressCallback); + if (!data) + return nullptr; + return new BinaryView(data); +} + + bool FileMetadata::SaveAutoSnapshot(BinaryView* data) { return BNSaveAutoSnapshot(data->GetObject()); } +bool FileMetadata::SaveAutoSnapshot(BinaryView* data, + const function& progressCallback) +{ + DatabaseProgressCallbackContext cb; + cb.func = progressCallback; + return BNSaveAutoSnapshotWithProgress(data->GetObject(), &cb, DatabaseProgressCallback); +} + + void FileMetadata::BeginUndoActions() { BNBeginUndoActions(m_object); diff --git a/function.cpp b/function.cpp index c5033276..27193992 100644 --- a/function.cpp +++ b/function.cpp @@ -288,6 +288,19 @@ vector Function::GetStackVariablesReferencedByInstructio } +vector Function::GetConstantsReferencedByInstruction(Architecture* arch, uint64_t addr) +{ + size_t count; + BNConstantReference* refs = BNGetConstantsReferencedByInstruction(m_object, arch->GetObject(), addr, &count); + + vector result; + result.insert(result.end(), &refs[0], &refs[count]); + + BNFreeConstantReferenceList(refs); + return result; +} + + Ref Function::GetLiftedIL() const { return new LowLevelILFunction(BNGetFunctionLiftedIL(m_object)); diff --git a/python/__init__.py b/python/__init__.py index 027c2a1f..092e07c0 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -372,18 +372,32 @@ class FileMetadata(object): def navigate(self, view, offset): return core.BNNavigate(self.handle, str(view), offset) - def create_database(self, filename): - - return core.BNCreateDatabase(self.raw.handle, str(filename)) + def create_database(self, filename, progress_func = None): + if progress_func is None: + return core.BNCreateDatabase(self.raw.handle, str(filename)) + else: + return core.BNCreateDatabaseWithProgress(self.raw.handle, str(filename), None, + ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong)( + lambda ctxt, cur, total: progress_func(cur, total))) - def open_existing_database(self, filename): - view = core.BNOpenExistingDatabase(self.handle, str(filename)) + def open_existing_database(self, filename, progress_func = None): + if progress_func is None: + view = core.BNOpenExistingDatabase(self.handle, str(filename)) + else: + view = core.BNOpenExistingDatabaseWithProgress(self.handle, str(filename), None, + ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong)( + lambda ctxt, cur, total: progress_func(cur, total))) if view is None: return None return BinaryView(self, handle = view) - def save_auto_snapshot(self): - return core.BNSaveAutoSnapshot(self.raw.handle) + def save_auto_snapshot(self, progress_func = None): + if progress_func is None: + return core.BNSaveAutoSnapshot(self.raw.handle) + else: + return core.BNSaveAutoSnapshotWithProgress(self.raw.handle, None, + ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong)( + lambda ctxt, cur, total: progress_func(cur, total))) def get_view_of_type(self, name): view = core.BNGetFileViewOfType(self.handle, str(name)) @@ -1683,26 +1697,28 @@ class BinaryView(object): """ return core.LittleEndian - def create_database(self, filename): + def create_database(self, filename, progress_func = None): """ ``perform_get_database`` writes the current database (.bndb) file out to the specified file. :param str filename: path and filename to write the bndb to, this string `should` have ".bndb" appended to it. + :param callable() progress_func: optional function to be called with the current progress and total count. :return: true on success, false on failure :rtype: bool """ return self.file.create_database(filename) - def save_auto_snapshot(self): + def save_auto_snapshot(self, progress_func = None): """ ``save_auto_snapshot`` saves the current database to the already created file. .. note:: :py:method:`create_database` should have been called prior to executing this method + :param callable() progress_func: optional function to be called with the current progress and total count. :return: True if it successfully saved the snapshot, False otherwise :rtype: bool """ - return self.file.save_auto_snapshot() + return self.file.save_auto_snapshot(progress_func) def get_view_of_type(self, name): """ @@ -4248,6 +4264,16 @@ class StackVariableReference: return "" % (self.source_operand, self.name, self.referenced_offset) return "" % (self.source_operand, self.name) +class ConstantReference: + def __init__(self, val, size): + self.value = val + self.size = size + + def __repr__(self): + if self.size == 0: + return "" % self.value + return "" % (self.value, self.size) + class IndirectBranchInfo: def __init__(self, source_arch, source_addr, dest_arch, dest_addr, auto_defined): self.source_arch = source_arch @@ -4531,6 +4557,15 @@ class Function(object): core.BNFreeStackVariableReferenceList(refs, count.value) return result + def get_constants_referenced_by(self, arch, addr): + count = ctypes.c_ulonglong() + refs = core.BNGetConstantsReferencedByInstruction(self.handle, arch.handle, addr, count) + result = [] + for i in xrange(0, count.value): + result.append(ConstantReference(refs[i].value, refs[i].size)) + core.BNFreeConstantReferenceList(refs) + return result + def get_lifted_il_at(self, arch, addr): return core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr) -- cgit v1.3.1 From 827662fbb6caa9d0aa3089cafb20a578a68eaee7 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 30 Aug 2016 19:30:43 -0400 Subject: Add API to determine if a function still has analysis updates to complete --- binaryninjaapi.h | 1 + binaryninjacore.h | 1 + function.cpp | 6 ++++++ python/__init__.py | 5 +++++ 4 files changed, 13 insertions(+) (limited to 'function.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 7c951dee..f60ee159 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1611,6 +1611,7 @@ namespace BinaryNinja bool WasAutomaticallyDiscovered() const; bool CanReturn() const; bool HasExplicitlyDefinedType() const; + bool NeedsUpdate() const; std::vector> GetBasicBlocks() const; void MarkRecentUse(); diff --git a/binaryninjacore.h b/binaryninjacore.h index 4d8c31d9..c293f940 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1381,6 +1381,7 @@ extern "C" BINARYNINJACOREAPI void BNRemoveUserFunction(BNBinaryView* view, BNFunction* func); BINARYNINJACOREAPI void BNUpdateAnalysis(BNBinaryView* view); BINARYNINJACOREAPI void BNAbortAnalysis(BNBinaryView* view); + BINARYNINJACOREAPI bool BNIsFunctionUpdateNeeded(BNFunction* func); BINARYNINJACOREAPI BNFunction* BNNewFunctionReference(BNFunction* func); BINARYNINJACOREAPI void BNFreeFunction(BNFunction* func); diff --git a/function.cpp b/function.cpp index 27193992..78a33bda 100644 --- a/function.cpp +++ b/function.cpp @@ -72,6 +72,12 @@ bool Function::HasExplicitlyDefinedType() const } +bool Function::NeedsUpdate() const +{ + return BNIsFunctionUpdateNeeded(m_object); +} + + vector> Function::GetBasicBlocks() const { size_t count; diff --git a/python/__init__.py b/python/__init__.py index 092e07c0..e9f036ae 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -4348,6 +4348,11 @@ class Function(object): """Whether function has explicitly defined types (read-only)""" return core.BNHasExplicitlyDefinedType(self.handle) + @property + def needs_update(self): + """Whether the function has analysis that needs to be updated (read-only)""" + return core.BNIsFunctionUpdateNeeded(self.handle) + @property def basic_blocks(self): """List of basic blocks (read-only)""" -- cgit v1.3.1 From 3978e18b09ca745fd08defb8f00fbece267beaf2 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 30 Aug 2016 21:59:40 -0400 Subject: Add API to reanalyze --- binaryninjaapi.h | 4 ++++ binaryninjacore.h | 3 +++ binaryview.cpp | 6 ++++++ function.cpp | 6 ++++++ python/__init__.py | 16 ++++++++++++++++ 5 files changed, 35 insertions(+) (limited to 'function.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f60ee159..7c417623 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -919,6 +919,8 @@ namespace BinaryNinja void UndefineUserType(const std::string& name); bool FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = NoFindFlags); + + void Reanalyze(); }; class BinaryData: public BinaryView @@ -1672,6 +1674,8 @@ namespace BinaryNinja size_t operand); void SetIntegerConstantDisplayType(Architecture* arch, uint64_t instrAddr, uint64_t value, size_t operand, BNIntegerDisplayType type); + + void Reanalyze(); }; struct FunctionGraphEdge diff --git a/binaryninjacore.h b/binaryninjacore.h index c293f940..3aa0a1e6 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1565,6 +1565,9 @@ extern "C" BINARYNINJACOREAPI void BNUndefineAnalysisType(BNBinaryView* view, const char* name); BINARYNINJACOREAPI void BNUndefineUserAnalysisType(BNBinaryView* view, const char* name); + BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view); + BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func); + // Disassembly settings BINARYNINJACOREAPI BNDisassemblySettings* BNCreateDisassemblySettings(void); BINARYNINJACOREAPI BNDisassemblySettings* BNNewDisassemblySettingsReference(BNDisassemblySettings* settings); diff --git a/binaryview.cpp b/binaryview.cpp index 14393930..6631f3d6 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1440,6 +1440,12 @@ bool BinaryView::FindNextData(uint64_t start, const DataBuffer& data, uint64_t& } +void BinaryView::Reanalyze() +{ + BNReanalyzeAllFunctions(m_object); +} + + BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetObject())) { } diff --git a/function.cpp b/function.cpp index 78a33bda..cbd9ec40 100644 --- a/function.cpp +++ b/function.cpp @@ -572,3 +572,9 @@ void Function::SetIntegerConstantDisplayType(Architecture* arch, uint64_t instrA { BNSetIntegerConstantDisplayType(m_object, arch->GetObject(), instrAddr, value, operand, type); } + + +void Function::Reanalyze() +{ + BNReanalyzeFunction(m_object); +} diff --git a/python/__init__.py b/python/__init__.py index e9f036ae..82aaba32 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -3231,6 +3231,14 @@ class BinaryView(object): return None return result.value + def reanalyze(self): + """ + ``reanalyze`` causes all functions to be reanalyzed. This function does not wait for the analysis to finish. + + :rtype: None + """ + core.BNReanalyzeAllFunctions(self.handle) + def __setattr__(self, name, value): try: object.__setattr__(self,name,value) @@ -4677,6 +4685,14 @@ class Function(object): display_type = core.BNIntegerDisplayType_by_name[display_type] core.BNSetIntegerConstantDisplayType(self.handle, arch.handle, instr_addr, value, operand, display_type) + def reanalyze(self): + """ + ``reanalyze`` causes this functions to be reanalyzed. This function does not wait for the analysis to finish. + + :rtype: None + """ + core.BNReanalyzeFunction(self.handle) + class BasicBlockEdge: def __init__(self, branch_type, target, arch): self.type = core.BNBranchType_names[branch_type] -- cgit v1.3.1 From 50cafb19ae59ba48fea2e7bd0c79a2e9473c2c86 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Sat, 3 Sep 2016 01:32:35 -0400 Subject: Adding APIs to ensure IL is available for upcoming caching methods --- binaryninjaapi.h | 21 ++++++++++++++++ binaryninjacore.h | 3 +++ function.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ python/__init__.py | 38 ++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+) (limited to 'function.cpp') diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 342dcc48..72e13567 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1611,8 +1611,11 @@ namespace BinaryNinja class Function: public CoreRefCountObject { + int m_advancedAnalysisRequests; + public: Function(BNFunction* func); + virtual ~Function(); Ref GetArchitecture() const; Ref GetPlatform() const; @@ -1684,6 +1687,24 @@ namespace BinaryNinja BNIntegerDisplayType type); void Reanalyze(); + + void RequestAdvancedAnalysisData(); + void ReleaseAdvancedAnalysisData(); + void ReleaseAdvancedAnalysisData(size_t count); + }; + + class AdvancedFunctionAnalysisDataRequestor + { + Ref m_func; + + public: + AdvancedFunctionAnalysisDataRequestor(Function* func = nullptr); + AdvancedFunctionAnalysisDataRequestor(const AdvancedFunctionAnalysisDataRequestor& req); + ~AdvancedFunctionAnalysisDataRequestor(); + AdvancedFunctionAnalysisDataRequestor& operator=(const AdvancedFunctionAnalysisDataRequestor& req); + + Ref GetFunction() { return m_func; } + void SetFunction(Function* func); }; struct FunctionGraphEdge diff --git a/binaryninjacore.h b/binaryninjacore.h index 6eff4d46..0c2738cb 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1384,6 +1384,9 @@ extern "C" BINARYNINJACOREAPI void BNUpdateAnalysis(BNBinaryView* view); BINARYNINJACOREAPI void BNAbortAnalysis(BNBinaryView* view); BINARYNINJACOREAPI bool BNIsFunctionUpdateNeeded(BNFunction* func); + BINARYNINJACOREAPI void BNRequestAdvancedFunctionAnalysisData(BNFunction* func); + BINARYNINJACOREAPI void BNReleaseAdvancedFunctionAnalysisData(BNFunction* func); + BINARYNINJACOREAPI void BNReleaseAdvancedFunctionAnalysisDataMultiple(BNFunction* func, size_t count); BINARYNINJACOREAPI BNFunction* BNNewFunctionReference(BNFunction* func); BINARYNINJACOREAPI void BNFreeFunction(BNFunction* func); diff --git a/function.cpp b/function.cpp index cbd9ec40..de12918f 100644 --- a/function.cpp +++ b/function.cpp @@ -27,6 +27,14 @@ using namespace std; Function::Function(BNFunction* func) { m_object = func; + m_advancedAnalysisRequests = 0; +} + + +Function::~Function() +{ + if (m_advancedAnalysisRequests > 0) + BNReleaseAdvancedFunctionAnalysisDataMultiple(m_object, (size_t)m_advancedAnalysisRequests); } @@ -578,3 +586,67 @@ void Function::Reanalyze() { BNReanalyzeFunction(m_object); } + + +void Function::RequestAdvancedAnalysisData() +{ + BNRequestAdvancedFunctionAnalysisData(m_object); +#ifdef WIN32 + InterlockedIncrement((LONG*)&m_advancedAnalysisRequests); +#else + __sync_fetch_and_add(&m_advancedAnalysisRequests, 1); +#endif +} + + +void Function::ReleaseAdvancedAnalysisData() +{ + BNReleaseAdvancedFunctionAnalysisData(m_object); +#ifdef WIN32 + InterlockedDecrement((LONG*)&m_advancedAnalysisRequests); +#else + __sync_fetch_and_add(&m_advancedAnalysisRequests, -1); +#endif +} + + +AdvancedFunctionAnalysisDataRequestor::AdvancedFunctionAnalysisDataRequestor(Function* func): m_func(func) +{ + if (m_func) + m_func->RequestAdvancedAnalysisData(); +} + + +AdvancedFunctionAnalysisDataRequestor::AdvancedFunctionAnalysisDataRequestor(const AdvancedFunctionAnalysisDataRequestor& req) +{ + m_func = req.m_func; + if (m_func) + m_func->RequestAdvancedAnalysisData(); +} + + +AdvancedFunctionAnalysisDataRequestor::~AdvancedFunctionAnalysisDataRequestor() +{ + if (m_func) + m_func->ReleaseAdvancedAnalysisData(); +} + + +AdvancedFunctionAnalysisDataRequestor& AdvancedFunctionAnalysisDataRequestor::operator=( + const AdvancedFunctionAnalysisDataRequestor& req) +{ + SetFunction(req.m_func); + return *this; +} + + +void AdvancedFunctionAnalysisDataRequestor::SetFunction(Function* func) +{ + if (m_func) + m_func->ReleaseAdvancedAnalysisData(); + + m_func = func; + + if (m_func) + m_func->RequestAdvancedAnalysisData(); +} diff --git a/python/__init__.py b/python/__init__.py index d199385a..cd559fe5 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -4330,8 +4330,11 @@ class Function(object): def __init__(self, view, handle): self._view = view self.handle = core.handle_of_type(handle, core.BNFunction) + self._advanced_analysis_requests = 0 def __del__(self): + if self._advanced_analysis_requests > 0: + core.BNReleaseAdvancedFunctionAnalysisDataMultiple(self.handle, self._advanced_analysis_requests) core.BNFreeFunction(self.handle) @property @@ -4726,6 +4729,41 @@ class Function(object): """ core.BNReanalyzeFunction(self.handle) + def request_advanced_analysis_data(self): + core.BNRequestAdvancedFunctionAnalysisData(self.handle) + self._advanced_analysis_requests += 1 + + def release_advanced_analysis_data(self): + core.BNReleaseAdvancedFunctionAnalysisData(self.handle) + self._advanced_analysis_requests -= 1 + +class AdvancedFunctionAnalysisDataRequestor(object): + def __init__(self, func = None): + self._function = func + if self._function is not None: + self._function.request_advanced_analysis_data() + + def __del__(self): + if self._function is not None: + self._function.release_advanced_analysis_data() + + @property + def function(self): + return self._function + + @function.setter + def function(self, func): + if self._function is not None: + self._function.release_advanced_analysis_data() + self._function = func + if self._function is not None: + self._function.request_advanced_analysis_data() + + def close(self): + if self._function is not None: + self._function.release_advanced_analysis_data() + self._function = None + class BasicBlockEdge: def __init__(self, branch_type, target, arch): self.type = core.BNBranchType_names[branch_type] -- cgit v1.3.1 From fb0d896cd5cc3197a8dd259a9ca53f2788ef5fdb Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 14 Sep 2016 00:28:27 -0400 Subject: Add APIs for instruction and block highlighting --- basicblock.cpp | 110 +++++++++++++++++++++++++++++++++++ binaryninjaapi.h | 30 ++++++++++ binaryninjacore.h | 40 +++++++++++++ function.cpp | 123 +++++++++++++++++++++++++++++++++++++++ functiongraphblock.cpp | 6 ++ python/__init__.py | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 461 insertions(+) (limited to 'function.cpp') diff --git a/basicblock.cpp b/basicblock.cpp index 377c5704..93a279a1 100644 --- a/basicblock.cpp +++ b/basicblock.cpp @@ -172,3 +172,113 @@ vector BasicBlock::GetDisassemblyText(DisassemblySettings* BNFreeDisassemblyTextLines(lines, count); return result; } + + +BNHighlightColor BasicBlock::GetBasicBlockHighlight() +{ + return BNGetBasicBlockHighlight(m_object); +} + + +void BasicBlock::SetAutoBasicBlockHighlight(BNHighlightColor color) +{ + BNSetAutoBasicBlockHighlight(m_object, color); +} + + +void BasicBlock::SetAutoBasicBlockHighlight(BNHighlightStandardColor color, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = StandardHighlightColor; + hc.color = color; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetAutoBasicBlockHighlight(hc); +} + + +void BasicBlock::SetAutoBasicBlockHighlight(BNHighlightStandardColor color, BNHighlightStandardColor mixColor, + uint8_t mix, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = MixedHighlightColor; + hc.color = color; + hc.mixColor = mixColor; + hc.mix = mix; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetAutoBasicBlockHighlight(hc); +} + + +void BasicBlock::SetAutoBasicBlockHighlight(uint8_t r, uint8_t g, uint8_t b, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = CustomHighlightColor; + hc.color = NoHighlightColor; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = r; + hc.g = g; + hc.b = b; + hc.alpha = alpha; + SetAutoBasicBlockHighlight(hc); +} + + +void BasicBlock::SetUserBasicBlockHighlight(BNHighlightColor color) +{ + BNSetUserBasicBlockHighlight(m_object, color); +} + + +void BasicBlock::SetUserBasicBlockHighlight(BNHighlightStandardColor color, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = StandardHighlightColor; + hc.color = color; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetUserBasicBlockHighlight(hc); +} + + +void BasicBlock::SetUserBasicBlockHighlight(BNHighlightStandardColor color, BNHighlightStandardColor mixColor, + uint8_t mix, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = MixedHighlightColor; + hc.color = color; + hc.mixColor = mixColor; + hc.mix = mix; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetUserBasicBlockHighlight(hc); +} + + +void BasicBlock::SetUserBasicBlockHighlight(uint8_t r, uint8_t g, uint8_t b, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = CustomHighlightColor; + hc.color = NoHighlightColor; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = r; + hc.g = g; + hc.b = b; + hc.alpha = alpha; + SetUserBasicBlockHighlight(hc); +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index d4df479b..30285380 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1561,6 +1561,18 @@ namespace BinaryNinja std::vector> GetAnnotations(); std::vector GetDisassemblyText(DisassemblySettings* settings); + + BNHighlightColor GetBasicBlockHighlight(); + void SetAutoBasicBlockHighlight(BNHighlightColor color); + void SetAutoBasicBlockHighlight(BNHighlightStandardColor color, uint8_t alpha = 255); + void SetAutoBasicBlockHighlight(BNHighlightStandardColor color, BNHighlightStandardColor mixColor, + uint8_t mix, uint8_t alpha = 255); + void SetAutoBasicBlockHighlight(uint8_t r, uint8_t g, uint8_t b, uint8_t alpha = 255); + void SetUserBasicBlockHighlight(BNHighlightColor color); + void SetUserBasicBlockHighlight(BNHighlightStandardColor color, uint8_t alpha = 255); + void SetUserBasicBlockHighlight(BNHighlightStandardColor color, BNHighlightStandardColor mixColor, + uint8_t mix, uint8_t alpha = 255); + void SetUserBasicBlockHighlight(uint8_t r, uint8_t g, uint8_t b, uint8_t alpha = 255); }; struct StackVariable @@ -1633,6 +1645,7 @@ namespace BinaryNinja bool NeedsUpdate() const; std::vector> GetBasicBlocks() const; + Ref GetBasicBlockAtAddress(Architecture* arch, uint64_t addr) const; void MarkRecentUse(); std::string GetCommentForAddress(uint64_t addr) const; @@ -1692,6 +1705,22 @@ namespace BinaryNinja void SetIntegerConstantDisplayType(Architecture* arch, uint64_t instrAddr, uint64_t value, size_t operand, BNIntegerDisplayType type); + BNHighlightColor GetInstructionHighlight(Architecture* arch, uint64_t addr); + void SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightColor color); + void SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + uint8_t alpha = 255); + void SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + BNHighlightStandardColor mixColor, uint8_t mix, uint8_t alpha = 255); + void SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, uint8_t r, uint8_t g, uint8_t b, + uint8_t alpha = 255); + void SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightColor color); + void SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + uint8_t alpha = 255); + void SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + BNHighlightStandardColor mixColor, uint8_t mix, uint8_t alpha = 255); + void SetUserInstructionHighlight(Architecture* arch, uint64_t addr, uint8_t r, uint8_t g, uint8_t b, + uint8_t alpha = 255); + void Reanalyze(); void RequestAdvancedAnalysisData(); @@ -1731,6 +1760,7 @@ namespace BinaryNinja public: FunctionGraphBlock(BNFunctionGraphBlock* block); + Ref GetBasicBlock() const; Ref GetArchitecture() const; uint64_t GetStart() const; uint64_t GetEnd() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 51bf3391..de7b77fd 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1020,6 +1020,35 @@ extern "C" size_t size; }; + enum BNHighlightColorStyle + { + StandardHighlightColor = 0, + MixedHighlightColor = 1, + CustomHighlightColor = 2 + }; + + enum BNHighlightStandardColor + { + NoHighlightColor = 0, + BlueHighlightColor = 1, + GreenHighlightColor = 2, + CyanHighlightColor = 3, + RedHighlightColor = 4, + MagentaHighlightColor = 5, + YellowHighlightColor = 6, + OrangeHighlightColor = 7, + WhiteHighlightColor = 8, + BlackHighlightColor = 9 + }; + + struct BNHighlightColor + { + BNHighlightColorStyle style; + BNHighlightStandardColor color; + BNHighlightStandardColor mixColor; + uint8_t mix, r, g, b, alpha; + }; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); @@ -1418,6 +1447,7 @@ extern "C" BINARYNINJACOREAPI void BNFreeBasicBlock(BNBasicBlock* block); BINARYNINJACOREAPI BNBasicBlock** BNGetFunctionBasicBlockList(BNFunction* func, size_t* count); BINARYNINJACOREAPI void BNFreeBasicBlockList(BNBasicBlock** blocks, size_t count); + BINARYNINJACOREAPI BNBasicBlock* BNGetFunctionBasicBlockAtAddress(BNFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI BNBasicBlock* BNGetRecentBasicBlockForAddress(BNBinaryView* view, uint64_t addr); BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlocksForAddress(BNBinaryView* view, uint64_t addr, size_t* count); BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlocksStartingAtAddress(BNBinaryView* view, uint64_t addr, size_t* count); @@ -1575,6 +1605,15 @@ extern "C" BINARYNINJACOREAPI void BNReanalyzeAllFunctions(BNBinaryView* view); BINARYNINJACOREAPI void BNReanalyzeFunction(BNFunction* func); + BINARYNINJACOREAPI BNHighlightColor BNGetInstructionHighlight(BNFunction* func, BNArchitecture* arch, uint64_t addr); + BINARYNINJACOREAPI void BNSetAutoInstructionHighlight(BNFunction* func, BNArchitecture* arch, uint64_t addr, + BNHighlightColor color); + BINARYNINJACOREAPI void BNSetUserInstructionHighlight(BNFunction* func, BNArchitecture* arch, uint64_t addr, + BNHighlightColor color); + BINARYNINJACOREAPI BNHighlightColor BNGetBasicBlockHighlight(BNBasicBlock* block); + BINARYNINJACOREAPI void BNSetAutoBasicBlockHighlight(BNBasicBlock* block, BNHighlightColor color); + BINARYNINJACOREAPI void BNSetUserBasicBlockHighlight(BNBasicBlock* block, BNHighlightColor color); + // Disassembly settings BINARYNINJACOREAPI BNDisassemblySettings* BNCreateDisassemblySettings(void); BINARYNINJACOREAPI BNDisassemblySettings* BNNewDisassemblySettingsReference(BNDisassemblySettings* settings); @@ -1622,6 +1661,7 @@ extern "C" BINARYNINJACOREAPI BNFunctionGraphBlock* BNNewFunctionGraphBlockReference(BNFunctionGraphBlock* block); BINARYNINJACOREAPI void BNFreeFunctionGraphBlock(BNFunctionGraphBlock* block); + BINARYNINJACOREAPI BNBasicBlock* BNGetFunctionGraphBasicBlock(BNFunctionGraphBlock* block); BINARYNINJACOREAPI BNArchitecture* BNGetFunctionGraphBlockArchitecture(BNFunctionGraphBlock* block); BINARYNINJACOREAPI uint64_t BNGetFunctionGraphBlockStart(BNFunctionGraphBlock* block); BINARYNINJACOREAPI uint64_t BNGetFunctionGraphBlockEnd(BNFunctionGraphBlock* block); diff --git a/function.cpp b/function.cpp index de12918f..109b6f49 100644 --- a/function.cpp +++ b/function.cpp @@ -100,6 +100,15 @@ vector> Function::GetBasicBlocks() const } +Ref Function::GetBasicBlockAtAddress(Architecture* arch, uint64_t addr) const +{ + BNBasicBlock* block = BNGetFunctionBasicBlockAtAddress(m_object, arch->GetObject(), addr); + if (!block) + return nullptr; + return new BasicBlock(block); +} + + void Function::MarkRecentUse() { BNMarkFunctionAsRecentlyUsed(m_object); @@ -582,6 +591,120 @@ void Function::SetIntegerConstantDisplayType(Architecture* arch, uint64_t instrA } +BNHighlightColor Function::GetInstructionHighlight(Architecture* arch, uint64_t addr) +{ + return BNGetInstructionHighlight(m_object, arch->GetObject(), addr); +} + + +void Function::SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightColor color) +{ + BNSetAutoInstructionHighlight(m_object, arch->GetObject(), addr, color); +} + + +void Function::SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = StandardHighlightColor; + hc.color = color; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetAutoInstructionHighlight(arch, addr, hc); +} + + +void Function::SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + BNHighlightStandardColor mixColor, uint8_t mix, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = MixedHighlightColor; + hc.color = color; + hc.mixColor = mixColor; + hc.mix = mix; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetAutoInstructionHighlight(arch, addr, hc); +} + + +void Function::SetAutoInstructionHighlight(Architecture* arch, uint64_t addr, uint8_t r, uint8_t g, uint8_t b, + uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = CustomHighlightColor; + hc.color = NoHighlightColor; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = r; + hc.g = g; + hc.b = b; + hc.alpha = alpha; + SetAutoInstructionHighlight(arch, addr, hc); +} + + +void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightColor color) +{ + BNSetUserInstructionHighlight(m_object, arch->GetObject(), addr, color); +} + + +void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = StandardHighlightColor; + hc.color = color; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetUserInstructionHighlight(arch, addr, hc); +} + + +void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, BNHighlightStandardColor color, + BNHighlightStandardColor mixColor, uint8_t mix, uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = MixedHighlightColor; + hc.color = color; + hc.mixColor = mixColor; + hc.mix = mix; + hc.r = 0; + hc.g = 0; + hc.b = 0; + hc.alpha = alpha; + SetUserInstructionHighlight(arch, addr, hc); +} + + +void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, uint8_t r, uint8_t g, uint8_t b, + uint8_t alpha) +{ + BNHighlightColor hc; + hc.style = CustomHighlightColor; + hc.color = NoHighlightColor; + hc.mixColor = NoHighlightColor; + hc.mix = 0; + hc.r = r; + hc.g = g; + hc.b = b; + hc.alpha = alpha; + SetUserInstructionHighlight(arch, addr, hc); +} + + void Function::Reanalyze() { BNReanalyzeFunction(m_object); diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp index 436339f6..47261453 100644 --- a/functiongraphblock.cpp +++ b/functiongraphblock.cpp @@ -32,6 +32,12 @@ FunctionGraphBlock::FunctionGraphBlock(BNFunctionGraphBlock* block) } +Ref FunctionGraphBlock::GetBasicBlock() const +{ + return new BasicBlock(BNGetFunctionGraphBasicBlock(m_object)); +} + + Ref FunctionGraphBlock::GetArchitecture() const { return new CoreArchitecture(BNGetFunctionGraphBlockArchitecture(m_object)); diff --git a/python/__init__.py b/python/__init__.py index 33202a2c..b29c9f80 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -4381,6 +4381,93 @@ class IndirectBranchInfo: def __repr__(self): return " %s:%#x>" % (self.source_arch.name, self.source_addr, self.dest_arch.name, self.dest_addr) +class HighlightColor(object): + def __init__(self, color = None, mix_color = None, mix = None, red = None, green = None, blue = None, alpha = 255): + if (red is not None) and (green is not None) and (blue is not None): + self.style = core.CustomHighlightColor + self.red = red + self.green = green + self.blue = blue + elif (mix_color is not None) and (mix is not None): + self.style = core.MixedHighlightColor + if color is None: + self.color = core.NoHighlightColor + else: + self.color = color + self.mix_color = mix_color + self.mix = mix + else: + self.style = core.StandardHighlightColor + if color is None: + self.color = core.NoHighlightColor + else: + self.color = color + self.alpha = alpha + + def _standard_color_to_str(self, color): + if color == core.NoHighlightColor: + return "none" + if color == core.BlueHighlightColor: + return "blue" + if color == core.GreenHighlightColor: + return "green" + if color == core.CyanHighlightColor: + return "cyan" + if color == core.RedHighlightColor: + return "red" + if color == core.MagentaHighlightColor: + return "magenta" + if color == core.YellowHighlightColor: + return "yellow" + if color == core.OrangeHighlightColor: + return "orange" + if color == core.WhiteHighlightColor: + return "white" + if color == core.BlackHighlightColor: + return "black" + return "%d" % color + + def __repr__(self): + if self.style == core.StandardHighlightColor: + if self.alpha == 255: + return "" % self._standard_color_to_str(self.color) + return "" % (self._standard_color_to_str(self.color), self.alpha) + if self.style == core.MixedHighlightColor: + if self.alpha == 255: + return "" % (self._standard_color_to_str(self.color), + self._standard_color_to_str(self.mix_color), self.mix) + return "" % (self._standard_color_to_str(self.color), + self._standard_color_to_str(self.mix_color), self.mix, self.alpha) + if self.style == core.CustomHighlightColor: + if self.alpha == 255: + return "" % (self.red, self.green, self.blue) + return "" % (self.red, self.green, self.blue, self.alpha) + return "" + + def _get_core_struct(self): + result = core.BNHighlightColor() + result.style = self.style + result.color = core.NoHighlightColor + result.mix_color = core.NoHighlightColor + result.mix = 0 + result.r = 0 + result.g = 0 + result.b = 0 + result.alpha = self.alpha + + if self.style == core.StandardHighlightColor: + result.color = self.color + elif self.style == core.MixedHighlightColor: + result.color = self.color + result.mixColor = self.mix_color + result.mix = self.mix + elif self.style == core.CustomHighlightColor: + result.r = self.red + result.g = self.green + result.b = self.blue + + return result + class Function(object): def __init__(self, view, handle): self._view = view @@ -4790,6 +4877,32 @@ class Function(object): core.BNReleaseAdvancedFunctionAnalysisData(self.handle) self._advanced_analysis_requests -= 1 + def get_basic_block_at(self, arch, addr): + block = core.BNGetFunctionBasicBlockAtAddress(self.handle, arch.handle, addr) + if not block: + return None + return BasicBlock(self._view, handle = block) + + def get_instr_highlight(self, arch, addr): + color = core.BNGetInstructionHighlight(self.handle, arch.handle, addr) + if color.style == core.StandardHighlightColor: + return HighlightColor(color = color.color, alpha = color.alpha) + elif color.style == core.MixedHighlightColor: + return HighlightColor(color = color.color, mix_color = color.mixColor, mix = color.mix, alpha = color.alpha) + elif color.style == core.CustomHighlightColor: + return HighlightColor(red = color.r, green = color.g, blue = color.b, alpha = color.alpha) + return HighlightColor(color = core.NoHighlightColor) + + def set_auto_instr_highlight(self, arch, addr, color): + if not isinstance(color, HighlightColor): + color = HighlightColor(color = color) + core.BNSetAutoInstructionHighlight(self.handle, arch.handle, addr, color._get_core_struct()) + + def set_user_instr_highlight(self, arch, addr, color): + if not isinstance(color, HighlightColor): + color = HighlightColor(color = color) + core.BNSetUserInstructionHighlight(self.handle, arch.handle, addr, color._get_core_struct()) + class AdvancedFunctionAnalysisDataRequestor(object): def __init__(self, func = None): self._function = func @@ -4902,6 +5015,22 @@ class BasicBlock(object): def disassembly_text(self): return self.get_disassembly_text() + @property + def highlight(self): + """Highlight color for basic block""" + color = core.BNGetBasicBlockHighlight(self.handle) + if color.style == core.StandardHighlightColor: + return HighlightColor(color = color.color, alpha = color.alpha) + elif color.style == core.MixedHighlightColor: + return HighlightColor(color = color.color, mix_color = color.mixColor, mix = color.mix, alpha = color.alpha) + elif color.style == core.CustomHighlightColor: + return HighlightColor(red = color.r, green = color.g, blue = color.b, alpha = color.alpha) + return HighlightColor(color = core.NoHighlightColor) + + @highlight.setter + def highlight(self, value): + self.set_user_highlight(value) + def __setattr__(self, name, value): try: object.__setattr__(self,name,value) @@ -4956,6 +5085,16 @@ class BasicBlock(object): core.BNFreeDisassemblyTextLines(lines, count.value) return result + def set_auto_highlight(self, color): + if not isinstance(color, HighlightColor): + color = HighlightColor(color = color) + core.BNSetAutoBasicBlockHighlight(self.handle, color._get_core_struct()) + + def set_user_highlight(self, color): + if not isinstance(color, HighlightColor): + color = HighlightColor(color = color) + core.BNSetUserBasicBlockHighlight(self.handle, color._get_core_struct()) + class LowLevelILBasicBlock(BasicBlock): def __init__(self, view, handle, owner): super(LowLevelILBasicBlock, self).__init__(view, handle) @@ -4998,6 +5137,19 @@ class FunctionGraphBlock(object): def __del__(self): core.BNFreeFunctionGraphBlock(self.handle) + @property + def basic_block(self): + """Basic block associated with this part of the funciton graph (read-only)""" + block = core.BNGetFunctionGraphBasicBlock(self.handle) + func = core.BNGetBasicBlockFunction(block) + if func is None: + core.BNFreeBasicBlock(block) + block = None + else: + block = BasicBlock(BinaryView(None, handle = core.BNGetFunctionData(func)), block) + core.BNFreeFunction(func) + return block + @property def arch(self): """Function graph block architecture (read-only)""" -- cgit v1.3.1