Skip to content

Commit 8ba7106

Browse files
committed
Support eligibility callbacks through the API for Workflow actions.
1 parent f1eccb7 commit 8ba7106

File tree

4 files changed

+35
-12
lines changed

4 files changed

+35
-12
lines changed

activity.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ using namespace BinaryNinja;
55
using namespace std;
66

77

8-
Activity::Activity(const string& configuration, const std::function<void(Ref<AnalysisContext> analysisContext)>& action) : m_action(action)
8+
Activity::Activity(const string& configuration, const std::function<void(Ref<AnalysisContext> analysisContext)>& action,
9+
const std::function<bool(Ref<Activity>, Ref<AnalysisContext>)>& eligibility) : m_action(action), m_eligibility(eligibility)
910
{
1011
// LogError("API-Side Activity Constructed!");
11-
m_object = BNCreateActivity(configuration.c_str(), this, Run);
12+
if (eligibility)
13+
m_object = BNCreateActivityWithEligibility(configuration.c_str(), this, RunAction, CheckEligibility);
14+
else
15+
m_object = BNCreateActivity(configuration.c_str(), this, RunAction);
1216
}
1317

1418

@@ -25,12 +29,21 @@ Activity::~Activity()
2529
}
2630

2731

28-
void Activity::Run(void* ctxt, BNAnalysisContext* analysisContext)
32+
void Activity::RunAction(void* ctxt, BNAnalysisContext* analysisContext)
2933
{
30-
// LogError("API-Side Activity Run!");
31-
Activity* activity = (Activity*)ctxt;
34+
// LogError("API-Side Activity RunAction!");
35+
auto boundActivity = static_cast<Activity*>(ctxt);
3236
Ref<AnalysisContext> ac = new AnalysisContext(BNNewAnalysisContextReference(analysisContext));
33-
activity->m_action(ac);
37+
boundActivity->m_action(ac);
38+
}
39+
40+
41+
bool Activity::CheckEligibility(void* ctxt, BNActivity* activity, BNAnalysisContext* analysisContext)
42+
{
43+
auto boundActivity = static_cast<Activity*>(ctxt);
44+
Ref<Activity> act = new Activity(BNNewActivityReference(activity));
45+
Ref<AnalysisContext> ac = new AnalysisContext(BNNewAnalysisContextReference(analysisContext));
46+
return boundActivity->m_eligibility(act, ac);
3447
}
3548

3649

binaryninjaapi.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9943,15 +9943,19 @@ namespace BinaryNinja {
99439943
{
99449944
protected:
99459945
std::function<void(Ref<AnalysisContext> analysisContext)> m_action;
9946+
std::function<bool(Ref<Activity>, Ref<AnalysisContext>)> m_eligibility;
99469947

9947-
static void Run(void* ctxt, BNAnalysisContext* analysisContext);
9948+
static void RunAction(void* ctxt, BNAnalysisContext* analysisContext);
9949+
static bool CheckEligibility(void* ctxt, BNActivity* activity, BNAnalysisContext* analysisContext);
99489950

99499951
public:
99509952
/*!
99519953
\param configuration a JSON representation of the activity configuration
99529954
\param action Workflow action, a function taking a Ref<AnalysisContext> as an argument.
9955+
\param eligibility A function that determines whether the activity is eligible to run
99539956
*/
9954-
Activity(const std::string& configuration, const std::function<void(Ref<AnalysisContext>)>& action);
9957+
Activity(const std::string& configuration, const std::function<void(Ref<AnalysisContext>)>& action,
9958+
const std::function<bool(Ref<Activity>, Ref<AnalysisContext>)>& eligibility = nullptr);
99559959
Activity(BNActivity* activity);
99569960
virtual ~Activity();
99579961

binaryninjacore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 88
40+
#define BN_CURRENT_CORE_ABI_VERSION 89
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
@@ -5400,6 +5400,7 @@ extern "C"
54005400

54015401
// Activity
54025402
BINARYNINJACOREAPI BNActivity* BNCreateActivity(const char* configuration, void* ctxt, void (*action)(void*, BNAnalysisContext*));
5403+
BINARYNINJACOREAPI BNActivity* BNCreateActivityWithEligibility(const char* configuration, void* ctxt, void (*action)(void*, BNAnalysisContext*), bool (*eligibilityHandler)(void*, BNActivity*, BNAnalysisContext*));
54035404
BINARYNINJACOREAPI BNActivity* BNNewActivityReference(BNActivity* activity);
54045405
BINARYNINJACOREAPI void BNFreeActivity(BNActivity* activity);
54055406

python/workflow.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,17 @@ class Activity(object):
152152
"""
153153

154154
_action_callbacks = {}
155+
_eligibility_callbacks = {}
155156

156-
def __init__(self, configuration: str = "", handle: Optional[core.BNActivityHandle] = None, action: Optional[Callable[[Any], None]] = None):
157+
def __init__(self, configuration: str = "", handle: Optional[core.BNActivityHandle] = None, action: Optional[Callable[[Any], None]] = None, eligibility: Optional[Callable[[Any], bool]] = None):
157158
if handle is None:
158-
#cls._notify(ac, callback)
159159
action_callback = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNAnalysisContext))(lambda ctxt, ac: self._action(ac))
160-
_handle = core.BNCreateActivity(configuration, None, action_callback)
160+
if eligibility:
161+
eligibility_callback = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.POINTER(core.BNActivity), ctypes.POINTER(core.BNAnalysisContext))(lambda ctxt, act, ac: eligibility(act, ac))
162+
_handle = core.BNCreateActivityWithEligibility(configuration, None, action_callback, eligibility_callback)
163+
self.__class__._eligibility_callbacks[len(self.__class__._eligibility_callbacks)] = eligibility_callback
164+
else:
165+
_handle = core.BNCreateActivity(configuration, None, action_callback)
161166
self.action = action
162167
self.__class__._action_callbacks[len(self.__class__._action_callbacks)] = action_callback
163168
else:

0 commit comments

Comments
 (0)