Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion frida-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ pub use bindings::*;
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))]
pub use crate::{
_frida_g_bytes_new as g_bytes_new, _frida_g_bytes_unref as g_bytes_unref,
_frida_g_clear_object as g_clear_object, _frida_g_signal_connect_data as g_signal_connect_data,
_frida_g_clear_object as g_clear_object, _frida_g_idle_source_new as g_idle_source_new,
_frida_g_signal_connect_data as g_signal_connect_data,
_frida_g_source_attach as g_source_attach,
_frida_g_source_set_callback as g_source_set_callback, _frida_g_source_unref as g_source_unref,
};
37 changes: 37 additions & 0 deletions frida/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,43 @@ impl Frida {
let version = unsafe { CStr::from_ptr(frida_sys::frida_version_string() as _) };
version.to_str().unwrap_or_default()
}

/// Schedules the closure to be executed on the main frida context.
pub fn schedule_on_main<F>(&self, func: F)
where
F: FnOnce() + Send + 'static,
{
unsafe {
unsafe extern "C" fn trampoline<F: FnOnce() + Send + 'static>(
func: frida_sys::gpointer,
) -> frida_sys::gboolean {
let func: &mut Option<F> = &mut *(func as *mut Option<F>);
let func = func
.take()
.expect("schedule_on_main closure called multiple times");
func();
frida_sys::G_SOURCE_REMOVE as frida_sys::gboolean
}
unsafe extern "C" fn destroy_closure<F: FnOnce() + Send + 'static>(
ptr: frida_sys::gpointer,
) {
let _ = Box::<Option<F>>::from_raw(ptr as *mut _);
}

let func = Box::into_raw(Box::new(Some(func)));
let source = frida_sys::g_idle_source_new();
let ctx = frida_sys::frida_get_main_context();

frida_sys::g_source_set_callback(
source,
Some(trampoline::<F>),
func as frida_sys::gpointer,
Some(destroy_closure::<F>),
);
frida_sys::g_source_attach(source, ctx);
frida_sys::g_source_unref(source);
}
}
}

impl Drop for Frida {
Expand Down