use binaryninja::workflow::{activity, Activity, AnalysisContext, Workflow}; use crate::{activities, error::WorkflowRegistrationError}; /// Base confidence levels for types applied by each of the activities in this workflow. /// These are ordered such that later activities can override types applied by earlier activities. #[repr(u8)] pub enum Confidence { ObjCMsgSend = 96, SuperInit = 100, } const WORKFLOW_INFO: &str = r#"{ "title": "Objective-C", "description": "Enhanced analysis for Objective-C code.", "capabilities": [] }"#; fn run( 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), ); let super_init_activity = Activity::new_with_action( activity::Config::action( "core.function.objectiveC.types.superInit", "Obj-C: Adjust return types of [super init…] calls", "Adjust the return type of calls to objc_msgSendSuper2 where the selector is in the init family.", ) .eligibility( activity::Eligibility::auto().predicate( activity::ViewType::in_(["Mach-O", "DSCView"]), )), run(activities::super_init::process), ); workflow .activity_after(&inline_stubs_activity, "core.function.translateTailCalls")? .activity_after(&objc_msg_send_calls_activity, &inline_stubs_activity.name())? .activity_after(&super_init_activity, "core.function.generateMediumLevelIL")? .register_with_config(WORKFLOW_INFO)?; Ok(()) }