Skip to content

Instantly share code, notes, and snippets.

@yurial
Forked from apsun/hax.c
Created June 24, 2020 15:20
Show Gist options
  • Save yurial/4bf2c8142883b2ab938a69f805212d3e to your computer and use it in GitHub Desktop.
Save yurial/4bf2c8142883b2ab938a69f805212d3e to your computer and use it in GitHub Desktop.

Revisions

  1. @apsun apsun revised this gist Jul 9, 2017. No changes.
  2. @apsun apsun created this gist Jul 4, 2017.
    50 changes: 50 additions & 0 deletions hax.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    /*
    * Hook main() using LD_PRELOAD, because why not?
    * Obviously, this code is not portable. Use at your own risk.
    *
    * Compile using 'gcc hax.c -o hax.so -fPIC -shared -ldl'
    * Then run your program as 'LD_PRELOAD=$PWD/hax.so ./a.out'
    */

    #define _GNU_SOURCE
    #include <stdio.h>
    #include <dlfcn.h>

    /* Trampoline for the real main() */
    static int (*main_orig)(int, char **, char **);

    /* Our fake main() that gets called by __libc_start_main() */
    int main_hook(int argc, char **argv, char **envp)
    {
    for (int i = 0; i < argc; ++i) {
    printf("argv[%d] = %s\n", i, argv[i]);
    }
    printf("--- Before main ---\n");
    int ret = main_orig(argc, argv, envp);
    printf("--- After main ----\n");
    printf("main() returned %d\n", ret);
    return ret;
    }

    /*
    * Wrapper for __libc_start_main() that replaces the real main
    * function with our hooked version.
    */
    int __libc_start_main(
    int (*main)(int, char **, char **),
    int argc,
    char **argv,
    int (*init)(int, char **, char **),
    void (*fini)(void),
    void (*rtld_fini)(void),
    void *stack_end)
    {
    /* Save the real main function address */
    main_orig = main;

    /* Find the real __libc_start_main()... */
    typeof(&__libc_start_main) orig = dlsym(RTLD_NEXT, "__libc_start_main");

    /* ... and call it with our custom main function */
    return orig(main_hook, argc, argv, init, fini, rtld_fini, stack_end);
    }