binaryninja/
function_recognizer.rs1use crate::low_level_il::function::LowLevelILFunction;
2use crate::low_level_il::LowLevelILRegularFunction;
3use crate::medium_level_il::MediumLevelILFunction;
4use crate::{architecture::CoreArchitecture, binary_view::BinaryView, function::Function};
5use binaryninjacore_sys::*;
6use std::os::raw::c_void;
7
8pub trait FunctionRecognizer {
9 fn recognize_low_level_il(
10 &self,
11 _bv: &BinaryView,
12 _func: &Function,
13 _llil: &LowLevelILRegularFunction,
14 ) -> bool {
15 false
16 }
17
18 fn recognize_medium_level_il(
19 &self,
20 _bv: &BinaryView,
21 _func: &Function,
22 _mlil: &MediumLevelILFunction,
23 ) -> bool {
24 false
25 }
26}
27
28fn create_function_recognizer_registration<R>(recognizer: R) -> BNFunctionRecognizer
29where
30 R: 'static + FunctionRecognizer + Send + Sync + Sized,
31{
32 #[repr(C)]
33 struct FunctionRecognizerHandlerContext<R>
34 where
35 R: 'static + FunctionRecognizer + Send + Sync,
36 {
37 recognizer: R,
38 }
39
40 extern "C" fn cb_recognize_low_level_il<R>(
41 ctxt: *mut c_void,
42 bv: *mut BNBinaryView,
43 func: *mut BNFunction,
44 llil: *mut BNLowLevelILFunction,
45 ) -> bool
46 where
47 R: 'static + FunctionRecognizer + Send + Sync,
48 {
49 let context = unsafe { &*(ctxt as *mut FunctionRecognizerHandlerContext<R>) };
50 let bv = unsafe { BinaryView::from_raw(bv).to_owned() };
51 let func = unsafe { Function::from_raw(func).to_owned() };
52 let llil = unsafe { LowLevelILFunction::from_raw(llil).to_owned() };
53 let _span = ffi_span!("FunctionRecognizer::recognize_low_level_il", bv);
54 context.recognizer.recognize_low_level_il(&bv, &func, &llil)
55 }
56
57 extern "C" fn cb_recognize_medium_level_il<R>(
58 ctxt: *mut c_void,
59 bv: *mut BNBinaryView,
60 func: *mut BNFunction,
61 mlil: *mut BNMediumLevelILFunction,
62 ) -> bool
63 where
64 R: 'static + FunctionRecognizer + Send + Sync,
65 {
66 let context = unsafe { &*(ctxt as *mut FunctionRecognizerHandlerContext<R>) };
67 let bv = unsafe { BinaryView::from_raw(bv).to_owned() };
68 let func = unsafe { Function::from_raw(func).to_owned() };
69 let mlil = unsafe { MediumLevelILFunction::from_raw(mlil).to_owned() };
70 let _span = ffi_span!("FunctionRecognizer::recognize_medium_level_il", bv);
71 context
72 .recognizer
73 .recognize_medium_level_il(&bv, &func, &mlil)
74 }
75
76 let recognizer = FunctionRecognizerHandlerContext { recognizer };
77 let raw = Box::into_raw(Box::new(recognizer));
79 BNFunctionRecognizer {
80 context: raw as *mut _,
81 recognizeLowLevelIL: Some(cb_recognize_low_level_il::<R>),
82 recognizeMediumLevelIL: Some(cb_recognize_medium_level_il::<R>),
83 }
84}
85
86pub fn register_global_function_recognizer<R>(recognizer: R)
87where
88 R: 'static + FunctionRecognizer + Send + Sync + Sized,
89{
90 let mut recognizer = create_function_recognizer_registration::<R>(recognizer);
91 unsafe {
92 BNRegisterGlobalFunctionRecognizer(&mut recognizer);
93 }
94}
95
96pub(crate) fn register_arch_function_recognizer<R>(arch: &CoreArchitecture, recognizer: R)
97where
98 R: 'static + FunctionRecognizer + Send + Sync + Sized,
99{
100 let mut recognizer = create_function_recognizer_registration::<R>(recognizer);
101 unsafe {
102 BNRegisterArchitectureFunctionRecognizer(arch.handle, &mut recognizer);
103 }
104}