diff options
| author | Mark Rowe <mark@vector35.com> | 2025-08-11 10:42:07 -0700 |
|---|---|---|
| committer | Mark Rowe <mark@vector35.com> | 2025-08-27 19:15:49 -0700 |
| commit | 2303f75b080f6dd0c9a5c669a71f64ce830f5650 (patch) | |
| tree | a49d80ea0a8131a50c16f85e767722679ff08c85 /plugins/workflow_objc/src/workflow.rs | |
| parent | b302d7ba796f41b1102ee61feed8b8e212299997 (diff) | |
Rewrite Obj-C workflow in Rust
This is functionally equivalent to the previous workflow_objc, with the
following changes:
1. It mutates the `core.function.metaAnalysis` workflow rather than
registering a new named workflow. The activities now all check for
the presence of the Objective-C metadata added by `ObjCProcessor` to
determine whether they should do work, rather than relying on
`MachoView` to override the function workflow when Objective-C
metadata is present. This fixes
https://github.com/Vector35/binaryninja-api/issues/6779.
2. The auto-inlining of `objc_msgSend` selector stub functions is
performed in a separate activity from the processing of
`objc_msgSend` call sites. The selector stub inlining activity is
configured so that it does not run in `DSCView` as the shared cache
needs different behavior for stub functions more generally that
`SharedCacheWorkflow` already provides.
3. The way that types like `id` and `SEL` are referenced is fixed so
that they show up as `id` rather than `objc_struct*`.
This also replaces the Objective-C portion of the shared cache's
workflow, and incorporates several bug fixes that had been applied to it
but not the standalone Objective-C workflow.
Diffstat (limited to 'plugins/workflow_objc/src/workflow.rs')
| -rw-r--r-- | plugins/workflow_objc/src/workflow.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/plugins/workflow_objc/src/workflow.rs b/plugins/workflow_objc/src/workflow.rs new file mode 100644 index 00000000..090a8e5e --- /dev/null +++ b/plugins/workflow_objc/src/workflow.rs @@ -0,0 +1,57 @@ +use binaryninja::workflow::{activity, Activity, AnalysisContext, Workflow}; + +use crate::{activities, error::WorkflowRegistrationError}; + +const WORKFLOW_INFO: &str = r#"{ + "title": "Objective-C", + "description": "Enhanced analysis for Objective-C code.", + "capabilities": [] +}"#; + +fn run<E: std::fmt::Debug>( + func: impl Fn(&AnalysisContext) -> Result<(), E>, +) -> impl Fn(&AnalysisContext) { + move |ac| { + if let Err(err) = func(ac) { + log::debug!("Error occurred while running activity: {err:#x?}"); + } + } +} + +pub fn register_activities() -> Result<(), WorkflowRegistrationError> { + let workflow = + Workflow::cloned("core.function.metaAnalysis").ok_or(WorkflowRegistrationError)?; + + let objc_msg_send_calls_activity = Activity::new_with_action( + activity::Config::action( + "core.function.objectiveC.analyzeMessageSends", + "Obj-C: Analyze Message Sends", + "Analyze inline objc_msgSend calls, including applying call type adjustments and resolving to direct calls (if enabled)", + ).eligibility( + activity::Eligibility::auto().predicate( + activity::ViewType::in_(["Mach-O", "DSCView"]), + )), + run(activities::objc_msg_send_calls::process), + ); + + let inline_stubs_activity = Activity::new_with_action( + activity::Config::action( + "core.function.objectiveC.inlineStubs", + "Obj-C: Inline Message Send Stubs", + "Inline Objective-C selector stubs, such as _objc_msgSend$foo, into their callers", + ) + .eligibility( + activity::Eligibility::without_setting() + // The shared cache view does its own inlining of stub functions. + .predicate(activity::ViewType::in_(["Mach-O"])), + ), + run(activities::inline_stubs::process), + ); + + workflow + .activity_after(&inline_stubs_activity, "core.function.translateTailCalls")? + .activity_after(&objc_msg_send_calls_activity, &inline_stubs_activity.name())? + .register_with_config(WORKFLOW_INFO)?; + + Ok(()) +} |
