macro_rules! plugin_import {
{
$(
#[ $type_meta:meta ]
)*
static $static:ident : $ty:ident = extern $name:literal {
$(
$(
#[$meta:meta]
)*
fn $fn_name:ident
$(
<
$(
$lifetimes:lifetime
),*
$(,)?
>
)?
(
$(
$arg_name:ident : $arg_ty:ty
),*
$(,)?
) $(-> $fn_ret:ty)?;
)*
$(
callbacks {
$(
fn $cb_fn_name:ident(
$(
$cb_arg_name:ident : $cb_arg_ty:ty
),*
$(,)?
) $(-> $cb_fn_ret:ty)?;
)*
}
)?
};
} => { ... };
}Expand description
A macro for importing an external PANDA plugin to use
Note: it is recommended that, if the plugin you want to use already has
panda-rs bindings, they should be used instead. Those are located in the
plugins module, and typically include a note about where
the high-level bindings for the given plugin are located.
§Example Usage
§Declaring bindings for free function in an external plugin:
plugin_import!{
static OSI: Osi = extern "osi" {
fn get_process_handles(cpu: *mut CPUState) -> GBoxedSlice<OsiProcHandle>;
fn get_current_thread(cpu: *mut CPUState) -> GBox<OsiThread>;
fn get_modules(cpu: *mut CPUState) -> GBoxedSlice<OsiModule>;
fn get_mappings(cpu: *mut CPUState, p: *mut OsiProc) -> GBoxedSlice<OsiModule>;
fn get_processes(cpu: *mut CPUState) -> GBoxedSlice<OsiProc>;
fn get_current_process(cpu: *mut CPUState) -> GBox<OsiProc>;
};
}This will create a lazy initialized static variable named OSI in the current
scope. This static will include all of the functions listed as methods, when
any function is run the plugin (the name of which is specified by extern "osi")
will be loaded on the fly before executing the method.
To load a plugin without running any function, plugin_import also automatically
creates an ensure_init method which initializes the plugin without any other
side effects.
§Plugin Callbacks
Plugin-to-Plugin callbacks in PANDA are typically quite verbose to make bindings for
by hand, so the plugin_import macro provides a shorthand for defining a function
prototype for the callback and it will generate all the code needed to add and remove
callbacks for it.
plugin_import! {
static PROC_START_LINUX: ProcStartLinux = extern "proc_start_linux" {
callbacks {
fn on_rec_auxv(cpu: &mut CPUState, tb: &mut TranslationBlock, auxv: &AuxvValues);
}
};
}the above creates another lazy static which has the following methods for working with
the on_rec_auxv callback:
add_callback_on_rec_auxv- add a callback by function pointerremove_callback_on_rec_auxv- remove a callback by function pointer
One requirement of these function pointers is that they must use the C ABI. So the argument for both methods would be of the type:
extern "C" fn (&mut CPUState, &mut TranslationBlock, &AuxvValues)This macro will also generate a trait allowing any plugin-to-plugin callbacks to be
used via the PppCallback API. So the above would generate
a trait called ProcStartLinuxCallbacks which would have a method called on_rec_auxv,
which is automatically implemented for PppCallback.