Skip to content

Instantly share code, notes, and snippets.

@dvanhorn
Created January 26, 2021 02:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvanhorn/6b1e6f1b7d6ffa005edaee3f3958b913 to your computer and use it in GitHub Desktop.
Save dvanhorn/6b1e6f1b7d6ffa005edaee3f3958b913 to your computer and use it in GitHub Desktop.
mfftw
global frog
global duck
default rel
section .text
extern ptr_to_f
extern f
frog:
sub rsp, 8
lea rax, [rel f wrt ..plt]
call rax
add rsp, 8
ret
duck:
sub rsp, 8
lea rax, [rel ptr_to_f wrt ..got]
mov rax, [rax]
call [rax]
add rsp, 8
ret
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
int main(int argc, char** argv) {
void *handle;
int (*func)();
handle = dlopen("./f.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "Fail to open");
return EXIT_FAILURE;
}
func = dlsym(handle, argv[1]);
if (!func) {
fprintf(stderr, "Error: %s\n", dlerror());
dlclose(handle);
return EXIT_FAILURE;
}
printf("%d\n", func());
return EXIT_SUCCESS;
}
int f() {
return 42;
}
int (*ptr_to_f)() = f;
#include <stdlib.h>
#include <stdio.h>
extern int frog();
extern int duck();
int main(int argc, char** argv) {
printf("%d\n", strcmp(argv[1], "duck") ?
duck() : frog());
return EXIT_SUCCESS;
}

the solution is to be relative to got and add yet another level of indirection. Thanks to Matthew Flatt.

dvanhorn@starburst:small $ nasm -f elf64 call_f.s -o call_f.o
dvanhorn@starburst:small $ gcc static.c f.c call_f.o -o static
dvanhorn@starburst:small $ gcc -ldl dynamic.c -o dynamic
dvanhorn@starburst:small $ gcc -shared f.c call_f.o -o f.so
dvanhorn@starburst:small $ ./static frog
42
dvanhorn@starburst:small $ ./static duck
42
dvanhorn@starburst:small $ ./dynamic frog
42
dvanhorn@starburst:small $ ./dynamic duck
42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment