Skip to content

Commit f5ff6f5

Browse files
committed
Add support for recoverable analysis abort.
1 parent 6a8a2d5 commit f5ff6f5

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

binaryninjaapi.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5224,9 +5224,9 @@ namespace BinaryNinja {
52245224
*/
52255225
void UpdateAnalysis();
52265226

5227-
/*! Abort the currently running analysis
5227+
/*! Abort analysis and suspend the workflow machine
52285228

5229-
This method should be considered non-recoverable and generally only used when shutdown is imminent after stopping.
5229+
Stops analysis and transitions the workflow machine to the Suspend state. This operation is recoverable, and the workflow machine can be re-enabled via the WorkflowMachine Enable API.
52305230
*/
52315231
void AbortAnalysis();
52325232

@@ -10058,6 +10058,22 @@ namespace BinaryNinja {
1005810058
WorkflowMachine(Ref<BinaryView> view);
1005910059
WorkflowMachine(Ref<Function> function);
1006010060

10061+
/*! Enable the workflow machine
10062+
10063+
Re-enables the workflow machine if it is in the Suspend state.
10064+
\return true if the command is accepted, false otherwise.
10065+
*/
10066+
bool Enable();
10067+
10068+
/*! Disable the workflow machine
10069+
10070+
Disables analysis and suspends the workflow machine, equivalent to AbortAnalysis.
10071+
This operation is recoverable and the workflow machine can be re-enabled via the Enable API.
10072+
\return true if the command is accepted, false otherwise.
10073+
*/
10074+
bool Disable();
10075+
10076+
1006110077
std::optional<bool> QueryOverride(const std::string& activity);
1006210078
bool SetOverride(const std::string& activity, bool enable);
1006310079
bool ClearOverride(const std::string& activity);

python/binaryview.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,9 +4931,8 @@ def update_analysis_and_wait(self) -> None:
49314931

49324932
def abort_analysis(self) -> None:
49334933
"""
4934-
``abort_analysis`` will abort the currently running analysis.
4935-
4936-
.. warning:: This method should be considered non-recoverable and generally only used when shutdown is imminent after stopping.
4934+
``abort_analysis`` aborts analysis and suspends the workflow machine. This operation is recoverable, and the workflow machine
4935+
can be re-enabled via the ``enable`` API on WorkflowMachine.
49374936
49384937
:rtype: None
49394938
"""

workflow.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,54 @@ WorkflowMachine::WorkflowMachine(Ref<Function> function): m_function(function)
122122
}
123123

124124

125+
bool WorkflowMachine::Enable()
126+
{
127+
rapidjson::Document request(rapidjson::kObjectType);
128+
rapidjson::Document::AllocatorType& allocator = request.GetAllocator();
129+
request.AddMember("command", "enable", allocator);
130+
rapidjson::StringBuffer buffer;
131+
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
132+
request.Accept(writer);
133+
134+
string jsonResult;
135+
if (m_function)
136+
jsonResult = BNPostWorkflowRequestForFunction(m_function->GetObject(), buffer.GetString());
137+
else
138+
jsonResult = BNPostWorkflowRequestForBinaryView(m_view->GetObject(), buffer.GetString());
139+
140+
rapidjson::Document response(rapidjson::kObjectType);
141+
response.Parse(jsonResult.c_str());
142+
if (response.HasMember("commandStatus") && response["commandStatus"].HasMember("accepted"))
143+
return response["commandStatus"]["accepted"].GetBool();
144+
145+
return false;
146+
}
147+
148+
149+
bool WorkflowMachine::Disable()
150+
{
151+
rapidjson::Document request(rapidjson::kObjectType);
152+
rapidjson::Document::AllocatorType& allocator = request.GetAllocator();
153+
request.AddMember("command", "disable", allocator);
154+
rapidjson::StringBuffer buffer;
155+
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
156+
request.Accept(writer);
157+
158+
string jsonResult;
159+
if (m_function)
160+
jsonResult = BNPostWorkflowRequestForFunction(m_function->GetObject(), buffer.GetString());
161+
else
162+
jsonResult = BNPostWorkflowRequestForBinaryView(m_view->GetObject(), buffer.GetString());
163+
164+
rapidjson::Document response(rapidjson::kObjectType);
165+
response.Parse(jsonResult.c_str());
166+
if (response.HasMember("commandStatus") && response["commandStatus"].HasMember("accepted"))
167+
return response["commandStatus"]["accepted"].GetBool();
168+
169+
return false;
170+
}
171+
172+
125173
std::optional<bool> WorkflowMachine::QueryOverride(const string& activity)
126174
{
127175
rapidjson::Document request(rapidjson::kObjectType);

0 commit comments

Comments
 (0)