Skip to content

Instantly share code, notes, and snippets.

@saikyun
Last active January 12, 2023 08:54
Show Gist options
  • Save saikyun/c8ccec67a61cf70319409752e97e5f93 to your computer and use it in GitHub Desktop.
Save saikyun/c8ccec67a61cf70319409752e97e5f93 to your computer and use it in GitHub Desktop.
// needs clang
// probably only macos
// usage:
// clang main.c && ./a.out
// try entering `5 * 5`, or `printf("hello\n")`
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_LEN 1024
char *check_error() {
char *err;
err = dlerror();
if (err)
{
printf("dl error! %s\n", err);
}
return err;
}
int main(int argc, char **argv) {
// wat();
char *plugin_name;
void *plugin;
int ( *f1ptr )();
int res = 0;
while (res != -1) {
// char lib[MAX_LEN];
// char func[MAX_LEN];
char *lib;
char *func;
// char line[MAX_LEN];
char *line = malloc(MAX_LEN);
if (line == NULL) {
printf("No memory\n");
return 1;
}
/*
printf("lib: ");
scanf("%s", lib);
printf("func: ");
scanf("%s", func);
*/
lib = "aoeu.dylib";
func = "aoeu";
FILE *fp;
fp = fopen("temp.c", "w+");
printf("c=> ");
fgets(line, MAX_LEN, stdin);
//scanf("%s", line);
fputs("#include <stdio.h>\n", fp);
fputs("int ", fp);
fputs(func, fp);
fputs("() {\n", fp);
fputs("return ", fp);
fputs(line, fp);
fputs(";\n}", fp);
fclose(fp);
free(line);
char * ls_args[7] = { "clang", "-shared", "-fpic", "temp.c", "-o", lib, NULL};
pid_t c_pid, pid;
int status;
c_pid = fork(); //duplicate
if( c_pid == 0 ){
//child
pid = getpid();
//printf("Child: %d, %d: I'm the child\n", pid, c_pid);
//printf("Child: sleeping for 2-seconds, then exiting with status 12\n");
execvp( ls_args[0], ls_args );
} else if (c_pid > 0) {
//parent
//waiting for child to terminate
pid = wait(&status);
if ( WIFEXITED(status) ){
//printf("Parent: Child exited with status: %d\n", WEXITSTATUS(status));
}
}else{
//error: The return of fork() is negative
perror("fork failed");
_exit(2); //exit failure, hard
}
check_error();
plugin = dlopen(lib, RTLD_NOW);
check_error();
if (!plugin)
{
printf("Cannot load %s: %s", plugin_name, dlerror ());
}
f1ptr = dlsym( plugin, func );
check_error();
res = f1ptr();
printf("%d\n", res);
dlclose(plugin);
check_error();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment