summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--activity.cpp6
-rw-r--r--binaryninjaapi.h24
-rw-r--r--binaryninjacore.h22
-rw-r--r--binaryview.cpp4
-rw-r--r--function.cpp4
-rw-r--r--python/binaryview.py2
-rw-r--r--python/function.py2
-rw-r--r--python/workflow.py156
-rw-r--r--workflow.cpp106
9 files changed, 266 insertions, 60 deletions
diff --git a/activity.cpp b/activity.cpp
index 4b2f933f..fcc7386a 100644
--- a/activity.cpp
+++ b/activity.cpp
@@ -5,8 +5,7 @@ using namespace BinaryNinja;
using namespace std;
-Activity::Activity(const string& configuration, const std::function<void(Ref<AnalysisContext> analysisContext)>& action) :
- m_action(action)
+Activity::Activity(const string& configuration, const std::function<void(Ref<AnalysisContext> analysisContext)>& action) : m_action(action)
{
// LogError("API-Side Activity Constructed!");
m_object = BNCreateActivity(configuration.c_str(), this, Run);
@@ -15,6 +14,7 @@ Activity::Activity(const string& configuration, const std::function<void(Ref<Ana
Activity::Activity(BNActivity* activity)
{
+ // LogError("API-Side Activity Constructed!");
m_object = BNNewActivityReference(activity);
}
@@ -27,6 +27,7 @@ Activity::~Activity()
void Activity::Run(void* ctxt, BNAnalysisContext* analysisContext)
{
+ // LogError("API-Side Activity Run!");
Activity* activity = (Activity*)ctxt;
Ref<AnalysisContext> ac = new AnalysisContext(BNNewAnalysisContextReference(analysisContext));
activity->m_action(ac);
@@ -35,6 +36,7 @@ void Activity::Run(void* ctxt, BNAnalysisContext* analysisContext)
string Activity::GetName() const
{
+ // LogError("API-Side Activity GetName!");
char* name = BNActivityGetName(m_object);
string result = name;
BNFreeString(name);
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index bcaf644e..e67a836e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -6419,7 +6419,7 @@ namespace BinaryNinja {
void Reanalyze();
- Ref<Workflow> GetWorkflow() const;
+ Ref<Workflow> GetWorkflow();
/*! Displays contents to the user in the UI or on the command-line
@@ -9914,6 +9914,20 @@ namespace BinaryNinja {
std::string GetName() const;
};
+ class WorkflowMachine
+ {
+ Ref<BinaryView> m_view;
+ Ref<Function> m_function;
+
+ public:
+ WorkflowMachine(Ref<BinaryView> view);
+ WorkflowMachine(Ref<Function> function);
+
+ std::optional<bool> QueryOverride(const std::string& activity);
+ bool SetOverride(const std::string& activity, bool enable);
+ bool ClearOverride(const std::string& activity);
+ };
+
/*! A Binary Ninja Workflow is an abstraction of a computational binary analysis pipeline and it provides the extensibility
mechanism needed for tailored binary analysis and decompilation. More specifically, a Workflow is a repository of activities along with a
unique strategy to execute them. Binary Ninja provides two Workflows named ``core.module.defaultAnalysis`` and ``core.function.defaultAnalysis``
@@ -9927,9 +9941,13 @@ namespace BinaryNinja {
*/
class Workflow : public CoreRefCountObject<BNWorkflow, BNNewWorkflowReference, BNFreeWorkflow>
{
+ std::unique_ptr<WorkflowMachine> m_machine;
+
public:
Workflow(const std::string& name = "");
Workflow(BNWorkflow* workflow);
+ Workflow(BNWorkflow* workflow, Ref<BinaryView> view);
+ Workflow(BNWorkflow* workflow, Ref<Function> function);
virtual ~Workflow() {}
/*! Get a list of all workflows
@@ -10095,6 +10113,8 @@ namespace BinaryNinja {
void ShowReport(const std::string& name);
std::vector<std::string> GetEligibilitySettings();
+
+ WorkflowMachine* GetWorkflowMachine() const { return m_machine.get(); }
};
class DisassemblySettings :
@@ -11012,7 +11032,7 @@ namespace BinaryNinja {
void MarkUpdatesRequired(BNFunctionUpdateType type = UserFunctionUpdate);
void MarkCallerUpdatesRequired(BNFunctionUpdateType type = UserFunctionUpdate);
- Ref<Workflow> GetWorkflow() const;
+ Ref<Workflow> GetWorkflow();
void RequestAdvancedAnalysisData();
void ReleaseAdvancedAnalysisData();
diff --git a/binaryninjacore.h b/binaryninjacore.h
index e1b08f5c..2fcf82c6 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -37,14 +37,14 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
-#define BN_CURRENT_CORE_ABI_VERSION 80
+#define BN_CURRENT_CORE_ABI_VERSION 81
// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
// will require rebuilding. The minimum version is increased when there are
// incompatible changes that break binary compatibility, such as changes to
// existing types or functions.
-#define BN_MINIMUM_CORE_ABI_VERSION 80
+#define BN_MINIMUM_CORE_ABI_VERSION 81
#ifdef __GNUC__
#ifdef BINARYNINJACORE_LIBRARY
@@ -5157,11 +5157,6 @@ extern "C"
BINARYNINJACOREAPI void BNMarkUpdatesRequired(BNFunction* func, BNFunctionUpdateType type);
BINARYNINJACOREAPI void BNMarkCallerUpdatesRequired(BNFunction* func, BNFunctionUpdateType type);
- BINARYNINJACOREAPI BNWorkflow* BNGetWorkflowForBinaryView(BNBinaryView* view);
- BINARYNINJACOREAPI BNWorkflow* BNGetWorkflowForFunction(BNFunction* func);
- BINARYNINJACOREAPI char* BNPostWorkflowRequestForFunction(BNFunction* func, const char* request);
- BINARYNINJACOREAPI char* BNGetProvenanceString(BNFunction* func);
-
BINARYNINJACOREAPI BNHighlightColor BNGetInstructionHighlight(
BNFunction* func, BNArchitecture* arch, uint64_t addr);
BINARYNINJACOREAPI void BNSetAutoInstructionHighlight(
@@ -5433,6 +5428,19 @@ extern "C"
BINARYNINJACOREAPI const char** BNWorkflowGetEligibilitySettings(BNWorkflow* workflow, size_t* inoutSize);
+ // BinaryView Workflow Machine
+ BINARYNINJACOREAPI BNWorkflow* BNGetWorkflowForBinaryView(BNBinaryView* view);
+ BINARYNINJACOREAPI char* BNPostWorkflowRequestForBinaryView(BNBinaryView* view, const char* request);
+ BINARYNINJACOREAPI void BNShowWorkflowReportForBinaryView(BNBinaryView* view, const char* name);
+
+ // Function Workflow Machine
+ BINARYNINJACOREAPI BNWorkflow* BNGetWorkflowForFunction(BNFunction* func);
+ BINARYNINJACOREAPI char* BNPostWorkflowRequestForFunction(BNFunction* func, const char* request);
+ BINARYNINJACOREAPI void BNShowWorkflowReportForFunction(BNFunction* func, const char* name);
+
+ // Provenance
+ BINARYNINJACOREAPI char* BNGetProvenanceString(BNFunction* func);
+
// Disassembly settings
BINARYNINJACOREAPI BNDisassemblySettings* BNCreateDisassemblySettings(void);
BINARYNINJACOREAPI BNDisassemblySettings* BNNewDisassemblySettingsReference(BNDisassemblySettings* settings);
diff --git a/binaryview.cpp b/binaryview.cpp
index 7bd9cec8..32aff542 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -4678,12 +4678,12 @@ void BinaryView::Reanalyze()
}
-Ref<Workflow> BinaryView::GetWorkflow() const
+Ref<Workflow> BinaryView::GetWorkflow()
{
BNWorkflow* workflow = BNGetWorkflowForBinaryView(m_object);
if (!workflow)
return nullptr;
- return new Workflow(workflow);
+ return new Workflow(workflow, this);
}
diff --git a/function.cpp b/function.cpp
index ab441193..433bdea1 100644
--- a/function.cpp
+++ b/function.cpp
@@ -2483,12 +2483,12 @@ void Function::MarkCallerUpdatesRequired(BNFunctionUpdateType type)
}
-Ref<Workflow> Function::GetWorkflow() const
+Ref<Workflow> Function::GetWorkflow()
{
BNWorkflow* workflow = BNGetWorkflowForFunction(m_object);
if (!workflow)
return nullptr;
- return new Workflow(workflow);
+ return new Workflow(workflow, this);
}
diff --git a/python/binaryview.py b/python/binaryview.py
index 3d5187d6..8c056db0 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -8945,7 +8945,7 @@ to a the type "tagRECT" found in the typelibrary "winX64common"
handle = core.BNGetWorkflowForBinaryView(self.handle)
if handle is None:
return None
- return _workflow.Workflow(handle=handle)
+ return _workflow.Workflow(handle=handle, object_handle=self.handle)
def rebase(self, address: int, force: Optional[bool] = False,
progress_func: Optional[ProgressFuncType] = None) -> Optional['BinaryView']:
diff --git a/python/function.py b/python/function.py
index 62a5dc0c..e43c11e2 100644
--- a/python/function.py
+++ b/python/function.py
@@ -3021,7 +3021,7 @@ class Function:
handle = core.BNGetWorkflowForFunction(self.handle)
if handle is None:
return None
- return workflow.Workflow(handle=handle, function_handle=self.handle)
+ return workflow.Workflow(handle=handle, object_handle=self.handle)
@property
def provenance(self):
diff --git a/python/workflow.py b/python/workflow.py
index 77227933..98e3118b 100644
--- a/python/workflow.py
+++ b/python/workflow.py
@@ -253,7 +253,7 @@ class Workflow(metaclass=_WorkflowMetaclass):
.. note:: Binary Ninja Workflows is currently under development and available as an early feature preview. For additional documentation see Help / User Guide / Developer Guide / Workflows
"""
- def __init__(self, name: str = "", handle: core.BNWorkflowHandle = None, query_registry: bool = True, function_handle: core.BNFunctionHandle = None):
+ def __init__(self, name: str = "", handle: core.BNWorkflowHandle = None, query_registry: bool = True, object_handle: Union[core.BNFunctionHandle, core.BNBinaryViewHandle] = None):
if handle is None:
if query_registry:
_handle = core.BNWorkflowInstance(str(name))
@@ -265,8 +265,8 @@ class Workflow(metaclass=_WorkflowMetaclass):
self.handle = _handle
self._name = core.BNGetWorkflowName(self.handle)
self._machine = None
- if function_handle is not None:
- self._machine = WorkflowMachine(function_handle)
+ if object_handle is not None:
+ self._machine = WorkflowMachine(object_handle)
def __del__(self):
if core is not None:
@@ -498,14 +498,6 @@ class Workflow(metaclass=_WorkflowMetaclass):
core.BNShowGraphReport(None, f'{self.name} <{activity}>' if activity else self.name, graph.handle)
return graph
- def show_metrics(self) -> None:
- """
- ``show_metrics`` Not yet implemented.
-
- :rtype: None
- """
- core.BNWorkflowShowReport(self.handle, "metrics")
-
def show_topology(self) -> None:
"""
``show_topology`` Show the Workflow topology in the UI.
@@ -514,14 +506,6 @@ class Workflow(metaclass=_WorkflowMetaclass):
"""
core.BNWorkflowShowReport(self.handle, "topology")
- def show_trace(self) -> None:
- """
- ``show_trace`` Not yet implemented.
-
- :rtype: None
- """
- core.BNWorkflowShowReport(self.handle, "trace")
-
def eligibility_settings(self) -> List[str]:
"""
``eligibility_settings`` Retrieve the list of eligibility settings for the Workflow.
@@ -548,28 +532,67 @@ class Workflow(metaclass=_WorkflowMetaclass):
raise AttributeError("Machine does not exist.")
class WorkflowMachine:
- def __init__(self, handle: core.BNFunctionHandle = None):
+ def __init__(self, handle: Union[core.BNFunctionHandle, core.BNBinaryViewHandle] = None):
+ if isinstance(handle, core.BNFunctionHandle):
+ self.is_function_machine = True
+ elif isinstance(handle, core.BNBinaryViewHandle):
+ self.is_function_machine = False
+ else:
+ raise ValueError("WorkflowMachine requires a Function or BinaryView handle!")
self.handle = handle
+ def show_metrics(self) -> None:
+ if self.is_function_machine:
+ core.BNShowWorkflowReportForFunction(self.handle, "metrics")
+ else:
+ core.BNShowWorkflowReportForBinaryView(self.handle, "metrics")
+
+ def show_topology(self) -> None:
+ if self.is_function_machine:
+ core.BNShowWorkflowReportForFunction(self.handle, "topology")
+ else:
+ core.BNShowWorkflowReportForBinaryView(self.handle, "topology")
+
+ def show_trace(self) -> None:
+ if self.is_function_machine:
+ core.BNShowWorkflowReportForFunction(self.handle, "trace")
+ else:
+ core.BNShowWorkflowReportForBinaryView(self.handle, "trace")
+
def log(self, enable: bool = True, is_global: bool = False):
request = json.dumps({"command": "log", "enable": enable, "global": is_global})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def metrics(self, enable: bool = True, is_global: bool = False):
request = json.dumps({"command": "metrics", "enable": enable, "global": is_global})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def dump(self):
request = json.dumps({"command": "dump"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def configure(self, advanced: bool = True, incremental: bool = False):
request = json.dumps({"command": "configure", "advanced": advanced, "incremental": incremental})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def resume(self):
request = json.dumps({"command": "run"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def run(self):
status = self.status()
@@ -580,62 +603,109 @@ class WorkflowMachine:
raise AttributeError("Unknown status response!")
request = json.dumps({"command": "run"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def abort(self):
request = json.dumps({"command": "abort"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def halt(self):
request = json.dumps({"command": "halt"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def reset(self):
request = json.dumps({"command": "reset"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def enable(self):
request = json.dumps({"command": "enable"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def disable(self):
request = json.dumps({"command": "disable"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def step(self):
request = json.dumps({"command": "step"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def breakpoint_delete(self, activities):
request = json.dumps({"command": "breakpoint", "action": "delete", "activities": activities})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def breakpoint_query(self):
request = json.dumps({"command": "breakpoint", "action": "query"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def breakpoint_set(self, activities):
request = json.dumps({"command": "breakpoint", "action": "set", "activities": activities})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def status(self):
request = json.dumps({"command": "status"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def override_clear(self, activity):
request = json.dumps({"command": "override", "action": "clear", "activity": activity})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
- def override_query(self):
- request = json.dumps({"command": "override", "action": "query"})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ def override_query(self, activity = None):
+ if activity is None:
+ activity = ""
+ request = json.dumps({"command": "override", "action": "query", "activity": activity})
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def override_set(self, activity, enable):
request = json.dumps({"command": "override", "action": "set", "activity": activity, "enable": enable})
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def request(self, request):
- return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ if self.is_function_machine:
+ return json.loads(core.BNPostWorkflowRequestForFunction(self.handle, request))
+ else:
+ return json.loads(core.BNPostWorkflowRequestForBinaryView(self.handle, request))
def cli(self):
WorkflowMachineCLI(self).cmdloop()
@@ -811,7 +881,7 @@ class WorkflowMachineCLI(cmd.Cmd):
status = self.machine.override_clear(args.activity)
print(json.dumps(status, indent=4))
elif args.action == "query":
- status = self.machine.override_query()
+ status = self.machine.override_query(args.activity)
accepted = status.get('commandStatus', {}).get('accepted', False)
if accepted:
response = status.pop("response", None)
diff --git a/workflow.cpp b/workflow.cpp
index 0d02ab5b..90ddb024 100644
--- a/workflow.cpp
+++ b/workflow.cpp
@@ -1,5 +1,6 @@
#include "binaryninjaapi.h"
#include "json/json.h"
+#include "rapidjsonwrapper.h"
#include <string>
#include <variant>
@@ -100,6 +101,97 @@ bool AnalysisContext::Inform(const string& request)
}
+WorkflowMachine::WorkflowMachine(Ref<BinaryView> view): m_view(view)
+{
+
+}
+
+
+WorkflowMachine::WorkflowMachine(Ref<Function> function): m_function(function)
+{
+
+}
+
+
+std::optional<bool> WorkflowMachine::QueryOverride(const string& activity)
+{
+ rapidjson::Document request(rapidjson::kObjectType);
+ rapidjson::Document::AllocatorType& allocator = request.GetAllocator();
+ request.AddMember("command", "override", allocator);
+ request.AddMember("action", "query", allocator);
+ request.AddMember("activity", rapidjson::Value(activity.c_str(), allocator), allocator);
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ request.Accept(writer);
+
+ string jsonResult;
+ if (m_function)
+ jsonResult = BNPostWorkflowRequestForFunction(m_function->GetObject(), buffer.GetString());
+ else
+ jsonResult = BNPostWorkflowRequestForBinaryView(m_view->GetObject(), buffer.GetString());
+
+ rapidjson::Document response(rapidjson::kObjectType);
+ response.Parse(jsonResult.c_str());
+ if (response.HasMember("response") && response["response"].HasMember("activity") && response["response"]["activity"].HasMember("override"))
+ return response["response"]["activity"]["override"].GetBool();
+
+ return std::nullopt;
+}
+
+
+bool WorkflowMachine::SetOverride(const string& activity, bool enable)
+{
+ rapidjson::Document request(rapidjson::kObjectType);
+ rapidjson::Document::AllocatorType& allocator = request.GetAllocator();
+ request.AddMember("command", "override", allocator);
+ request.AddMember("action", "set", allocator);
+ request.AddMember("activity", rapidjson::Value(activity.c_str(), allocator), allocator);
+ request.AddMember("enable", enable, allocator);
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ request.Accept(writer);
+
+ string jsonResult;
+ if (m_function)
+ jsonResult = BNPostWorkflowRequestForFunction(m_function->GetObject(), buffer.GetString());
+ else
+ jsonResult = BNPostWorkflowRequestForBinaryView(m_view->GetObject(), buffer.GetString());
+
+ rapidjson::Document response(rapidjson::kObjectType);
+ response.Parse(jsonResult.c_str());
+ if (response.HasMember("commandStatus") && response["commandStatus"].HasMember("accepted"))
+ return response["commandStatus"]["accepted"].GetBool();
+
+ return false;
+}
+
+
+bool WorkflowMachine::ClearOverride(const string& activity)
+{
+ rapidjson::Document request(rapidjson::kObjectType);
+ rapidjson::Document::AllocatorType& allocator = request.GetAllocator();
+ request.AddMember("command", "override", allocator);
+ request.AddMember("action", "clear", allocator);
+ request.AddMember("activity", rapidjson::Value(activity.c_str(), allocator), allocator);
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ request.Accept(writer);
+
+ string jsonResult;
+ if (m_function)
+ jsonResult = BNPostWorkflowRequestForFunction(m_function->GetObject(), buffer.GetString());
+ else
+ jsonResult = BNPostWorkflowRequestForBinaryView(m_view->GetObject(), buffer.GetString());
+
+ rapidjson::Document response(rapidjson::kObjectType);
+ response.Parse(jsonResult.c_str());
+ if (response.HasMember("commandStatus") && response["commandStatus"].HasMember("accepted"))
+ return response["commandStatus"]["accepted"].GetBool();
+
+ return false;
+}
+
+
Workflow::Workflow(const string& name)
{
m_object = BNCreateWorkflow(name.c_str());
@@ -112,6 +204,20 @@ Workflow::Workflow(BNWorkflow* workflow)
}
+Workflow::Workflow(BNWorkflow* workflow, Ref<BinaryView> view)
+{
+ m_object = BNNewWorkflowReference(workflow);
+ m_machine = make_unique<WorkflowMachine>(view);
+}
+
+
+Workflow::Workflow(BNWorkflow* workflow, Ref<Function> function)
+{
+ m_object = BNNewWorkflowReference(workflow);
+ m_machine = make_unique<WorkflowMachine>(function);
+}
+
+
vector<Ref<Workflow>> Workflow::GetList()
{
size_t count;