frida-rust icon indicating copy to clipboard operation
frida-rust copied to clipboard

Stalker has wrong behavior on follow

Open qrzbing opened this issue 10 months ago • 7 comments

I just try to study stalker example code in https://github.com/frida/frida-rust/blob/91028136615342bf84c8f05f6c246fb11064832a/examples/gum/stalker/src/main.rs#L45-L47

I want to trace a C function so I add some code between follow and unfollow, you can see this repo.

In short, the C function is

void process_input(const char *input, char *output) {
    snprintf(output, BUFFER_SIZE, "Echo: %s", input);
}

and the rust code is

    let input = CString::new("test").expect("CString::new failed");
    let mut output_buffer = vec![0u8; 1024];
    let output_ptr = output_buffer.as_mut_ptr() as *mut libc::c_char;

    stalker.follow_me(&transformer, Some(&mut event_sink));

    unsafe {
        process_input(input.as_ptr(), output_ptr);
    }

    stalker.unfollow_me();

    let output_cstr = unsafe { CStr::from_ptr(output_ptr) };
    let output_str = output_cstr.to_str().expect("Invalid UTF-8 string");
    println!("Output from process_input: {}", output_str);

I think it should output Output from process_input: Echo test, but actually it outputs Output from process_input: Echo: %s.

Since frida is context sensitive, do I need to be careful about calling follow and unfollow? Am I missing any calls?

qrzbing avatar Mar 11 '25 15:03 qrzbing

Does process_input function correctly if you don't do the follow_me?

s1341 avatar Mar 12 '25 06:03 s1341

Does process_input function correctly if you don't do the follow_me?

Yes, if I comment out stalker.follow_me and stalker.unfollow_me, it works correctly, here are two outputs:

If I try to follow_me:

$ cargo run                    
... ...
start
stop
Output from process_input: Echo: %s  # This is incorrect

If I comment out follow_me:

$ cargo run
... ...
Output from process_input: Echo: test # This is correct

qrzbing avatar Mar 12 '25 06:03 qrzbing

By the way I try to reimplement it in C:

// Transformer callback
static void transform_block(GumStalkerIterator *iterator,
                            GumStalkerOutput *output,
                            gpointer user_data)
{
    cs_insn *insn;
    while (gum_stalker_iterator_next(iterator, &insn))
    {

        gum_stalker_iterator_keep(iterator);
    }
}

static void on_process_input(const char *input, char *output)
{
    printf("Input intercepted: %s\n", input);

    GumStalkerTransformer *transformer = gum_stalker_transformer_make_from_callback(transform_block, NULL, NULL);

    // Follow current thread before calling original
    gum_stalker_follow_me(stalker, transformer, NULL);

    // Call original
    if (process_input != NULL)
    {
        process_input(input, output);
    }

    // Unfollow after original returns
    gum_stalker_unfollow_me(stalker);

    printf("Output: %s\n", output);
}

and this code works fine.

I compare these two codes, and remove event-sink feature in rust code, but still do not work.

qrzbing avatar Mar 12 '25 07:03 qrzbing

If you remove the put_callout in your transformer, does it work?

s1341 avatar Mar 12 '25 07:03 s1341

If you remove the put_callout in your transformer, does it work?

Of course I tried, but nothing changed. I also have changed different version of frida, but still not work.

qrzbing avatar Mar 12 '25 07:03 qrzbing

I just cloned your project, added auto-download to the frida-gum features and did cargo run, and I got the correct output.

Can you try with auto-download?

s1341 avatar Mar 12 '25 07:03 s1341

I just cloned your project, added auto-download to the frida-gum features and did cargo run, and I got the correct output.

Can you try with auto-download?

Hmmm, I do same thing like you, but still output incorrect. What I do is:

git clone [email protected]:qrzbing/frida-rust-stalker-debug.git
code frida-rust-stalker-debug

# Add `auto-download` to frida-gum features
cargo run

And then output:

$ cargo run
... ...
   Compiling frida-build v0.16.7
   Compiling frida-gum-sys v0.16.7
   Compiling frida-gum v0.16.7
   Compiling stalker v0.1.0 (/home/qrzbing/tests/frida-rust-stalker-debug)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 03s
     Running `target/debug/stalker`
start
stop
Output from process_input: Echo: %s

After this I do same thing with cargo run --release, but still not work.

I can't figure it out, it's so weird. My platform is Debian 12 in WSL2, with Rust version 1.85.0, clang version 19.1.7.


Update:

I run the code on Windows 11 24H2 with rustc 1.84.0, clang version 18.1.8, it works fine. I will try to run code on more platform to test what matter cause this problem.

qrzbing avatar Mar 12 '25 07:03 qrzbing

Can this be closed?

s1341 avatar Jul 22 '25 04:07 s1341

Oh, since I haven't replay it on more platform recently, i think it can be closed.

qrzbing avatar Jul 24 '25 08:07 qrzbing