Skip to content

Instantly share code, notes, and snippets.

@dvanhorn
Created January 26, 2021 01:59
Show Gist options
  • Save dvanhorn/e105cdec5a33e85159bf18ddc6ed6e5b to your computer and use it in GitHub Desktop.
Save dvanhorn/e105cdec5a33e85159bf18ddc6ed6e5b to your computer and use it in GitHub Desktop.
fml
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 ..plt]
call [rel 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;
}

OK, so the assembly code, when statically linked into a executable works both with the call to f and the indirect call through ptr_to_f.

When dynamically loaded, the call to f works, but the call through ptr_to_f seg faults.

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
Segmentation fault
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment