1
+ #include <graphics.h>
1
2
#include <memory2.h>
2
3
#include <fdlfcn.h>
3
4
#include <stdint.h>
4
5
#include <stddef.h>
5
6
#include <heap.h>
6
7
#include <elf.h>
7
8
8
- #define READ_FROM_MEMORY (dest , base , offset , size ) memcpy(dest, (void*)( (uint8_t* )base + offset ), size)
9
+ #define READ_FROM_MEMORY (dest , base , offset , size ) printf("reading at address 0x%x", (uint64_t)base + (uint64_t)offset); memcpy(dest, (void*)( (uint64_t )base + (uint64_t) offset ), size)
9
10
10
11
void * fdl_load_section (void * filedata , Elf64_Shdr * section_header )
11
12
{
12
13
void * section_data = malloc (section_header -> sh_size );
13
- if (section_data == NULL ) {
14
- error ("fdlopen: malloc failed for section" );
14
+ if (section_data == NULL )
15
+ {
16
+ error ("fdlopen: malloc failed for section" , __FILE__ );
15
17
return NULL ;
16
18
}
17
19
@@ -22,94 +24,111 @@ void* fdl_load_section(void* filedata, Elf64_Shdr* section_header)
22
24
23
25
int fdl_apply_relocations (fdlfcn_handle * lib , int reloc_section_index )
24
26
{
27
+ if (lib == NULL || reloc_section_index == -1 )
28
+ return 1 ;
29
+
25
30
Elf64_Ehdr * elf_header = & lib -> ehdr ;
26
31
Elf64_Shdr * section_headers = lib -> shdrs ;
27
32
Elf64_Sym * symbols = lib -> symbols ;
28
33
Elf64_Rela * relocations = lib -> relocations ;
29
34
30
- // Get number of relocations
31
35
int num_relocations = section_headers [reloc_section_index ].sh_size / sizeof (Elf64_Rela );
32
36
33
- for (int i = 0 ; i < num_relocations ; i ++ ) {
37
+ for (int i = 0 ; i < num_relocations ; i ++ )
38
+ {
34
39
Elf64_Rela * reloc = & relocations [i ];
35
40
36
- // Get symbol index
37
41
int sym_index = ELF64_R_SYM (reloc -> r_info );
38
42
Elf64_Sym * sym = & symbols [sym_index ];
39
43
40
- // Get relocation type
41
44
int reloc_type = ELF64_R_TYPE (reloc -> r_info );
42
-
43
- // Get target address
44
45
uintptr_t target_addr = 0 ;
45
46
46
- // Determine target address based on relocation type
47
- switch (reloc_type ) {
48
- case R_X86_64_64 :
49
- target_addr = (uintptr_t )sym -> st_value ;
50
- break ;
51
- case R_X86_64_PC32 :
52
- target_addr = (uintptr_t )sym -> st_value - (uintptr_t )(lib -> address + reloc -> r_offset + 4 );
53
- break ;
54
- case R_X86_64_PLT32 :
55
- // Simplified handling - Adjust based on actual PLT implementation
56
- target_addr = (uintptr_t )sym -> st_value ;
57
- break ;
58
- case R_X86_64_GOTPCREL :
59
- // Simplified handling - Adjust based on actual GOT implementation
60
- target_addr = (uintptr_t )sym -> st_value ;
61
- break ;
62
- default :
63
- error ("fdlopen: Unsupported relocation type: %d" , reloc_type );
64
- return -1 ;
47
+ if (reloc_type == R_X86_64_64 )
48
+ target_addr = (uintptr_t )sym -> st_value ;
49
+ else if (reloc_type == R_X86_64_PC32 )
50
+ target_addr = (uintptr_t )sym -> st_value - (uintptr_t )(lib -> address + reloc -> r_offset + 4 );
51
+ else if (reloc_type == R_X86_64_PLT32 )
52
+ target_addr = (uintptr_t )sym -> st_value ;
53
+ else if (reloc_type == R_X86_64_GOTPCREL )
54
+ target_addr = (uintptr_t )sym -> st_value ;
55
+ else
56
+ {
57
+ printf ("fdlopen: Unsupported relocation type: %d: %s" , reloc_type , __FILE__ );
58
+ return -1 ;
65
59
}
66
60
67
- // Apply relocation
68
61
uintptr_t * ptr = (uintptr_t * )(lib -> address + reloc -> r_offset );
69
62
* ptr += target_addr + reloc -> r_addend ;
70
63
}
71
64
72
- return 0 ; // Relocation successful
65
+ return 0 ;
73
66
}
74
67
75
68
void * fdlsym (fdlfcn_handle * handle , const char * symbol_name )
76
69
{
77
- for (int i = 0 ; i < handle -> ehdr .e_shnum ; i ++ ) {
78
- if (strcmp (handle -> shdrs [i ].sh_name , ".symtab" ) == 0 ) {
79
- Elf64_Shdr symtab_section = handle -> shdrs [i ];
80
- Elf64_Sym * symbols = handle -> symbols ;
81
-
82
- for (int j = 0 ; j < symtab_section .sh_size / sizeof (Elf64_Sym ); j ++ ) {
83
- char * symbol_name_str = (char * )((Elf64_Shdr * )((char * )handle -> shdrs + handle -> ehdr .e_shstrndx ))-> sh_addr + symbols [j ].st_name ;
84
- if (strcmp (symbol_name_str , symbol_name ) == 0 ) {
85
- // Handle symbol versioning (if needed)
86
- // ...
87
-
88
- // Calculate symbol address
89
- uintptr_t symbol_address = (uintptr_t )handle -> address + symbols [j ].st_value ;
90
- return (void * )symbol_address ;
91
- }
92
- }
70
+ if (handle == NULL )
71
+ return NULL ;
72
+
73
+ Elf64_Sym * symbols = handle -> symbols ;
74
+
75
+ int symtab_index = -1 ;
76
+ for (int i = 0 ; i < handle -> ehdr .e_shnum ; i ++ )
77
+ {
78
+ if (handle -> shdrs [i ].sh_type == SHT_SYMTAB )
79
+ {
80
+ symtab_index = i ;
93
81
break ;
94
82
}
95
83
}
96
84
97
- error ("fdlsym: Symbol '%s' not found" , symbol_name );
85
+ if (symtab_index == -1 )
86
+ {
87
+ printf ("Symbol '%s' not found" , symbol_name );
88
+ return NULL ;
89
+ }
90
+
91
+ Elf64_Shdr symtab_section = handle -> shdrs [symtab_index ];
92
+
93
+ for (int j = 0 ; j < symtab_section .sh_size / sizeof (Elf64_Sym ); j ++ )
94
+ {
95
+ char * symbol_name_str = (char * )((uint64_t )handle -> symtab_str_section_data + symbols [j ].st_name );
96
+ if (strcmp (symbol_name_str , symbol_name ) == 0 && ELF64_ST_BIND (symbols [j ].st_info ) != STB_LOCAL )
97
+ {
98
+ uintptr_t symbol_address = (uintptr_t )handle -> text_section_data + symbols [j ].st_value ;
99
+ printf ("Found symbol '%s'" , symbol_name );
100
+ return (void * )symbol_address ;
101
+ }
102
+ }
103
+
104
+ printf ("fdlsym: Symbol '%s' not found" , symbol_name );
98
105
return NULL ;
99
106
}
100
107
101
108
int fdlclose (fdlfcn_handle * handle )
102
109
{
103
- if (handle -> text_section_data )
110
+ if (handle == NULL )
111
+ return 1 ;
112
+
113
+ return 0 ; /// TODO: somehow all the free calls cause a gp fault, fix that
114
+
115
+ if (handle -> text_section_data != NULL )
104
116
free (handle -> text_section_data );
105
- if (handle -> data_section_data )
117
+ if (handle -> data_section_data != NULL )
106
118
free (handle -> data_section_data );
107
- if (handle -> rodata_section_data )
119
+ if (handle -> rodata_section_data != NULL )
108
120
free (handle -> rodata_section_data );
121
+ if (handle -> string_table_data != NULL )
122
+ free (handle -> string_table_data );
123
+ if (handle -> symtab_str_section_data != NULL )
124
+ free (handle -> symtab_str_section_data );
125
+ if (handle -> shdrs != NULL )
126
+ free (handle -> shdrs );
127
+ if (handle -> symbols != NULL )
128
+ free (handle -> symbols );
129
+ if (handle -> relocations != NULL )
130
+ free (handle -> relocations );
109
131
110
- free (handle -> shdrs );
111
- free (handle -> symbols );
112
- free (handle -> relocations );
113
132
free (handle );
114
133
115
134
return 0 ;
@@ -123,30 +142,41 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
123
142
fdlfcn_handle * handle = malloc (sizeof (fdlfcn_handle ));
124
143
if (handle == NULL )
125
144
{
126
- error ("Could not allocate memory for shared object file handle" );
145
+ error ("Could not allocate memory for shared object file handle" , __FILE__ );
127
146
return NULL ;
128
147
}
129
148
memset (handle , 0 , sizeof (fdlfcn_handle ));
130
149
131
- // Read ELF header
132
150
Elf64_Ehdr elf_header ;
133
151
memcpy (& elf_header , filedata , sizeof (Elf64_Ehdr ));
134
152
135
- // Read section headers
153
+ if (memcmp (& elf_header .e_ident [EI_MAG0 ], ELFMAG , SELFMAG ) != 0 || elf_header .e_ident [EI_CLASS ] != ELFCLASS64 || elf_header .e_type != ET_DYN ||
154
+ elf_header .e_machine != EM_X86_64 || elf_header .e_version != EV_CURRENT )
155
+ {
156
+ error ("Not a valid .so file" , __FILE__ );
157
+ free (handle );
158
+ return NULL ;
159
+ }
160
+
136
161
Elf64_Shdr * section_headers = malloc (elf_header .e_shnum * sizeof (Elf64_Shdr ));
162
+ if (section_headers == NULL )
163
+ {
164
+ free (handle );
165
+ return NULL ;
166
+ }
137
167
READ_FROM_MEMORY (section_headers , filedata , elf_header .e_shoff , elf_header .e_shnum * sizeof (Elf64_Shdr ));
138
168
139
- // Find important section indices
140
169
int strtab_index = elf_header .e_shstrndx ;
141
170
int symtab_index = -1 ;
142
171
int text_section_index = -1 ;
143
172
int data_section_index = -1 ;
144
173
int rodata_section_index = -1 ;
145
174
int reloc_section_index = -1 ;
146
175
176
+ void * strtableAddr = fdl_load_section (filedata , & section_headers [strtab_index ]);
147
177
for (int i = 0 ; i < elf_header .e_shnum ; i ++ )
148
178
{
149
- char * section_name = (char * )(( Elf64_Shdr * )(( char * ) section_headers + strtab_index )) -> sh_addr + section_headers [i ].sh_name ;
179
+ char * section_name = (char * )strtableAddr + section_headers [i ].sh_name ;
150
180
if (strcmp (section_name , ".text" ) == 0 )
151
181
text_section_index = i ;
152
182
else if (strcmp (section_name , ".data" ) == 0 )
@@ -161,10 +191,10 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
161
191
reloc_section_index = i ;
162
192
}
163
193
164
- // Load sections into memory
165
194
void * text_section_data = NULL ;
166
195
void * data_section_data = NULL ;
167
196
void * rodata_section_data = NULL ;
197
+ void * symtab_str_section_data = NULL ;
168
198
169
199
if (text_section_index != -1 )
170
200
{
@@ -204,37 +234,52 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
204
234
}
205
235
}
206
236
207
- // Read symbol table
208
237
if (symtab_index != -1 )
209
238
{
210
239
Elf64_Shdr symtab_section = section_headers [symtab_index ];
211
240
handle -> symbols = malloc (symtab_section .sh_size );
212
241
READ_FROM_MEMORY (handle -> symbols , filedata , symtab_section .sh_offset , symtab_section .sh_size );
213
- } else {
214
- handle -> symbols = NULL ;
242
+ symtab_str_section_data = fdl_load_section (filedata , & section_headers [symtab_section .sh_link ]);
215
243
}
244
+ else
245
+ handle -> symbols = NULL ;
216
246
217
- // Read relocation entries
218
- if ( reloc_section_index != -1 ) {
247
+ if ( reloc_section_index != -1 )
248
+ {
219
249
Elf64_Shdr reloc_section = section_headers [reloc_section_index ];
220
250
handle -> relocations = malloc (reloc_section .sh_size );
221
251
READ_FROM_MEMORY (handle -> relocations , filedata , reloc_section .sh_offset , reloc_section .sh_size );
222
- } else {
223
- handle -> relocations = NULL ;
224
252
}
253
+ else
254
+ handle -> relocations = NULL ;
225
255
226
- handle -> address = (void * )section_headers [text_section_index ].sh_addr ;
256
+ handle -> address = text_section_data ;
257
+ handle -> text_section_data = text_section_data ;
258
+ handle -> symtab_str_section_data = symtab_str_section_data ;
259
+ handle -> text_section_header = & section_headers [text_section_index ];
260
+ handle -> data_section_data = data_section_data ;
261
+ handle -> data_section_header = & section_headers [data_section_index ];
262
+ handle -> rodata_section_data = rodata_section_data ;
263
+ handle -> rodata_section_header = & section_headers [rodata_section_index ];
264
+ handle -> string_table_data = strtableAddr ;
265
+ handle -> ehdr = elf_header ;
266
+ handle -> shdrs = section_headers ;
267
+ handle -> symtab_index = symtab_index ;
227
268
228
- if (fdl_apply_relocations (handle , reloc_section_index ) != 0 )
269
+ if (fdl_apply_relocations (handle , reloc_section_index ) != 0 && reloc_section_index != -1 )
229
270
{
230
- error ("fdlopen: Relocation failed" );
271
+ error ("fdlopen: Relocation failed" , __FILE__ );
231
272
232
273
if (text_section_data )
233
274
free (text_section_data );
234
275
if (data_section_data )
235
276
free (data_section_data );
236
277
if (rodata_section_data )
237
278
free (rodata_section_data );
279
+ if (strtableAddr )
280
+ free (strtableAddr );
281
+ if (symtab_str_section_data )
282
+ free (symtab_str_section_data );
238
283
239
284
free (section_headers );
240
285
free (handle -> symbols );
@@ -243,16 +288,7 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
243
288
return NULL ;
244
289
}
245
290
246
- handle -> text_section_data = text_section_data ;
247
- handle -> text_section_header = & section_headers [text_section_index ];
248
- handle -> data_section_data = data_section_data ;
249
- handle -> data_section_header = & section_headers [data_section_index ];
250
- handle -> rodata_section_data = rodata_section_data ;
251
- handle -> rodata_section_header = & section_headers [rodata_section_index ];
252
-
253
- handle -> ehdr = elf_header ;
254
- handle -> shdrs = section_headers ;
255
- handle -> symtab_index = symtab_index ; // Store symtab index for later use
291
+ info ("fdlopen: Successfully loaded .so file" , __FILE__ );
256
292
257
293
return handle ;
258
294
}
0 commit comments