diff options
Diffstat (limited to 'cleanc.c')
-rw-r--r-- | cleanc.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/cleanc.c b/cleanc.c new file mode 100644 index 0000000..bc73574 --- /dev/null +++ b/cleanc.c @@ -0,0 +1,129 @@ +#include <fcntl.h> +#include <stdio.h> +#include <elf.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include "Clean.h" + +void call_funcname(char*); + +void hello(void) { + printf("Hello world!\n"); +} + +void* parameters[100]; +uint8_t param_ptr = 0; + +void init(void) { + parameters[0] = NULL; + param_ptr = 0; +} + +void puti(long i) { + printf("puti %d %d\n", param_ptr, i); + parameters[param_ptr] = malloc(sizeof(long)); + *((long*)parameters[param_ptr]) = i; + param_ptr++; +} + +char* cleantocstring(CleanString s) { + char* cs = malloc(sizeof(char) * CleanStringLength(s) + 1); + int i; + for (i = 0; i < CleanStringLength(s); i++) + cs[i] = CleanStringCharacters(s)[i]; + cs[i] = 0; + return cs; +} + +void call(CleanString fname) { + char*f = cleantocstring(fname); + call_funcname(f); + param_ptr = 0; + // todo +} + +long geti(void) { + printf("geti %d\n", param_ptr); + return (long)*((long*)parameters[param_ptr++]); +} + +void call_funcname(char* fname) { + // http://stackoverflow.com/a/1118808/1544337 + Elf64_Shdr * shdr; + Elf64_Ehdr * ehdr; + Elf * elf; + Elf_Scn * scn; + Elf_Data * data; + int cnt; + void (*fp)() = NULL; + + int fd = 0; + + /* This is probably Linux specific - Read in our own executable*/ + if ((fd = open("/proc/self/exe", O_RDONLY)) == -1) + exit(1); + + elf_version(EV_CURRENT); + + if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + fprintf(stderr, "file is not an ELF binary\n"); + exit(1); + } + /* Let's get the elf sections */ + if (((ehdr = elf64_getehdr(elf)) == NULL) || + ((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) || + ((data = elf_getdata(scn, NULL)) == NULL)) { + fprintf(stderr, "Failed to get SOMETHING\n"); + exit(1); + } + + /* Let's go through each elf section looking for the symbol table */ + for (cnt = 1, scn = NULL; scn = elf_nextscn(elf, scn); cnt++) { + if ((shdr = elf64_getshdr(scn)) == NULL) + exit(1); + + if (shdr->sh_type == SHT_SYMTAB) { + char *name; + char *strName; + data = 0; + if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0) { + fprintf(stderr, "No data in symbol table\n"); + continue; + } + + Elf64_Sym *esym = (Elf64_Sym*) data->d_buf; + Elf64_Sym *lastsym = (Elf64_Sym*) ((char*) data->d_buf + data->d_size); + + /* Look through all symbols */ + for (; esym < lastsym; esym++) { + if ((esym->st_value == 0) || + (ELF64_ST_BIND(esym->st_info)== STB_WEAK) || + (ELF64_ST_BIND(esym->st_info)== STB_NUM) || + (ELF64_ST_TYPE(esym->st_info)!= STT_FUNC)) + continue; + + name = elf_strptr(elf,shdr->sh_link , (size_t)esym->st_name); + + if(!name){ + fprintf(stderr,"%s\n",elf_errmsg(elf_errno())); + //exit(-1); + } else if(strcmp(fname, name) == 0 ) { + fp = (void(*)(void)) esym->st_value; + } + } + + /* Call and hope we don't segfault!*/ + if (fp != NULL) { + fp(); + return; + } + } + } + + elf_end(elf); + + fprintf(stderr, "done, nothing found\n"); +} + |