summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2018-03-07 18:10:55 -0500
committerRusty Wagner <rusty@vector35.com>2018-03-07 18:11:24 -0500
commit1c7349fcf125994f2e577361626fe1fb02eac029 (patch)
tree9855e97a3572c41af9f07f27e6b12eb1f117bf5d
parent352949f41ea0b66c833f272d2a2a1e5a77a9507c (diff)
Add APIs for skipping analysis of functions that are too large, and overriding this behavior
-rw-r--r--binaryninjaapi.h11
-rw-r--r--binaryninjacore.h17
-rw-r--r--binaryview.cpp23
-rw-r--r--function.cpp24
-rw-r--r--functiongraph.cpp6
-rw-r--r--python/binaryview.py19
-rw-r--r--python/function.py34
7 files changed, 133 insertions, 1 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 89eba009..2d7e2ccf 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -866,6 +866,7 @@ namespace BinaryNinja
static void FunctionAddedCallback(void* ctxt, BNBinaryView* data, BNFunction* func);
static void FunctionRemovedCallback(void* ctxt, BNBinaryView* data, BNFunction* func);
static void FunctionUpdatedCallback(void* ctxt, BNBinaryView* data, BNFunction* func);
+ static void FunctionUpdateRequestedCallback(void* ctxt, BNBinaryView* data, BNFunction* func);
static void DataVariableAddedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var);
static void DataVariableRemovedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var);
static void DataVariableUpdatedCallback(void* ctxt, BNBinaryView* data, BNDataVariable* var);
@@ -886,6 +887,7 @@ namespace BinaryNinja
virtual void OnAnalysisFunctionAdded(BinaryView* view, Function* func) { (void)view; (void)func; }
virtual void OnAnalysisFunctionRemoved(BinaryView* view, Function* func) { (void)view; (void)func; }
virtual void OnAnalysisFunctionUpdated(BinaryView* view, Function* func) { (void)view; (void)func; }
+ virtual void OnAnalysisFunctionUpdateRequested(BinaryView* view, Function* func) { (void)view; (void)func; }
virtual void OnDataVariableAdded(BinaryView* view, const DataVariable& var) { (void)view; (void)var; }
virtual void OnDataVariableRemoved(BinaryView* view, const DataVariable& var) { (void)view; (void)var; }
virtual void OnDataVariableUpdated(BinaryView* view, const DataVariable& var) { (void)view; (void)var; }
@@ -1344,6 +1346,9 @@ namespace BinaryNinja
std::string GetStringMetadata(const std::string& key);
std::vector<uint8_t> GetRawMetadata(const std::string& key);
uint64_t GetUIntMetadata(const std::string& key);
+
+ uint64_t GetMaxFunctionSizeForAnalysis();
+ void SetMaxFunctionSizeForAnalysis(uint64_t size);
};
class BinaryData: public BinaryView
@@ -2475,6 +2480,11 @@ namespace BinaryNinja
Confidence<RegisterValue> GetGlobalPointerValue() const;
Confidence<RegisterValue> GetRegisterValueAtExit(uint32_t reg) const;
+
+ bool IsFunctionTooLarge();
+ bool IsAnalysisSkipped();
+ BNFunctionAnalysisSkipOverride GetAnalysisSkipOverride();
+ void SetAnalysisSkipOverride(BNFunctionAnalysisSkipOverride skip);
};
class AdvancedFunctionAnalysisDataRequestor
@@ -2550,6 +2560,7 @@ namespace BinaryNinja
void Abort();
std::vector<Ref<FunctionGraphBlock>> GetBlocks();
+ bool HasBlocks() const;
int GetWidth() const;
int GetHeight() const;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 5329a1d9..a1b78b1c 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -989,6 +989,7 @@ extern "C"
void (*functionAdded)(void* ctxt, BNBinaryView* view, BNFunction* func);
void (*functionRemoved)(void* ctxt, BNBinaryView* view, BNFunction* func);
void (*functionUpdated)(void* ctxt, BNBinaryView* view, BNFunction* func);
+ void (*functionUpdateRequested)(void* ctxt, BNBinaryView* view, BNFunction* func);
void (*dataVariableAdded)(void* ctxt, BNBinaryView* view, BNDataVariable* var);
void (*dataVariableRemoved)(void* ctxt, BNBinaryView* view, BNDataVariable* var);
void (*dataVariableUpdated)(void* ctxt, BNBinaryView* view, BNDataVariable* var);
@@ -1739,6 +1740,13 @@ extern "C"
uint8_t confidence;
};
+ enum BNFunctionAnalysisSkipOverride
+ {
+ DefaultFunctionAnalysisSkip,
+ NeverSkipFunctionAnalysis,
+ AlwaysSkipFunctionAnalysis
+ };
+
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
BINARYNINJACOREAPI void BNFreeString(char* str);
BINARYNINJACOREAPI char** BNAllocStringList(const char** contents, size_t size);
@@ -2421,6 +2429,14 @@ extern "C"
BINARYNINJACOREAPI void BNSetIntegerConstantDisplayType(BNFunction* func, BNArchitecture* arch,
uint64_t instrAddr, uint64_t value, size_t operand, BNIntegerDisplayType type);
+ BINARYNINJACOREAPI bool BNIsFunctionTooLarge(BNFunction* func);
+ BINARYNINJACOREAPI bool BNIsFunctionAnalysisSkipped(BNFunction* func);
+ BINARYNINJACOREAPI BNFunctionAnalysisSkipOverride BNGetFunctionAnalysisSkipOverride(BNFunction* func);
+ BINARYNINJACOREAPI void BNSetFunctionAnalysisSkipOverride(BNFunction* func, BNFunctionAnalysisSkipOverride skip);
+
+ BINARYNINJACOREAPI uint64_t BNGetMaxFunctionSizeForAnalysis(BNBinaryView* view);
+ BINARYNINJACOREAPI void BNSetMaxFunctionSizeForAnalysis(BNBinaryView* view, uint64_t size);
+
BINARYNINJACOREAPI BNAnalysisCompletionEvent* BNAddAnalysisCompletionEvent(BNBinaryView* view, void* ctxt,
void (*callback)(void* ctxt));
BINARYNINJACOREAPI BNAnalysisCompletionEvent* BNNewAnalysisCompletionEventReference(BNAnalysisCompletionEvent* event);
@@ -2536,6 +2552,7 @@ extern "C"
BINARYNINJACOREAPI BNFunctionGraphBlock** BNGetFunctionGraphBlocksInRegion(
BNFunctionGraph* graph, int left, int top, int right, int bottom, size_t* count);
BINARYNINJACOREAPI void BNFreeFunctionGraphBlockList(BNFunctionGraphBlock** blocks, size_t count);
+ BINARYNINJACOREAPI bool BNFunctionGraphHasBlocks(BNFunctionGraph* graph);
BINARYNINJACOREAPI int BNGetFunctionGraphWidth(BNFunctionGraph* graph);
BINARYNINJACOREAPI int BNGetFunctionGraphHeight(BNFunctionGraph* graph);
diff --git a/binaryview.cpp b/binaryview.cpp
index 96fd161d..0dcf6bc3 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -78,6 +78,15 @@ void BinaryDataNotification::FunctionUpdatedCallback(void* ctxt, BNBinaryView* o
}
+void BinaryDataNotification::FunctionUpdateRequestedCallback(void* ctxt, BNBinaryView* object, BNFunction* func)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new BinaryView(BNNewViewReference(object));
+ Ref<Function> funcObj = new Function(BNNewFunctionReference(func));
+ notify->OnAnalysisFunctionUpdateRequested(view, funcObj);
+}
+
+
void BinaryDataNotification::DataVariableAddedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
@@ -148,6 +157,7 @@ BinaryDataNotification::BinaryDataNotification()
m_callbacks.functionAdded = FunctionAddedCallback;
m_callbacks.functionRemoved = FunctionRemovedCallback;
m_callbacks.functionUpdated = FunctionUpdatedCallback;
+ m_callbacks.functionUpdateRequested = FunctionUpdateRequestedCallback;
m_callbacks.dataVariableAdded = DataVariableAddedCallback;
m_callbacks.dataVariableRemoved = DataVariableRemovedCallback;
m_callbacks.dataVariableUpdated = DataVariableUpdatedCallback;
@@ -1949,6 +1959,19 @@ uint64_t BinaryView::GetUIntMetadata(const string& key)
return data->GetUnsignedInteger();
}
+
+uint64_t BinaryView::GetMaxFunctionSizeForAnalysis()
+{
+ return BNGetMaxFunctionSizeForAnalysis(m_object);
+}
+
+
+void BinaryView::SetMaxFunctionSizeForAnalysis(uint64_t size)
+{
+ BNSetMaxFunctionSizeForAnalysis(m_object, size);
+}
+
+
BinaryData::BinaryData(FileMetadata* file): BinaryView(BNCreateBinaryDataView(file->GetObject()))
{
}
diff --git a/function.cpp b/function.cpp
index ab5f0ea3..1e91f8f3 100644
--- a/function.cpp
+++ b/function.cpp
@@ -1359,6 +1359,30 @@ vector<DisassemblyTextLine> Function::GetTypeTokens(DisassemblySettings* setting
}
+bool Function::IsFunctionTooLarge()
+{
+ return BNIsFunctionTooLarge(m_object);
+}
+
+
+bool Function::IsAnalysisSkipped()
+{
+ return BNIsFunctionAnalysisSkipped(m_object);
+}
+
+
+BNFunctionAnalysisSkipOverride Function::GetAnalysisSkipOverride()
+{
+ return BNGetFunctionAnalysisSkipOverride(m_object);
+}
+
+
+void Function::SetAnalysisSkipOverride(BNFunctionAnalysisSkipOverride skip)
+{
+ BNSetFunctionAnalysisSkipOverride(m_object, skip);
+}
+
+
AdvancedFunctionAnalysisDataRequestor::AdvancedFunctionAnalysisDataRequestor(Function* func): m_func(func)
{
if (m_func)
diff --git a/functiongraph.cpp b/functiongraph.cpp
index 77754913..a743254e 100644
--- a/functiongraph.cpp
+++ b/functiongraph.cpp
@@ -131,6 +131,12 @@ vector<Ref<FunctionGraphBlock>> FunctionGraph::GetBlocks()
}
+bool FunctionGraph::HasBlocks() const
+{
+ return BNFunctionGraphHasBlocks(m_graph);
+}
+
+
int FunctionGraph::GetWidth() const
{
return BNGetFunctionGraphWidth(m_graph);
diff --git a/python/binaryview.py b/python/binaryview.py
index 7a6bc875..1c986a94 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -65,6 +65,9 @@ class BinaryDataNotification(object):
def function_updated(self, view, func):
pass
+ def function_update_requested(self, view, func):
+ pass
+
def data_var_added(self, view, var):
pass
@@ -180,6 +183,7 @@ class BinaryDataNotificationCallbacks(object):
self._cb.functionAdded = self._cb.functionAdded.__class__(self._function_added)
self._cb.functionRemoved = self._cb.functionRemoved.__class__(self._function_removed)
self._cb.functionUpdated = self._cb.functionUpdated.__class__(self._function_updated)
+ self._cb.functionUpdateRequested = self._cb.functionUpdateRequested.__class__(self._function_update_requested)
self._cb.dataVariableAdded = self._cb.dataVariableAdded.__class__(self._data_var_added)
self._cb.dataVariableRemoved = self._cb.dataVariableRemoved.__class__(self._data_var_removed)
self._cb.dataVariableUpdated = self._cb.dataVariableUpdated.__class__(self._data_var_updated)
@@ -230,6 +234,12 @@ class BinaryDataNotificationCallbacks(object):
except:
log.log_error(traceback.format_exc())
+ def _function_update_requested(self, ctxt, view, func):
+ try:
+ self.notify.function_update_requested(self.view, function.Function(self.view, core.BNNewFunctionReference(func)))
+ except:
+ log.log_error(traceback.format_exc())
+
def _data_var_added(self, ctxt, view, var):
try:
address = var[0].address
@@ -1013,6 +1023,15 @@ class BinaryView(object):
result = core.BNGetGlobalPointerValue(self.handle)
return function.RegisterValue(self.arch, result.value, confidence = result.confidence)
+ @property
+ def max_function_size_for_analysis(self):
+ """Maximum size of function (sum of basic block sizes in bytes) for auto analysis"""
+ return core.BNGetMaxFunctionSizeForAnalysis(self.handle)
+
+ @max_function_size_for_analysis.setter
+ def max_function_size_for_analysis(self, size):
+ core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
+
def __len__(self):
return int(core.BNGetViewLength(self.handle))
diff --git a/python/function.py b/python/function.py
index f68aa76f..0d796d98 100644
--- a/python/function.py
+++ b/python/function.py
@@ -26,7 +26,8 @@ import ctypes
import _binaryninjacore as core
from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType,
HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend,
- DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType)
+ DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType,
+ FunctionAnalysisSkipOverride)
import architecture
import platform
import highlight
@@ -817,6 +818,32 @@ class Function(object):
for i in block:
yield i
+ @property
+ def too_large(self):
+ """Whether the function is too large to automatically perform analysis (read-only)"""
+ return core.BNIsFunctionTooLarge(self.handle)
+
+ @property
+ def analysis_skipped(self):
+ """Whether automatic analysis was skipped for this function"""
+ return core.BNIsFunctionAnalysisSkipped(self.handle)
+
+ @analysis_skipped.setter
+ def analysis_skipped(self, skip):
+ if skip:
+ core.BNSetFunctionAnalysisSkipOverride(self.handle, FunctionAnalysisSkipOverride.AlwaysSkipFunctionAnalysis)
+ else:
+ core.BNSetFunctionAnalysisSkipOverride(self.handle, FunctionAnalysisSkipOverride.NeverSkipFunctionAnalysis)
+
+ @property
+ def analysis_skip_override(self):
+ """Override for skipping of automatic analysis"""
+ return FunctionAnalysisSkipOverride(core.BNGetFunctionAnalysisSkipOverride(self.handle))
+
+ @analysis_skip_override.setter
+ def analysis_skip_override(self, override):
+ core.BNSetFunctionAnalysisSkipOverride(self.handle, override)
+
def __iter__(self):
count = ctypes.c_ulonglong()
blocks = core.BNGetFunctionBasicBlockList(self.handle, count)
@@ -1836,6 +1863,11 @@ class FunctionGraph(object):
return result
@property
+ def has_blocks(self):
+ """Whether the function graph has at least one block (read-only)"""
+ return core.BNFunctionGraphHasBlocks(self.handle)
+
+ @property
def width(self):
"""Function graph width (read-only)"""
return core.BNGetFunctionGraphWidth(self.handle)