Although this is not quite a practical solution, I bet you could, of course, call the function line by line if the program read its own executable file in it and analyzed the symbol table. The symbol table must contain the name of the function, as well as the address of the first instruction. Then you can put this address in the function pointer variable and call it.
I think I can try to hack this.
EDIT: Please, no one ever wrote real code like this, but here is how you can call a function using the line for Linux ELF binary file with a table of intact characters (requires libelf):
#include <fcntl.h> #include <stdio.h> #include <elf.h> #include <libelf.h> #include <stdlib.h> #include <string.h> void callMe() { printf("callMe called\n"); } int main(int argc, char **argv) { 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 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 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"); exit(1); } 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,"%sn",elf_errmsg(elf_errno())); exit(-1); } /* This could obviously be a generic string */ if(strcmp("callMe", name) == 0 ) { printf("Found callMe @ %x\n", esym->st_value); fp = esym->st_value; } } /* Call and hope we don't segfault!*/ fp(); elf_end(elf); return 0; }
Falaina Jul 13 '09 at 10:53 2009-07-13 10:53
source share