frida/frida-rust

frida_sys::g_signal_connect_object

Leoid opened this issue · 2 comments

Leoid commented

Hi,

Is there a way to read the GCallback output from g_signal_connect_object? for example the c_hanlder member in the mentioned function allows me only to declare an unsafe "callback_on_message" function that doesn't take arguments?

frida_sys::g_signal_connect_object(
                        frida_script as *mut c_void,
                        message_string.as_ptr(),
                        callback_on_message,
                        data,
                        connect_flags,
        
                    ); 

I got the error message:

    |
137 |                     let callback_on_message: frida_sys::GCallback = Some(on_message);
    |                                                                          ^^^^^^^^^^ incorrect number of function parameters
    |
    = note: expected fn pointer `unsafe extern "C" fn()`
                  found fn item `unsafe extern "C" fn(String) {on_message}`
    |
161 |                         Some(fnptr),
    |                              ^^^^^ incorrect number of function parameters
    |
    = note: expected fn pointer `unsafe extern "C" fn()`
               found fn pointer `unsafe extern "C" fn(String)`

Thanks in advance,
b1twis3

meme commented

The GObject Reference explains what is happening here, https://developer.gnome.org/gobject/stable/gobject-Closures.html#GCallback. The parameter is a GCallback which is an unsafe extern "C" fn() and must be casted with G_CALLBACK. This doesn't exist in Rust, so instead you need to transmute your function pointer to the target one, for example:

let callback_on_message: frida_sys::GCallback = Some(unsafe { std::mem::transmute(on_message) });

Also, a note: using String is probably not what you want. Instead, you'll be dealing with raw function pointers so likely you're looking for const *c_char as your parameter name instead. Not sure what the context of this call is, but passing String over FFI is not going to work.

Leoid commented

Great! Thanks, @meme!
I'll follow that guidance. Yeah, the String datatype was just an example. I guess the g_signal_connect_closure has a better option since its marshal member takes:
Option<unsafe extern "C" fn(closure: *mut GClosure, return_value: *mut GValue, n_param_values: guint, param_values: *const GValue, invocation_hint: gpointer, marshal_data: gpointer)>
Thanks again.