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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
#ifndef __ELFLOADER_PRIVATE_H_
#define __ELFLOADER_PRIVATE_H_
typedef struct library_s library_t;
typedef struct needed_libs_s needed_libs_t;
typedef struct cleanup_s cleanup_t;
#include <elf.h>
#include "elfloader.h"
#include "box32.h"
typedef struct multiblock_s {
void* p;
uintptr_t offs;
uintptr_t paddr;
uintptr_t align;
uint64_t size;
uint64_t asize;
uint8_t flags;
} multiblock_t;
typedef struct elfheader_s {
char* name;
char* path; // Resolved path to file
char* soname; // soname of the elf
uint16_t numPHEntries;
union {
Elf64_Phdr* _64;
Elf32_Phdr* _32;
} PHEntries;
uint16_t numSHEntries;
union {
Elf64_Shdr* _64;
Elf32_Shdr* _32;
} SHEntries;
size_t SHIdx;
size_t numSST;
char* SHStrTab;
char* StrTab;
union {
Elf64_Sym* _64;
Elf32_Sym* _32;
} SymTab;
size_t numSymTab;
char* DynStr;
union {
Elf64_Sym* _64;
Elf32_Sym* _32;
} DynSym;
size_t numDynSym;
union {
Elf64_Dyn* _64;
Elf32_Dyn* _32;
} Dynamic;
size_t numDynamic;
char* DynStrTab;
size_t szDynStrTab;
uint16_t* VerSym;
union {
Elf64_Verneed* _64;
Elf32_Verneed* _32;
} VerNeed;
int szVerNeed;
union {
Elf64_Verdef* _64;
Elf32_Verdef* _32;
} VerDef;
int szVerDef;
int e_type;
uint32_t flags;
uintptr_t hash;
uintptr_t gnu_hash;
intptr_t delta; // should be 0
void* image; // base of the elf image
void* raw; // raw pointer (might be unaligned vs image and max_align of elf)
size_t raw_size;
uintptr_t entrypoint;
uintptr_t initentry;
uintptr_t initarray;
size_t initarray_sz;
uintptr_t finientry;
uintptr_t finiarray;
size_t finiarray_sz;
uintptr_t rel;
size_t relsz;
int relent;
uintptr_t rela;
size_t relasz;
int relaent;
uintptr_t relr;
size_t relrsz;
int relrent;
uintptr_t jmprel;
size_t pltsz;
int pltent;
uint64_t pltrel;
uintptr_t gotplt;
uintptr_t gotplt_end;
uintptr_t pltgot;
uintptr_t got;
uintptr_t got_end;
uintptr_t plt;
uintptr_t plt_end;
uintptr_t text;
size_t textsz;
uintptr_t ehframe;
uintptr_t ehframe_end;
uintptr_t ehframehdr;
uintptr_t paddr;
uintptr_t vaddr;
size_t align;
uint64_t memsz;
uint64_t stacksz;
size_t stackalign;
uintptr_t tlsaddr;
uint64_t tlssize;
uint64_t tlsfilesize;
size_t tlsalign;
int64_t tlsbase; // the base of the tlsdata in the global tlsdata (always negative)
int init_done;
int fini_done;
int refcnt; // ref count for the elf
int malloc_hook_2; // this elf hook malloc, hacking it
int gnuunique; // set if contains some STB_GNU_UNIQUE binding, preventing dlclose to unload the lib
char* memory; // char* and not void* to allow math on memory pointer
multiblock_t* multiblocks;
int multiblock_n;
library_t *lib; // attached lib (exept on main elf)
needed_libs_t* needed;
FILE* file;
int fileno;
cleanup_t *cleanups; // atexit functions
int clean_sz;
int clean_cap;
} elfheader_t;
#define R_X86_64_NONE 0 /* No reloc */
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_COPY 5 /* Copy symbol at runtime */
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
#define R_X86_64_8 14 /* Direct 8 bit sign extended */
#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset to two GOT entries for GD symbol */
#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset to two GOT entries for LD symbol */
#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset to GOT entry for IE symbol */
#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
#define R_X86_64_PC64 24 /* PC relative 64 bit */
#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative offset to GOT */
#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset to GOT entry */
#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset to PLT entry */
#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor. */
#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
/* 39 Reserved was R_X86_64_PC32_BND */
/* 40 Reserved was R_X86_64_PLT32_BND */
#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */
#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */
#define R_X86_64_NUM 43
#ifndef STB_GNU_UNIQUE
#define STB_GNU_UNIQUE 10
#endif
#ifndef ELF32_ST_VISIBILITY
#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
#endif
#ifndef ELF64_ST_VISIBILITY
#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
#endif
elfheader_t* ParseElfHeader32(FILE* f, const char* name, int exec);
elfheader_t* ParseElfHeader64(FILE* f, const char* name, int exec);
const char* BindSym(int bind);
const char* BindSymFriendly(int bind);
uint16_t GetSymbolVersionFlag(elfheader_t* h, int index);
uint32_t old_elf_hash(const char* name);
uint32_t new_elf_hash(const char *name);
Elf32_Sym* ElfLookup32(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
Elf32_Sym* ElfSymTabLookup32(elfheader_t* h, const char* symname);
Elf32_Sym* ElfDynSymLookup32(elfheader_t* h, const char* symname);
Elf64_Sym* ElfLookup64(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
Elf64_Sym* ElfSymTabLookup64(elfheader_t* h, const char* symname);
Elf64_Sym* ElfDynSymLookup64(elfheader_t* h, const char* symname);
#endif //__ELFLOADER_PRIVATE_H_
|