-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelf_load_symbol.c
More file actions
84 lines (71 loc) · 2.38 KB
/
elf_load_symbol.c
File metadata and controls
84 lines (71 loc) · 2.38 KB
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
#include "elf_load_symbol.h"
#include "elf_symbol.h"
#include "elf_io.h"
#include <stdio.h>
Elf32_Sym correct_symbol_section(Elf32_Sym sym, Elf32_Half correl_table[]){
switch(sym.st_shndx){
case SHN_ABS:
case SHN_UNDEF:
case SHN_COMMON:
break;
default:
sym.st_shndx = correl_table[sym.st_shndx];
break;
}
return sym;
}
Elf32_Sym correct_symbol_value(Elf32_Sym sym, Elf32_Shdr section_table[], Elf32_Half sh_count){
if (sym.st_shndx==SHN_ABS){
return sym;
}
if (sym.st_shndx==SHN_COMMON){
return (Elf32_Sym) {.st_shndx=sym.st_shndx+1};
}
if (sym.st_shndx >= sh_count || sym.st_shndx == SHN_UNDEF){
return (Elf32_Sym) {.st_shndx=sym.st_shndx+1};
}
if (ELF32_ST_TYPE(sym.st_info) == STT_NOTYPE || ELF32_ST_TYPE(sym.st_info) == STT_SECTION)
sym.st_value += section_table[sym.st_shndx].sh_addr;
return sym;
}
void write_symbol(unsigned char *addr, Elf32_Sym symbol){
write_32bits(addr, &symbol.st_name);
addr += sizeof(symbol.st_name);
write_32bits(addr, &symbol.st_value);
addr += sizeof(symbol.st_value);
write_32bits(addr, &symbol.st_size);
addr += sizeof(symbol.st_size);
write_8bits(addr, &symbol.st_info);
addr += sizeof(symbol.st_info);
write_8bits(addr, &symbol.st_other);
addr += sizeof(symbol.st_other);
write_16bits(addr, &symbol.st_shndx);
}
void correct_all_symbol(Elf32_File* ef, Elf32_Half sh_num, Elf32_Half correl_table[], Elf32_Half correl_symbol[]){
unsigned char *symbol_addr = ef->section_content[sh_num];
Elf32_Sym temp;
const unsigned int num_symbols =
ef->section_table[sh_num].sh_size / sizeof(Elf32_Sym);
Elf32_Word nb_symbol = 1;
Elf32_Sym sym_table[num_symbols];
read_elf_symbol_table(symbol_addr, &ef->section_table[sh_num], sym_table);
//Let the undef symbol
symbol_addr += sizeof(Elf32_Sym);
correl_symbol[0] = 0;
//Modify other symbols
for(Elf32_Half i = 1; i < num_symbols; i++){
sym_table[i] = correct_symbol_section(sym_table[i],correl_table);
temp = correct_symbol_value(sym_table[i],ef->section_table,ef->header.e_shnum);
if (temp.st_shndx != sym_table[i].st_shndx){
continue;
}
else{
sym_table[i] = temp;
write_symbol(symbol_addr, sym_table[i]);
symbol_addr += sizeof(Elf32_Sym);
correl_symbol[i] = nb_symbol;
nb_symbol++;
}
}
ef->section_table[sh_num].sh_size = nb_symbol*sizeof(Elf32_Sym);
}