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");
}
|