aboutsummaryrefslogtreecommitdiff
path: root/cleanc.c
blob: bc735744e580aabed7e274ff61b6a949bf346fd0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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");
}