Skip to content

Instantly share code, notes, and snippets.

@dutc
Last active September 27, 2023 04:40
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save dutc/991c14bc20ef5a1249c4 to your computer and use it in GitHub Desktop.
Save dutc/991c14bc20ef5a1249c4 to your computer and use it in GitHub Desktop.
function hooking in C
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
void f1(void) {
printf("f1.");
}
void f2(void) {
printf("f2.");
}
int main(void) {
printf("main: f2() -> "); f2(); printf("\n");
printf("main: f1() -> "); f1(); printf("\n");
return 0;
}
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#if !(__x86_64__)
#error "This only works on x86_64"
#endif
extern void f1(void);
extern void f2(void);
__asm__("pop %rax");
void trampoline(void) {
printf("intercepted by trampoline() -> ");
f2();
}
/* TODO: make less ugly!
* there's got to be a nicer way to do this! */
#pragma pack(push, 1)
struct {
char push_rax;
char mov_rax[2];
char addr[8];
char jmp_rax[2]; }
jump_asm = {
.push_rax = 0x50,
.mov_rax = {0x48, 0xb8},
.jmp_rax = {0xff, 0xe0} };
#pragma pack(pop)
void __attribute__ ((constructor)) init(void) {
int pagesize = sysconf(_SC_PAGE_SIZE);
char *page = (char*)f1;
page = (char*)((size_t) page & ~(pagesize - 1));
int rc = mprotect(page, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC);
if(rc) {
fprintf(stderr, "mprotect() failed.\n");
return;
}
void* addr = &trampoline-1;
memcpy(jump_asm.addr, &addr, sizeof (void*));
memcpy((void* )f1, &jump_asm, sizeof jump_asm);
}
.PHONY: hook
CC=gcc -std=c99 -Wall
hook: hook-main hook-preload.so
./hook-main
LD_PRELOAD=./hook-preload.so ./hook-main
hook-main: hook-main.c
${CC} -O0 -Wl,--export-dynamic -g -ggdb -o $@ $^ -ldl
hook-preload.so: hook-preload.c
${CC} -O0 -fPIC -shared -g -ggdb -o $@ $^ -ldl
@dutc
Copy link
Author

dutc commented Oct 24, 2014

Note the effect of the preloaded library:

$ ./smash-main
main: f2() -> f2.
main: f1() -> f1.

$ LD_PRELOAD=./smash-preload.so ./smash-main
main: f2() -> f2.
main: f1() -> trampoline -> f2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment