redhook icon indicating copy to clipboard operation
redhook copied to clipboard

hook the main function

Open milahu opened this issue 4 years ago • 0 comments

this has no effect

hook! {
    unsafe fn main(
        argc: libc::c_int,
        argv: *const *const libc::c_char,
        envp: *const *const libc::c_char
    ) -> libc::c_int => my_main {

        println!("my_main");
        let exit_code = real!(main)(argc, argv, envp);
        return exit_code;
    }
}

this fails to compile. when i remove the hook!, then it compiles, but has no effect

hook! {
    unsafe fn __libc_start_main(
        _main: &dyn Fn(libc::c_int, *const *const libc::c_char, *const *const libc::c_char) -> libc::c_int,
        argc: libc::c_int,
        argv: *const *const libc::c_char,
        init: &dyn Fn(libc::c_int, *const *const libc::c_char, *const *const libc::c_char) -> libc::c_int,
        fini: &dyn Fn() -> libc::c_void,
        rtld_fini: &dyn Fn() -> libc::c_void,
        stack_end: *const libc::c_void
    ) -> libc::c_int => my___libc_start_main {

        println!("my___libc_start_main");
        let exit_code = real!(__libc_start_main)(_main, argc, argv, init, fini, rtld_fini, stack_end);
        return exit_code;
    }
}

error[E0277]: the type `dyn Fn(i32, *const *const i8, *const *const i8) -> i32` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary

error[E0277]: the type `dyn Fn() -> c_void` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary

a working example in C code

taken from abba23/spotify-adblock-linux

typedef int (*main_t)(int, char **, char **);
static main_t real_main;

int wrap_main(int argc, char **argv, char **envp) {
    printf("wrap_main\n");
    int main_res = real_main(argc, argv, envp);
    return main_res;
}

// wrap __libc_start_main: replace real_main with wrap_main
int __libc_start_main(
    main_t main, int argc, char **argv,
    main_t init,
    void (*fini)(void), void (*rtld_fini)(void), void *stack_end
) {
    static int (*real___libc_start_main)() = NULL;
    if (!real___libc_start_main) {
        printf("real___libc_start_main = %p (empty)\n", real___libc_start_main);
        char *error;
        real___libc_start_main = dlsym(RTLD_NEXT, "__libc_start_main");
        printf("real___libc_start_main = %p\n", real___libc_start_main);
        if ((error = dlerror()) != NULL) {
            printf("%s\n", error);
            exit(1);
        }
    }
    real_main = main;
    return real___libc_start_main(wrap_main, argc, argv, init, fini, rtld_fini, stack_end);
}

milahu avatar Sep 29 '21 06:09 milahu