1 /* radare - LGPL - Copyright 2008-2020 - nibble, pancake, alvaro_fe */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <r_types.h>
8 #include <r_util.h>
9 #include "elf.h"
10
11 #define MIPS_PLT_OFFSET 0x20
12 #define RISCV_PLT_OFFSET 0x20
13
14 #define RISCV_PLT_ENTRY_SIZE 0x10
15 #define X86_PLT_ENTRY_SIZE 0x10
16
17 #define SPARC_OFFSET_PLT_ENTRY_FROM_GOT_ADDR -0x6
18 #define X86_OFFSET_PLT_ENTRY_FROM_GOT_ADDR -0x6
19
20 #define ELF_PAGE_MASK 0xFFFFFFFFFFFFF000LL
21 #define ELF_PAGE_SIZE 12
22
23 #define R_ELF_NO_RELRO 0
24 #define R_ELF_PART_RELRO 1
25 #define R_ELF_FULL_RELRO 2
26
27 #define bprintf if(bin->verbose) R_LOG_WARN
28
29 #define MAX_REL_RELA_SZ (sizeof (Elf_(Rel)) > sizeof (Elf_(Rela))? sizeof (Elf_(Rel)): sizeof (Elf_(Rela)))
30
31 #define READ8(x, i) r_read_ble8((x) + (i)); (i) += 1
32 #define READ16(x, i) r_read_ble16((x) + (i), bin->endian); (i) += 2
33 #define READ32(x, i) r_read_ble32((x) + (i), bin->endian); (i) += 4
34 #define READ64(x, i) r_read_ble64((x) + (i), bin->endian); (i) += 8
35
36 #define BREAD8(x, i) r_buf_read_ble8_at (x, i); (i) += 1
37 #define BREAD16(x, i) r_buf_read_ble16_at (x, i, bin->endian); (i) += 2
38 #define BREAD32(x, i) r_buf_read_ble32_at (x, i, bin->endian); (i) += 4
39 #define BREAD64(x, i) r_buf_read_ble64_at (x, i, bin->endian); (i) += 8
40
41 #define NUMENTRIES_ROUNDUP(sectionsize, entrysize) (((sectionsize) + (entrysize)-1) / (entrysize))
42 #define COMPUTE_PLTGOT_POSITION(rel, pltgot_addr, n_initial_unused_entries) \
43 ((rel->rva - pltgot_addr - n_initial_unused_entries * R_BIN_ELF_WORDSIZE) / R_BIN_ELF_WORDSIZE)
44
45 #define GROWTH_FACTOR (1.5)
46
47 #define round_up(a) ((((a) + (4) - (1)) / (4)) * (4))
48
49 #define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
50 #define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */
51 #define EF_MIPS_ABI 0x0000f000
52
is_elfclass64(Elf_ (Ehdr)* h)53 static inline bool is_elfclass64(Elf_(Ehdr) *h) {
54 return h->e_ident[EI_CLASS] == ELFCLASS64;
55 }
56
is_mips_o32(Elf_ (Ehdr)* h)57 static bool is_mips_o32(Elf_(Ehdr) *h) {
58 if (h->e_ident[EI_CLASS] != ELFCLASS32) {
59 return false;
60 }
61 if ((h->e_flags & EF_MIPS_ABI2) != 0) {
62 return false;
63 }
64 if (((h->e_flags & EF_MIPS_ABI) != 0) &&
65 ((h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) {
66 return false;
67 }
68 return true;
69 }
70
is_mips_n32(Elf_ (Ehdr)* h)71 static bool is_mips_n32(Elf_(Ehdr) *h) {
72 if (h->e_ident[EI_CLASS] != ELFCLASS32) {
73 return false;
74 }
75 if (((h->e_flags & EF_MIPS_ABI2) == 0) ||
76 ((h->e_flags & EF_MIPS_ABI) != 0)) {
77 return false;
78 }
79 return true;
80 }
81
82 enum {
83 X86,
84 X86_64,
85 ARM,
86 AARCH64,
87 RCE,
88 ARCH_LEN
89 };
90
91 typedef struct reginfo {
92 ut32 regsize;
93 ut32 regdelta;
94 } reginfo_t;
95
96 static reginfo_t reginf[ARCH_LEN] = {
97 { 160, 0x5c },
98 { 216, 0x84 },
99 { 72, 0x5c },
100 { 272, 0x84 },
101 { 272, 0x84 }
102 };
103
__strnlen(const char * str,int len)104 static inline int __strnlen(const char *str, int len) {
105 int l = 0;
106 while (IS_PRINTABLE (*str) && --len) {
107 if (((ut8)*str) == 0xff) {
108 break;
109 }
110 str++;
111 l++;
112 }
113 return l + 1;
114 }
115
is_bin_etrel(ELFOBJ * bin)116 static bool is_bin_etrel(ELFOBJ *bin) {
117 return bin->ehdr.e_type == ET_REL;
118 }
119
__is_valid_ident(ELFOBJ * bin)120 static bool __is_valid_ident(ELFOBJ *bin) {
121 return !strncmp ((char *)bin->ehdr.e_ident, ELFMAG, SELFMAG) ||
122 !strncmp ((char *)bin->ehdr.e_ident, CGCMAG, SCGCMAG);
123 }
124
init_ehdr(ELFOBJ * bin)125 static bool init_ehdr(ELFOBJ *bin) {
126 ut8 e_ident[EI_NIDENT];
127 ut8 ehdr[sizeof (Elf_(Ehdr))] = { 0 };
128 int i, len;
129 if (r_buf_read_at (bin->b, 0, e_ident, EI_NIDENT) == -1) {
130 bprintf ("read (magic)\n");
131 return false;
132 }
133 sdb_set (bin->kv, "elf_type.cparse", "enum elf_type { ET_NONE=0, ET_REL=1,"
134 " ET_EXEC=2, ET_DYN=3, ET_CORE=4, ET_LOOS=0xfe00, ET_HIOS=0xfeff,"
135 " ET_LOPROC=0xff00, ET_HIPROC=0xffff };", 0);
136 sdb_set (bin->kv, "elf_machine.cparse", "enum elf_machine {EM_NONE=0, EM_M32=1,"
137 " EM_SPARC=2, EM_386=3, EM_68K=4, EM_88K=5, EM_IAMCU=6, EM_860=7, EM_MIPS=8,"
138 " EM_S370=9, EM_MIPS_RS3_LE=10, EM_RS6000=11, EM_PARISC=15, EM_nCUBE=16,"
139 " EM_VPP500=17, EM_SPARC32PLUS=18, EM_960=19, EM_PPC=20, EM_PPC64=21, EM_S390=22,"
140 " EM_SPU=23, EM_V800=36, EM_FR20=37, EM_RH32=38, EM_RCE=39, EM_ARM=40,"
141 " EM_ALPHA=41, EM_SH=42, EM_SPARCV9=43, EM_TRICORE=44, EM_ARC=45, EM_H8_300=46,"
142 " EM_H8_300H=47, EM_H8S=48, EM_H8_500=49, EM_IA_64=50, EM_MIPS_X=51,"
143 " EM_COLDFIRE=52, EM_68HC12=53, EM_MMA=54, EM_PCP=55, EM_NCPU=56, EM_NDR1=57,"
144 " EM_STARCORE=58, EM_ME16=59, EM_ST100=60, EM_TINYJ=61, EM_X86_64=62, EM_PDSP=63,"
145 " EM_PDP10=64, EM_PDP11=65, EM_FX66=66, EM_ST9PLUS=67, EM_ST7=68, EM_68HC16=69,"
146 " EM_68HC11=70, EM_68HC08=71, EM_68HC05=72, EM_SVX=73, EM_ST19=74, EM_VAX=75,"
147 " EM_CRIS=76, EM_JAVELIN=77, EM_FIREPATH=78, EM_ZSP=79, EM_MMIX=80, EM_HUANY=81,"
148 " EM_PRISM=82, EM_AVR=83, EM_FR30=84, EM_D10V=85, EM_D30V=86, EM_V850=87,"
149 " EM_M32R=88, EM_MN10300=89, EM_MN10200=90, EM_PJ=91, EM_OPENRISC=92,"
150 " EM_ARC_COMPACT=93, EM_XTENSA=94, EM_VIDEOCORE=95, EM_TMM_GPP=96, EM_NS32K=97,"
151 " EM_TPC=98, EM_SNP1K=99, EM_ST200=100, EM_IP2K=101, EM_MAX=102, EM_CR=103,"
152 " EM_F2MC16=104, EM_MSP430=105, EM_BLACKFIN=106, EM_SE_C33=107, EM_SEP=108,"
153 " EM_ARCA=109, EM_UNICORE=110, EM_EXCESS=111, EM_DXP=112, EM_ALTERA_NIOS2=113,"
154 " EM_CRX=114, EM_XGATE=115, EM_C166=116, EM_M16C=117, EM_DSPIC30F=118, EM_CE=119,"
155 " EM_M32C=120, EM_TSK3000=131, EM_RS08=132, EM_SHARC=133, EM_ECOG2=134,"
156 " EM_SCORE7=135, EM_DSP24=136, EM_VIDEOCORE3=137, EM_LATTICEMICO32=138,"
157 " EM_SE_C17=139, EM_TI_C6000=140, EM_TI_C2000=141, EM_TI_C5500=142,"
158 " EM_TI_ARP32=143, EM_TI_PRU=144,"
159 " EM_MMDSP_PLUS=160, EM_CYPRESS_M8C=161, EM_R32C=162, EM_TRIMEDIA=163,"
160 " EM_QDSP6=164, EM_8051=165, EM_STXP7X=166, EM_NDS32=167,"
161 " EM_ECOG1X=168, EM_MAXQ30=169, EM_XIMO16=170, EM_MANIK=171, EM_CRAYNV2=172,"
162 " EM_RX=173, EM_METAG=174, EM_MCST_ELBRUS=175, EM_ECOG16=176, EM_CR16=177,"
163 " EM_ETPU=178, EM_SLE9X=179, EM_L10M=180, EM_K10M=181, EM_AARCH64=183,"
164 " EM_AVR32=185, EM_STM8=186, EM_TILE64=187, EM_TILEPRO=188, EM_CUDA=190,"
165 " EM_TILEGX=191, EM_CLOUDSHIELD=192, EM_COREA_1ST=193, EM_COREA_2ND=194,"
166 " EM_ARC_COMPACT2=195, EM_OPEN8=196, EM_RL78=197, EM_VIDEOCORE5=198,"
167 " EM_78KOR=199, EM_56800EX=200, EM_BA1=201, EM_BA2=202, EM_XCORE=203,"
168 " EM_MCHP_PIC=204, EM_INTEL205=205, EM_INTEL206=206, EM_INTEL207=207,"
169 " EM_INTEL208=208, EM_INTEL209=209, EM_KM32=210, EM_KMX32=211, EM_KMX16=212,"
170 " EM_KMX8=213, EM_KVARC=214, EM_CDP=215, EM_COGE=216, EM_COOL=217, EM_NORC=218,"
171 " EM_CSR_KALIMBA=219, EM_AMDGPU=224, EM_RISCV=243, EM_LANAI=244, EM_BPF=247,"
172 " EM_CSKY=252}", 0);
173 sdb_set (bin->kv, "elf_class.cparse", "enum elf_class {ELFCLASSNONE=0, ELFCLASS32=1, ELFCLASS64=2};", 0);
174 sdb_set (bin->kv, "elf_data.cparse", "enum elf_data {ELFDATANONE=0, ELFDATA2LSB=1, ELFDATA2MSB=2};", 0);
175 sdb_set (bin->kv, "elf_hdr_version.cparse", "enum elf_hdr_version {EV_NONE=0, EV_CURRENT=1};", 0);
176 sdb_set (bin->kv, "elf_obj_version.cparse", "enum elf_obj_version {EV_NONE=0, EV_CURRENT=1};", 0);
177 sdb_num_set (bin->kv, "elf_header.offset", 0, 0);
178 sdb_num_set (bin->kv, "elf_header.size", sizeof (Elf_(Ehdr)), 0);
179 sdb_set (bin->kv, "elf_ident.format", "[4]z[1]E[1]E[1]E.::"
180 " magic (elf_class)class (elf_data)data (elf_hdr_version)version", 0);
181 #if R_BIN_ELF64
182 sdb_set (bin->kv, "elf_header.format", "?[2]E[2]E[4]EqqqxN2N2N2N2N2N2"
183 " (elf_ident)ident (elf_type)type (elf_machine)machine (elf_obj_version)version"
184 " entry phoff shoff flags ehsize phentsize phnum shentsize shnum shstrndx", 0);
185 #else
186 sdb_set (bin->kv, "elf_header.format", "?[2]E[2]E[4]ExxxxN2N2N2N2N2N2"
187 " (elf_ident)ident (elf_type)type (elf_machine)machine (elf_obj_version)version"
188 " entry phoff shoff flags ehsize phentsize phnum shentsize shnum shstrndx", 0);
189 #endif
190 bin->endian = (e_ident[EI_DATA] == ELFDATA2MSB)? 1: 0;
191 memset (&bin->ehdr, 0, sizeof (Elf_(Ehdr)));
192 len = r_buf_read_at (bin->b, 0, ehdr, sizeof (ehdr));
193 if (len < 32) { // tinyelf != sizeof (Elf_(Ehdr))) {
194 bprintf ("read (ehdr)\n");
195 return false;
196 }
197 // XXX no need to check twice
198 memcpy (&bin->ehdr.e_ident, ehdr, 16);
199 if (!__is_valid_ident (bin)) {
200 return false;
201 }
202 i = 16;
203 // TODO: use r_read or r_buf_read_ apis instead
204 bin->ehdr.e_type = READ16 (ehdr, i);
205 bin->ehdr.e_machine = READ16 (ehdr, i);
206 bin->ehdr.e_version = READ32 (ehdr, i);
207 #if R_BIN_ELF64
208 bin->ehdr.e_entry = READ64 (ehdr, i);
209 bin->ehdr.e_phoff = READ64 (ehdr, i);
210 bin->ehdr.e_shoff = READ64 (ehdr, i);
211 #else
212 bin->ehdr.e_entry = READ32 (ehdr, i);
213 bin->ehdr.e_phoff = READ32 (ehdr, i);
214 bin->ehdr.e_shoff = READ32 (ehdr, i);
215 #endif
216 bin->ehdr.e_flags = READ32 (ehdr, i);
217 bin->ehdr.e_ehsize = READ16 (ehdr, i);
218 bin->ehdr.e_phentsize = READ16 (ehdr, i);
219 bin->ehdr.e_phnum = READ16 (ehdr, i);
220 bin->ehdr.e_shentsize = READ16 (ehdr, i);
221 bin->ehdr.e_shnum = READ16 (ehdr, i);
222 bin->ehdr.e_shstrndx = READ16 (ehdr, i);
223 return true;
224 // [Outdated] Usage example:
225 // > td `k bin/cur/info/elf_type.cparse`; td `k bin/cur/info/elf_machine.cparse`
226 // > pf `k bin/cur/info/elf_header.format` @ `k bin/cur/info/elf_header.offset`
227 }
228
read_phdr(ELFOBJ * bin,bool linux_kernel_hack)229 static bool read_phdr(ELFOBJ *bin, bool linux_kernel_hack) {
230 bool phdr_found = false;
231 int i;
232 #if R_BIN_ELF64
233 const bool is_elf64 = true;
234 #else
235 const bool is_elf64 = false;
236 #endif
237 for (i = 0; i < bin->ehdr.e_phnum; i++) {
238 ut8 phdr[sizeof (Elf_(Phdr))] = { 0 };
239 int j = 0;
240 const size_t rsize = bin->ehdr.e_phoff + i * sizeof (Elf_(Phdr));
241 int len = r_buf_read_at (bin->b, rsize, phdr, sizeof (Elf_(Phdr)));
242 if (len < 1) {
243 bprintf ("read (phdr)\n");
244 R_FREE (bin->phdr);
245 return false;
246 }
247 bin->phdr[i].p_type = READ32 (phdr, j);
248 if (bin->phdr[i].p_type == PT_PHDR) {
249 phdr_found = true;
250 }
251
252 if (is_elf64) {
253 bin->phdr[i].p_flags = READ32 (phdr, j);
254 }
255 bin->phdr[i].p_offset = R_BIN_ELF_READWORD (phdr, j);
256 bin->phdr[i].p_vaddr = R_BIN_ELF_READWORD (phdr, j);
257 bin->phdr[i].p_paddr = R_BIN_ELF_READWORD (phdr, j);
258 bin->phdr[i].p_filesz = R_BIN_ELF_READWORD (phdr, j);
259 bin->phdr[i].p_memsz = R_BIN_ELF_READWORD (phdr, j);
260 if (!is_elf64) {
261 bin->phdr[i].p_flags = READ32 (phdr, j);
262 // bin->phdr[i].p_flags |= 1; tiny.elf needs this somehow :? LOAD0 is always +x for linux?
263 }
264 bin->phdr[i].p_align = R_BIN_ELF_READWORD (phdr, j);
265 }
266 /* Here is the where all the fun starts.
267 * Linux kernel since 2005 calculates phdr offset wrongly
268 * adding it to the load address (va of the LOAD0).
269 * See `fs/binfmt_elf.c` file this line:
270 * NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);
271 * So after the first read, we fix the address and read it again
272 */
273 if (linux_kernel_hack && phdr_found) {
274 ut64 load_addr = Elf_(r_bin_elf_get_baddr) (bin);
275 bin->ehdr.e_phoff = Elf_(r_bin_elf_v2p) (bin, load_addr + bin->ehdr.e_phoff);
276 return read_phdr (bin, false);
277 }
278 return true;
279 }
280
init_phdr(ELFOBJ * bin)281 static int init_phdr(ELFOBJ *bin) {
282 ut32 phdr_size;
283
284 r_return_val_if_fail (!bin->phdr, false);
285
286 if (!bin->ehdr.e_phnum) {
287 return false;
288 }
289 if (!UT32_MUL (&phdr_size, (ut32)bin->ehdr.e_phnum, sizeof (Elf_(Phdr)))) {
290 return false;
291 }
292 if (!phdr_size) {
293 return false;
294 }
295 if (phdr_size > bin->size) {
296 return false;
297 }
298 if (phdr_size > (ut32)bin->size) {
299 return false;
300 }
301 if (bin->ehdr.e_phoff > bin->size) {
302 return false;
303 }
304 if (bin->ehdr.e_phoff + phdr_size > bin->size) {
305 return false;
306 }
307 if (!(bin->phdr = R_NEWS0 (Elf_(Phdr), bin->ehdr.e_phnum))) {
308 perror ("malloc (phdr)");
309 return false;
310 }
311
312 bool linux_kern_hack = false;
313 /* Enable this hack only for the X86 64bit ELFs */
314 const int _128K = 1024 * 128;
315 if (r_buf_size (bin->b) > _128K && (bin->ehdr.e_machine == EM_X86_64 || bin->ehdr.e_machine == EM_386)) {
316 linux_kern_hack = true;
317 }
318 if (!read_phdr (bin, linux_kern_hack)) {
319 return false;
320 }
321
322 sdb_num_set (bin->kv, "elf_phdr.offset", bin->ehdr.e_phoff, 0);
323 sdb_num_set (bin->kv, "elf_phdr.size", sizeof (Elf_(Phdr)), 0);
324 sdb_set (bin->kv, "elf_p_type.cparse", "enum elf_p_type {PT_NULL=0,PT_LOAD=1,PT_DYNAMIC=2,"
325 "PT_INTERP=3,PT_NOTE=4,PT_SHLIB=5,PT_PHDR=6,PT_LOOS=0x60000000,"
326 "PT_HIOS=0x6fffffff,PT_LOPROC=0x70000000,PT_HIPROC=0x7fffffff};",
327 0);
328 sdb_set (bin->kv, "elf_p_flags.cparse", "enum elf_p_flags {PF_None=0,PF_Exec=1,"
329 "PF_Write=2,PF_Write_Exec=3,PF_Read=4,PF_Read_Exec=5,PF_Read_Write=6,"
330 "PF_Read_Write_Exec=7};", 0);
331 #if R_BIN_ELF64
332 sdb_set (bin->kv, "elf_phdr.format", "[4]E[4]Eqqqqqq (elf_p_type)type (elf_p_flags)flags"
333 " offset vaddr paddr filesz memsz align", 0);
334 #else
335 sdb_set (bin->kv, "elf_phdr.format", "[4]Exxxxx[4]Ex (elf_p_type)type offset vaddr paddr"
336 " filesz memsz (elf_p_flags)flags align", 0);
337 #endif
338 return true;
339 // Usage example:
340 // > td `k bin/cur/info/elf_p_type.cparse`; td `k bin/cur/info/elf_p_flags.cparse`
341 // > pf `k bin/cur/info/elf_phdr.format` @ `k bin/cur/info/elf_phdr.offset`
342 }
343
init_shdr(ELFOBJ * bin)344 static int init_shdr(ELFOBJ *bin) {
345 ut32 shdr_size;
346 ut8 shdr[sizeof (Elf_(Shdr))] = { 0 };
347 int i, j, len;
348
349 r_return_val_if_fail (bin && !bin->shdr, false);
350
351 if (!UT32_MUL (&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) {
352 return false;
353 }
354 if (shdr_size < 1) {
355 return false;
356 }
357 if (shdr_size > bin->size) {
358 return false;
359 }
360 if (bin->ehdr.e_shoff > bin->size) {
361 return false;
362 }
363 if (bin->ehdr.e_shoff + shdr_size > bin->size) {
364 return false;
365 }
366 if (!(bin->shdr = R_NEWS0 (Elf_(Shdr), bin->ehdr.e_shnum))) {
367 perror ("malloc (shdr)");
368 return false;
369 }
370 sdb_num_set (bin->kv, "elf_shdr.offset", bin->ehdr.e_shoff, 0);
371 sdb_num_set (bin->kv, "elf_shdr.size", sizeof (Elf_(Shdr)), 0);
372 sdb_set (bin->kv, "elf_s_type.cparse", "enum elf_s_type {SHT_NULL=0,SHT_PROGBITS=1,"
373 "SHT_SYMTAB=2,SHT_STRTAB=3,SHT_RELA=4,SHT_HASH=5,SHT_DYNAMIC=6,SHT_NOTE=7,"
374 "SHT_NOBITS=8,SHT_REL=9,SHT_SHLIB=10,SHT_DYNSYM=11,SHT_LOOS=0x60000000,"
375 "SHT_HIOS=0x6fffffff,SHT_LOPROC=0x70000000,SHT_HIPROC=0x7fffffff};", 0);
376
377 for (i = 0; i < bin->ehdr.e_shnum; i++) {
378 j = 0;
379 len = r_buf_read_at (bin->b, bin->ehdr.e_shoff + i * sizeof (Elf_(Shdr)), shdr, sizeof (Elf_(Shdr)));
380 if (len < 1) {
381 bprintf ("read (shdr) at 0x%" PFMT64x "\n", (ut64) bin->ehdr.e_shoff);
382 R_FREE (bin->shdr);
383 return false;
384 }
385 bin->shdr[i].sh_name = READ32 (shdr, j);
386 bin->shdr[i].sh_type = READ32 (shdr, j);
387 bin->shdr[i].sh_flags = R_BIN_ELF_READWORD (shdr, j);
388 bin->shdr[i].sh_addr = R_BIN_ELF_READWORD (shdr, j);
389 bin->shdr[i].sh_offset = R_BIN_ELF_READWORD (shdr, j);
390 bin->shdr[i].sh_size = R_BIN_ELF_READWORD (shdr, j);
391 bin->shdr[i].sh_link = READ32 (shdr, j);
392 bin->shdr[i].sh_info = READ32 (shdr, j);
393 bin->shdr[i].sh_addralign = R_BIN_ELF_READWORD (shdr, j);
394 bin->shdr[i].sh_entsize = R_BIN_ELF_READWORD (shdr, j);
395 }
396
397 #if R_BIN_ELF64
398 sdb_set (bin->kv, "elf_s_flags_64.cparse", "enum elf_s_flags_64 {SF64_None=0,SF64_Exec=1,"
399 "SF64_Alloc=2,SF64_Alloc_Exec=3,SF64_Write=4,SF64_Write_Exec=5,"
400 "SF64_Write_Alloc=6,SF64_Write_Alloc_Exec=7};", 0);
401 sdb_set (bin->kv, "elf_shdr.format", "x[4]E[8]Eqqqxxqq name (elf_s_type)type"
402 " (elf_s_flags_64)flags addr offset size link info addralign entsize", 0);
403 #else
404 sdb_set (bin->kv, "elf_s_flags_32.cparse", "enum elf_s_flags_32 {SF32_None=0,SF32_Exec=1,"
405 "SF32_Alloc=2,SF32_Alloc_Exec=3,SF32_Write=4,SF32_Write_Exec=5,"
406 "SF32_Write_Alloc=6,SF32_Write_Alloc_Exec=7};", 0);
407 sdb_set (bin->kv, "elf_shdr.format", "x[4]E[4]Exxxxxxx name (elf_s_type)type"
408 " (elf_s_flags_32)flags addr offset size link info addralign entsize", 0);
409 #endif
410 return true;
411 // Usage example:
412 // > td `k bin/cur/info/elf_s_type.cparse`; td `k bin/cur/info/elf_s_flags_64.cparse`
413 // > pf `k bin/cur/info/elf_shdr.format` @ `k bin/cur/info/elf_shdr.offset`
414 }
415
is_shidx_valid(ELFOBJ * bin,Elf_ (Half)value)416 static bool is_shidx_valid(ELFOBJ *bin, Elf_(Half) value) {
417 return value < bin->ehdr.e_shnum && !R_BETWEEN (SHN_LORESERVE, value, SHN_HIRESERVE);
418 }
419
init_strtab(ELFOBJ * bin)420 static int init_strtab(ELFOBJ *bin) {
421 r_return_val_if_fail (!bin->strtab, false);
422
423 if (!bin->shdr) {
424 return false;
425 }
426
427 Elf_(Half) shstrndx = bin->ehdr.e_shstrndx;
428 if (shstrndx != SHN_UNDEF && !is_shidx_valid (bin, shstrndx)) {
429 return false;
430 }
431
432 /* sh_size must be lower than UT32_MAX and not equal to zero, to avoid bugs on malloc() */
433 if (bin->shdr[shstrndx].sh_size > UT32_MAX) {
434 return false;
435 }
436 if (!bin->shdr[shstrndx].sh_size) {
437 return false;
438 }
439 bin->shstrtab_section = bin->strtab_section = &bin->shdr[shstrndx];
440 bin->shstrtab_size = bin->shstrtab_section->sh_size;
441 if (bin->shstrtab_size > bin->size) {
442 return false;
443 }
444 if (bin->shstrtab_section->sh_offset > bin->size) {
445 return false;
446 }
447 if (bin->shstrtab_section->sh_offset + bin->shstrtab_section->sh_size > bin->size) {
448 return false;
449 }
450
451 if (!(bin->shstrtab = calloc (1, bin->shstrtab_size + 1))) {
452 perror ("malloc");
453 bin->shstrtab = NULL;
454 return false;
455 }
456 int res = r_buf_read_at (bin->b, bin->shstrtab_section->sh_offset, (ut8*)bin->shstrtab,
457 bin->shstrtab_section->sh_size);
458 if (res < 1) {
459 bprintf ("read (shstrtab) at 0x%" PFMT64x "\n", (ut64) bin->shstrtab_section->sh_offset);
460 R_FREE (bin->shstrtab);
461 return false;
462 }
463 bin->shstrtab[bin->shstrtab_section->sh_size] = '\0';
464
465 sdb_num_set (bin->kv, "elf_shstrtab.offset", bin->shstrtab_section->sh_offset, 0);
466 sdb_num_set (bin->kv, "elf_shstrtab.size", bin->shstrtab_section->sh_size, 0);
467
468 return true;
469 }
470
Elf_(Phdr)471 static Elf_(Phdr) *get_dynamic_segment(ELFOBJ *bin) {
472 int i;
473 for (i = 0; i < bin->ehdr.e_phnum; i++) {
474 if (bin->phdr[i].p_type == PT_DYNAMIC) {
475 if (bin->phdr[i].p_filesz > bin->size) {
476 return NULL;
477 }
478 if (bin->phdr[i].p_offset > bin->size) {
479 return NULL;
480 }
481 if (bin->phdr[i].p_offset + sizeof (Elf_(Dyn)) > bin->size) {
482 return NULL;
483 }
484 return &bin->phdr[i];
485 }
486 }
487 return NULL;
488 }
489
init_dynamic_section_sdb(ELFOBJ * bin,Elf_ (Addr)strtabaddr,size_t strsize)490 static void init_dynamic_section_sdb(ELFOBJ *bin, Elf_(Addr) strtabaddr, size_t strsize) {
491 int r = Elf_(r_bin_elf_has_relro) (bin);
492 switch (r) {
493 case R_ELF_FULL_RELRO:
494 sdb_set (bin->kv, "elf.relro", "full", 0);
495 break;
496 case R_ELF_PART_RELRO:
497 sdb_set (bin->kv, "elf.relro", "partial", 0);
498 break;
499 default:
500 sdb_set (bin->kv, "elf.relro", "no", 0);
501 break;
502 }
503 sdb_num_set (bin->kv, "elf_strtab.offset", strtabaddr, 0);
504 sdb_num_set (bin->kv, "elf_strtab.size", strsize, 0);
505 }
506
set_default_value_dynamic_info(ELFOBJ * bin)507 static void set_default_value_dynamic_info(ELFOBJ *bin) {
508 bin->dyn_info.dt_pltrelsz = 0;
509 bin->dyn_info.dt_pltgot = R_BIN_ELF_ADDR_MAX;
510 bin->dyn_info.dt_hash = R_BIN_ELF_ADDR_MAX;
511 bin->dyn_info.dt_strtab = R_BIN_ELF_ADDR_MAX;
512 bin->dyn_info.dt_symtab = R_BIN_ELF_ADDR_MAX;
513 bin->dyn_info.dt_rela = R_BIN_ELF_ADDR_MAX;
514 bin->dyn_info.dt_relasz = 0;
515 bin->dyn_info.dt_relaent = 0;
516 bin->dyn_info.dt_strsz = 0;
517 bin->dyn_info.dt_syment = 0;
518 bin->dyn_info.dt_rel = R_BIN_ELF_ADDR_MAX;
519 bin->dyn_info.dt_relsz = 0;
520 bin->dyn_info.dt_relent = 0;
521 bin->dyn_info.dt_pltrel = R_BIN_ELF_XWORD_MAX;
522 bin->dyn_info.dt_jmprel = R_BIN_ELF_ADDR_MAX;
523 bin->dyn_info.dt_pltgot = R_BIN_ELF_ADDR_MAX;
524 bin->dyn_info.dt_mips_pltgot = R_BIN_ELF_ADDR_MAX;
525 bin->dyn_info.dt_bind_now = false;
526 bin->dyn_info.dt_flags = R_BIN_ELF_XWORD_MAX;
527 bin->dyn_info.dt_flags_1 = R_BIN_ELF_XWORD_MAX;
528 bin->dyn_info.dt_rpath = R_BIN_ELF_XWORD_MAX;
529 bin->dyn_info.dt_runpath = R_BIN_ELF_XWORD_MAX;
530 r_vector_init(&bin->dyn_info.dt_needed, sizeof(Elf_(Off)), NULL, NULL);
531 }
532
get_maximum_number_of_dynamic_entries(ut64 dyn_size)533 static size_t get_maximum_number_of_dynamic_entries(ut64 dyn_size) {
534 return dyn_size / sizeof (Elf_(Dyn));
535 }
536
fill_dynamic_entry(ELFOBJ * bin,ut64 entry_offset,Elf_ (Dyn)* d)537 static bool fill_dynamic_entry(ELFOBJ *bin, ut64 entry_offset, Elf_(Dyn) *d) {
538 ut8 sdyn[sizeof (Elf_(Dyn))] = { 0 };
539 int j = 0;
540 int len = r_buf_read_at (bin->b, entry_offset, sdyn, sizeof (Elf_(Dyn)));
541 if (len < 1) {
542 return false;
543 }
544
545 d->d_tag = R_BIN_ELF_READWORD (sdyn, j);
546 d->d_un.d_ptr = R_BIN_ELF_READWORD (sdyn, j);
547
548 return true;
549 }
550
fill_dynamic_entries(ELFOBJ * bin,ut64 loaded_offset,ut64 dyn_size)551 static void fill_dynamic_entries(ELFOBJ *bin, ut64 loaded_offset, ut64 dyn_size) {
552 Elf_(Dyn) d = { 0 };
553 size_t i;
554 size_t number_of_entries = get_maximum_number_of_dynamic_entries(dyn_size);
555
556 for (i = 0; i < number_of_entries; i++) {
557 ut64 entry_offset = loaded_offset + i * sizeof (Elf_(Dyn));
558 if (!fill_dynamic_entry (bin, entry_offset, &d)) {
559 break;
560 }
561
562 switch (d.d_tag) {
563 case DT_NULL:
564 break;
565 case DT_PLTRELSZ:
566 bin->dyn_info.dt_pltrelsz = d.d_un.d_val;
567 break;
568 case DT_PLTGOT:
569 bin->dyn_info.dt_pltgot = d.d_un.d_ptr;
570 break;
571 case DT_HASH:
572 bin->dyn_info.dt_hash = d.d_un.d_ptr;
573 break;
574 case DT_STRTAB:
575 bin->dyn_info.dt_strtab = d.d_un.d_ptr;
576 break;
577 case DT_SYMTAB:
578 bin->dyn_info.dt_symtab = d.d_un.d_ptr;
579 break;
580 case DT_RELA:
581 bin->dyn_info.dt_rela = d.d_un.d_ptr;
582 break;
583 case DT_RELASZ:
584 bin->dyn_info.dt_relasz = d.d_un.d_val;
585 break;
586 case DT_RELAENT:
587 bin->dyn_info.dt_relaent = d.d_un.d_val;
588 break;
589 case DT_STRSZ:
590 bin->dyn_info.dt_strsz = d.d_un.d_val;
591 break;
592 case DT_SYMENT:
593 bin->dyn_info.dt_syment = d.d_un.d_val;
594 break;
595 case DT_REL:
596 bin->dyn_info.dt_rel = d.d_un.d_ptr;
597 break;
598 case DT_RELSZ:
599 bin->dyn_info.dt_relsz = d.d_un.d_val;
600 break;
601 case DT_RELENT:
602 bin->dyn_info.dt_relent = d.d_un.d_val;
603 break;
604 case DT_PLTREL:
605 bin->dyn_info.dt_pltrel = d.d_un.d_val;
606 break;
607 case DT_JMPREL:
608 bin->dyn_info.dt_jmprel = d.d_un.d_ptr;
609 break;
610 case DT_MIPS_PLTGOT:
611 bin->dyn_info.dt_mips_pltgot = d.d_un.d_ptr;
612 break;
613 case DT_BIND_NOW:
614 bin->dyn_info.dt_bind_now = true;
615 break;
616 case DT_FLAGS:
617 bin->dyn_info.dt_flags = d.d_un.d_val;
618 break;
619 case DT_FLAGS_1:
620 bin->dyn_info.dt_flags_1 = d.d_un.d_val;
621 break;
622 case DT_RPATH:
623 bin->dyn_info.dt_rpath = d.d_un.d_val;
624 break;
625 case DT_RUNPATH:
626 bin->dyn_info.dt_runpath = d.d_un.d_val;
627 break;
628 case DT_NEEDED:
629 r_vector_push (&bin->dyn_info.dt_needed, &d.d_un.d_val);
630 break;
631 case DT_INIT:
632 case DT_FINI:
633 case DT_DEBUG:
634 case DT_INIT_ARRAY:
635 case DT_FINI_ARRAY:
636 case DT_INIT_ARRAYSZ:
637 case DT_FINI_ARRAYSZ:
638 case DT_PREINIT_ARRAY:
639 case DT_PREINIT_ARRAYSZ:
640 case DT_SONAME:
641 case DT_GNU_HASH:
642 // common dynamic entries in ELF, but we don't need to
643 // do anything with them.
644 break;
645 default:
646 if ((d.d_tag >= DT_VERSYM) && (d.d_tag <= DT_VERNEEDNUM)) {
647 bin->version_info[DT_VERSIONTAGIDX (d.d_tag)] = d.d_un.d_val;
648 } else {
649 R_LOG_DEBUG ("Dynamic tag %" PFMT64d " not handled\n", (ut64) d.d_tag);
650 }
651 break;
652 }
653 if (d.d_tag == DT_NULL) {
654 break;
655 }
656 }
657 }
658
init_dynamic_section(ELFOBJ * bin)659 static int init_dynamic_section(ELFOBJ *bin) {
660 ut64 strtabaddr = 0;
661 char *strtab = NULL;
662 size_t strsize = 0;
663 int r;
664 ut64 dyn_size = 0, loaded_offset;
665 set_default_value_dynamic_info(bin);
666
667 r_return_val_if_fail (bin, false);
668 if (!bin->phdr || !bin->ehdr.e_phnum) {
669 return false;
670 }
671
672 Elf_(Phdr) *dyn_phdr = get_dynamic_segment (bin);
673 if (!dyn_phdr) {
674 return false;
675 }
676
677 dyn_size = dyn_phdr->p_filesz;
678 loaded_offset = Elf_(r_bin_elf_v2p_new) (bin, dyn_phdr->p_vaddr);
679 if (loaded_offset == UT64_MAX) {
680 return false;
681 }
682
683 if (!dyn_size || loaded_offset + dyn_size > bin->size) {
684 return false;
685 }
686
687 fill_dynamic_entries (bin, loaded_offset, dyn_size);
688
689 if (bin->dyn_info.dt_strtab != R_BIN_ELF_ADDR_MAX) {
690 strtabaddr = Elf_(r_bin_elf_v2p_new) (bin, bin->dyn_info.dt_strtab);
691 }
692
693 if (bin->dyn_info.dt_strsz > 0) {
694 strsize = bin->dyn_info.dt_strsz;
695 }
696
697 if (strtabaddr == UT64_MAX || strtabaddr > bin->size || strsize > ST32_MAX || !strsize || strsize > bin->size || strtabaddr + strsize > bin->size) {
698 if (!strtabaddr) {
699 bprintf ("DT_STRTAB not found or invalid\n");
700 }
701 return false;
702 }
703 strtab = (char *)calloc (1, strsize + 1);
704 if (!strtab) {
705 return false;
706 }
707 r = r_buf_read_at (bin->b, strtabaddr, (ut8 *)strtab, strsize);
708 if (r < 1) {
709 free (strtab);
710 return false;
711 }
712
713 bin->strtab = strtab;
714 bin->strtab_size = strsize;
715 init_dynamic_section_sdb (bin, strtabaddr, strsize);
716 return true;
717 }
718
get_section_by_name(ELFOBJ * bin,const char * section_name)719 static RBinElfSection* get_section_by_name(ELFOBJ *bin, const char *section_name) {
720 if (bin->g_sections) {
721 size_t i;
722 for (i = 0; !bin->g_sections[i].last; i++) {
723 if (!strncmp (bin->g_sections[i].name, section_name, ELF_STRING_LENGTH - 1)) {
724 return &bin->g_sections[i];
725 }
726 }
727 }
728 return NULL;
729 }
730
get_ver_flags(ut32 flags)731 static char *get_ver_flags(ut32 flags) {
732 static char buff[32];
733 buff[0] = 0;
734
735 if (!flags) {
736 return "none";
737 }
738 if (flags & VER_FLG_BASE) {
739 strcpy (buff, "BASE ");
740 }
741 if (flags & VER_FLG_WEAK) {
742 if (flags & VER_FLG_BASE) {
743 strcat (buff, "| ");
744 }
745 strcat (buff, "WEAK ");
746 }
747
748 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)) {
749 strcat (buff, "| <unknown>");
750 }
751 return buff;
752 }
753
store_versioninfo_gnu_versym(ELFOBJ * bin,Elf_ (Shdr)* shdr,int sz)754 static Sdb *store_versioninfo_gnu_versym(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
755 size_t i;
756 const ut64 num_entries = sz / sizeof (Elf_(Versym));
757 const char *section_name = "";
758 const char *link_section_name = "";
759 Sdb *sdb = sdb_new0 ();
760 if (!sdb) {
761 return NULL;
762 }
763 if (!bin->version_info[DT_VERSIONTAGIDX (DT_VERSYM)]) {
764 sdb_free (sdb);
765 return NULL;
766 }
767 if (shdr->sh_link >= bin->ehdr.e_shnum) {
768 sdb_free (sdb);
769 return NULL;
770 }
771 Elf_(Shdr) *link_shdr = &bin->shdr[shdr->sh_link];
772 ut8 *edata = (ut8*) calloc (R_MAX (1, num_entries), 2 * sizeof (ut8));
773 if (!edata) {
774 sdb_free (sdb);
775 return NULL;
776 }
777 ut16 *data = (ut16 *)calloc (R_MAX (1, num_entries), sizeof (ut16));
778 if (!data) {
779 free (edata);
780 sdb_free (sdb);
781 return NULL;
782 }
783 ut64 off = Elf_(r_bin_elf_v2p) (bin, bin->version_info[DT_VERSIONTAGIDX (DT_VERSYM)]);
784 if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
785 section_name = &bin->shstrtab[shdr->sh_name];
786 }
787 if (bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
788 link_section_name = &bin->shstrtab[link_shdr->sh_name];
789 }
790 r_buf_read_at (bin->b, off, edata, sizeof (ut16) * num_entries);
791 sdb_set (sdb, "section_name", section_name, 0);
792 sdb_num_set (sdb, "num_entries", num_entries, 0);
793 sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
794 sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
795 sdb_num_set (sdb, "link", shdr->sh_link, 0);
796 sdb_set (sdb, "link_section_name", link_section_name, 0);
797 for (i = num_entries; i--;) {
798 data[i] = r_read_ble16 (&edata[i * sizeof (ut16)], bin->endian);
799 }
800 R_FREE (edata);
801 char *tmp_val = NULL;
802 for (i = 0; i < num_entries; i += 4) {
803 size_t j;
804 int check_def;
805 char key[32] = { 0 };
806
807 for (j = 0; (j < 4) && (i + j) < num_entries; j++) {
808 int k;
809 snprintf (key, sizeof (key), "entry%zd", i + j);
810 switch (data[i + j]) {
811 case 0:
812 sdb_set (sdb, key, "0 (*local*)", 0);
813 break;
814 case 1:
815 sdb_set (sdb, key, "1 (*global*)", 0);
816 break;
817 default:
818 free (tmp_val);
819 tmp_val = strdup (sdb_fmt ("%x ", data[i+j] & 0x7FFF));
820 check_def = true;
821 if (bin->version_info[DT_VERSIONTAGIDX (DT_VERNEED)]) {
822 Elf_(Verneed) vn;
823 ut8 svn[sizeof (Elf_(Verneed))] = { 0 };
824 ut64 offset = Elf_(r_bin_elf_v2p) (bin, bin->version_info[DT_VERSIONTAGIDX (DT_VERNEED)]);
825 do {
826 Elf_(Vernaux) vna;
827 ut8 svna[sizeof (Elf_(Vernaux))] = { 0 };
828 ut64 a_off;
829 if (offset > bin->size || offset + sizeof (vn) > bin->size) {
830 goto beach;
831 }
832 if (r_buf_read_at (bin->b, offset, svn, sizeof (svn)) < 0) {
833 bprintf ("Cannot read Verneed for Versym\n");
834 goto beach;
835 }
836 k = 0;
837 vn.vn_version = READ16 (svn, k);
838 vn.vn_cnt = READ16 (svn, k);
839 vn.vn_file = READ32 (svn, k);
840 vn.vn_aux = READ32 (svn, k);
841 vn.vn_next = READ32 (svn, k);
842 a_off = offset + vn.vn_aux;
843 do {
844 if (a_off > bin->size || a_off + sizeof (vna) > bin->size) {
845 goto beach;
846 }
847 if (r_buf_read_at (bin->b, a_off, svna, sizeof (svna)) < 0) {
848 bprintf ("Cannot read Vernaux for Versym\n");
849 goto beach;
850 }
851 k = 0;
852 vna.vna_hash = READ32 (svna, k);
853 vna.vna_flags = READ16 (svna, k);
854 vna.vna_other = READ16 (svna, k);
855 vna.vna_name = READ32 (svna, k);
856 vna.vna_next = READ32 (svna, k);
857 a_off += vna.vna_next;
858 } while (vna.vna_other != data[i + j] && vna.vna_next != 0);
859
860 if (vna.vna_other == data[i + j]) {
861 if (vna.vna_name > bin->strtab_size) {
862 goto beach;
863 }
864 sdb_set (sdb, key, sdb_fmt ("%s(%s)", tmp_val, bin->strtab + vna.vna_name), 0);
865 check_def = false;
866 break;
867 }
868 offset += vn.vn_next;
869 } while (vn.vn_next);
870 }
871
872 ut64 vinfoaddr = bin->version_info[DT_VERSIONTAGIDX (DT_VERDEF)];
873 if (check_def && data[i + j] != 0x8001 && vinfoaddr) {
874 Elf_(Verdef) vd;
875 ut8 svd[sizeof (Elf_(Verdef))] = { 0 };
876 ut64 offset = Elf_(r_bin_elf_v2p) (bin, vinfoaddr);
877 if (offset > bin->size || offset + sizeof (vd) > bin->size) {
878 goto beach;
879 }
880 do {
881 if (r_buf_read_at (bin->b, offset, svd, sizeof (svd)) < 0) {
882 bprintf ("Cannot read Verdef for Versym\n");
883 goto beach;
884 }
885 k = 0;
886 vd.vd_version = READ16 (svd, k);
887 vd.vd_flags = READ16 (svd, k);
888 vd.vd_ndx = READ16 (svd, k);
889 vd.vd_cnt = READ16 (svd, k);
890 vd.vd_hash = READ32 (svd, k);
891 vd.vd_aux = READ32 (svd, k);
892 vd.vd_next = READ32 (svd, k);
893 offset += vd.vd_next;
894 } while (vd.vd_ndx != (data[i + j] & 0x7FFF) && vd.vd_next != 0);
895
896 if (vd.vd_ndx == (data[i + j] & 0x7FFF)) {
897 Elf_(Verdaux) vda;
898 ut8 svda[sizeof (Elf_(Verdaux))] = { 0 };
899 ut64 off_vda = offset - vd.vd_next + vd.vd_aux;
900 if (off_vda > bin->size || off_vda + sizeof (vda) > bin->size) {
901 goto beach;
902 }
903 if (r_buf_read_at (bin->b, off_vda, svda, sizeof (svda)) < 0) {
904 bprintf ("Cannot read Verdaux for Versym\n");
905 goto beach;
906 }
907 k = 0;
908 vda.vda_name = READ32 (svda, k);
909 vda.vda_next = READ32 (svda, k);
910 if (vda.vda_name > bin->strtab_size) {
911 goto beach;
912 }
913 const char *name = bin->strtab + vda.vda_name;
914 if (name) {
915 const char *fname = sdb_fmt ("%s(%s%-*s)", tmp_val, name, (int)(12 - strlen (name)),")");
916 sdb_set (sdb, key, fname, 0);
917 }
918 }
919 }
920 }
921 }
922 R_FREE (tmp_val);
923 }
924 beach:
925 R_FREE (tmp_val);
926 free (data);
927 return sdb;
928 }
929
store_versioninfo_gnu_verdef(ELFOBJ * bin,Elf_ (Shdr)* shdr,int sz)930 static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
931 const char *section_name = "";
932 const char *link_section_name = "";
933 char *end = NULL;
934 ut8 dfs[sizeof (Elf_(Verdef))] = { 0 };
935 Sdb *sdb;
936 ut32 cnt;
937 size_t i;
938 if (shdr->sh_link >= bin->ehdr.e_shnum) {
939 return false;
940 }
941 Elf_(Shdr) *link_shdr = &bin->shdr[shdr->sh_link];
942 #ifdef R_BIN_ELF64
943 if ((int)shdr->sh_size < 1 || shdr->sh_size > SIZE_MAX) {
944 #else
945 if ((int)shdr->sh_size < 1) {
946 #endif
947 return false;
948 }
949 if (shdr->sh_size < sizeof (Elf_(Verdef)) || shdr->sh_size < sizeof (Elf_(Verdaux))) {
950 return false;
951 }
952 Elf_(Verdef) *defs = calloc (shdr->sh_size, 1);
953 if (!defs) {
954 bprintf ("Cannot allocate memory (Check Elf_(Verdef))\n");
955 return false;
956 }
957 if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
958 section_name = &bin->shstrtab[shdr->sh_name];
959 }
960 if (link_shdr && bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
961 link_section_name = &bin->shstrtab[link_shdr->sh_name];
962 }
963 sdb = sdb_new0 ();
964 end = (char *)defs + shdr->sh_size;
965 sdb_set (sdb, "section_name", section_name, 0);
966 sdb_num_set (sdb, "entries", shdr->sh_info, 0);
967 sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
968 sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
969 sdb_num_set (sdb, "link", shdr->sh_link, 0);
970 sdb_set (sdb, "link_section_name", link_section_name, 0);
971
972 for (cnt = 0, i = 0; cnt < shdr->sh_info && i < shdr->sh_size; cnt++) {
973 Sdb *sdb_verdef = sdb_new0 ();
974 char *vstart = ((char*)defs) + i;
975 size_t vstart_off = i;
976 char key[32] = { 0 };
977 Elf_(Verdef) *verdef = (Elf_(Verdef)*)vstart;
978 Elf_(Verdaux) aux = { 0 };
979 int j = 0;
980 int isum = 0;
981
982 if (vstart + sizeof (*verdef) > end) {
983 break;
984 }
985 r_buf_read_at (bin->b, shdr->sh_offset + i, dfs, sizeof (Elf_(Verdef)));
986 verdef->vd_version = READ16 (dfs, j);
987 verdef->vd_flags = READ16 (dfs, j);
988 verdef->vd_ndx = READ16 (dfs, j);
989 verdef->vd_cnt = READ16 (dfs, j);
990 verdef->vd_hash = READ32 (dfs, j);
991 verdef->vd_aux = READ32 (dfs, j);
992 verdef->vd_next = READ32 (dfs, j);
993 int vdaux = verdef->vd_aux;
994 if (vdaux < 1 || shdr->sh_size - vstart_off < vdaux) {
995 sdb_free (sdb_verdef);
996 goto out_error;
997 }
998 vstart += vdaux;
999 vstart_off += vdaux;
1000 if (vstart > end || shdr->sh_size - sizeof (Elf_(Verdaux)) < vstart_off) {
1001 sdb_free (sdb_verdef);
1002 goto out_error;
1003 }
1004
1005 j = 0;
1006 aux.vda_name = READ32 (vstart, j);
1007 aux.vda_next = READ32 (vstart, j);
1008
1009 isum = i + verdef->vd_aux;
1010 if (aux.vda_name > bin->dynstr_size) {
1011 sdb_free (sdb_verdef);
1012 goto out_error;
1013 }
1014
1015 sdb_num_set (sdb_verdef, "idx", i, 0);
1016 sdb_num_set (sdb_verdef, "vd_version", verdef->vd_version, 0);
1017 sdb_num_set (sdb_verdef, "vd_ndx", verdef->vd_ndx, 0);
1018 sdb_num_set (sdb_verdef, "vd_cnt", verdef->vd_cnt, 0);
1019 sdb_set (sdb_verdef, "vda_name", &bin->dynstr[aux.vda_name], 0);
1020 sdb_set (sdb_verdef, "flags", get_ver_flags (verdef->vd_flags), 0);
1021
1022 for (j = 1; j < verdef->vd_cnt; j++) {
1023 int k;
1024 Sdb *sdb_parent = sdb_new0 ();
1025 if (shdr->sh_size - vstart_off < aux.vda_next) {
1026 sdb_free (sdb_verdef);
1027 sdb_free (sdb_parent);
1028 goto out_error;
1029 }
1030 isum += aux.vda_next;
1031 vstart += aux.vda_next;
1032 vstart_off += aux.vda_next;
1033 if (vstart > end || shdr->sh_size - sizeof (Elf_(Verdaux)) < vstart_off) {
1034 sdb_free (sdb_verdef);
1035 sdb_free (sdb_parent);
1036 goto out_error;
1037 }
1038 k = 0;
1039 aux.vda_name = READ32 (vstart, k);
1040 aux.vda_next = READ32 (vstart, k);
1041 if (aux.vda_name > bin->dynstr_size) {
1042 sdb_free (sdb_verdef);
1043 sdb_free (sdb_parent);
1044 goto out_error;
1045 }
1046 sdb_num_set (sdb_parent, "idx", isum, 0);
1047 sdb_num_set (sdb_parent, "parent", j, 0);
1048 sdb_set (sdb_parent, "vda_name", &bin->dynstr[aux.vda_name], 0);
1049 snprintf (key, sizeof (key), "parent%d", j - 1);
1050 sdb_ns_set (sdb_verdef, key, sdb_parent);
1051 }
1052
1053 snprintf (key, sizeof (key), "verdef%u", cnt);
1054 sdb_ns_set (sdb, key, sdb_verdef);
1055 if (!verdef->vd_next || shdr->sh_size - i < verdef->vd_next) {
1056 sdb_free (sdb_verdef);
1057 goto out_error;
1058 }
1059 if ((st32)verdef->vd_next < 1) {
1060 bprintf ("Invalid vd_next in the ELF version\n");
1061 break;
1062 }
1063 i += verdef->vd_next;
1064 }
1065 free (defs);
1066 return sdb;
1067 out_error:
1068 free (defs);
1069 sdb_free (sdb);
1070 return NULL;
1071 }
1072
1073 static Sdb *store_versioninfo_gnu_verneed(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
1074 ut8 *end, *need = NULL;
1075 const char *section_name = "";
1076 Elf_(Shdr) *link_shdr = NULL;
1077 const char *link_section_name = "";
1078 Sdb *sdb_vernaux = NULL;
1079 Sdb *sdb_version = NULL;
1080 Sdb *sdb = NULL;
1081 ut64 i;
1082 int cnt;
1083
1084 if (!bin || !bin->dynstr) {
1085 return NULL;
1086 }
1087 if (shdr->sh_link >= bin->ehdr.e_shnum) {
1088 return NULL;
1089 }
1090 #ifdef R_BIN_ELF64
1091 if ((int)shdr->sh_size < 1 || shdr->sh_size > SIZE_MAX) {
1092 #else
1093 if ((int)shdr->sh_size < 1) {
1094 #endif
1095 return NULL;
1096 }
1097 sdb = sdb_new0 ();
1098 if (!sdb) {
1099 return NULL;
1100 }
1101 link_shdr = &bin->shdr[shdr->sh_link];
1102 if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
1103 section_name = &bin->shstrtab[shdr->sh_name];
1104 }
1105 if (bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
1106 link_section_name = &bin->shstrtab[link_shdr->sh_name];
1107 }
1108 if (!(need = (ut8*) calloc (R_MAX (1, shdr->sh_size), sizeof (ut8)))) {
1109 bprintf ("Cannot allocate memory for Elf_(Verneed)\n");
1110 goto beach;
1111 }
1112 end = need + shdr->sh_size;
1113 sdb_set (sdb, "section_name", section_name, 0);
1114 sdb_num_set (sdb, "num_entries", shdr->sh_info, 0);
1115 sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
1116 sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
1117 sdb_num_set (sdb, "link", shdr->sh_link, 0);
1118 sdb_set (sdb, "link_section_name", link_section_name, 0);
1119
1120 if (shdr->sh_offset > bin->size || shdr->sh_offset + shdr->sh_size > bin->size) {
1121 goto beach;
1122 }
1123 if (shdr->sh_offset + shdr->sh_size < shdr->sh_size) {
1124 goto beach;
1125 }
1126 i = r_buf_read_at (bin->b, shdr->sh_offset, need, shdr->sh_size);
1127 if (i < 1) {
1128 goto beach;
1129 }
1130 //XXX we should use DT_VERNEEDNUM instead of sh_info
1131 //TODO https://sourceware.org/ml/binutils/2014-11/msg00353.html
1132 for (i = 0, cnt = 0; cnt < shdr->sh_info; cnt++) {
1133 int j, isum;
1134 ut8 *vstart = need + i;
1135 Elf_(Verneed) vvn = { 0 };
1136 if (vstart + sizeof (Elf_(Verneed)) > end) {
1137 goto beach;
1138 }
1139 Elf_(Verneed) *entry = &vvn;
1140 char key[32] = { 0 };
1141 sdb_version = sdb_new0 ();
1142 if (!sdb_version) {
1143 goto beach;
1144 }
1145 j = 0;
1146 vvn.vn_version = READ16 (vstart, j);
1147 vvn.vn_cnt = READ16 (vstart, j);
1148 vvn.vn_file = READ32 (vstart, j);
1149 vvn.vn_aux = READ32 (vstart, j);
1150 vvn.vn_next = READ32 (vstart, j);
1151
1152 sdb_num_set (sdb_version, "vn_version", entry->vn_version, 0);
1153 sdb_num_set (sdb_version, "idx", i, 0);
1154 if (entry->vn_file > bin->dynstr_size) {
1155 goto beach;
1156 }
1157 {
1158 char *s = r_str_ndup (&bin->dynstr[entry->vn_file], 16);
1159 sdb_set (sdb_version, "file_name", s, 0);
1160 free (s);
1161 }
1162 sdb_num_set (sdb_version, "cnt", entry->vn_cnt, 0);
1163 st32 vnaux = entry->vn_aux;
1164 if (vnaux < 1) {
1165 goto beach;
1166 }
1167 vstart += vnaux;
1168 ut32 vn_cnt = entry->vn_cnt;
1169 for (j = 0, isum = i + entry->vn_aux; j < vn_cnt && vstart + sizeof (Elf_(Vernaux)) <= end; j++) {
1170 int k;
1171 Elf_(Vernaux) *aux = NULL;
1172 Elf_(Vernaux) vaux = {0};
1173 aux = (Elf_(Vernaux)*)&vaux;
1174 k = 0;
1175 vaux.vna_hash = READ32 (vstart, k);
1176 vaux.vna_flags = READ16 (vstart, k);
1177 vaux.vna_other = READ16 (vstart, k);
1178 vaux.vna_name = READ32 (vstart, k);
1179 vaux.vna_next = READ32 (vstart, k);
1180 if (aux->vna_name > bin->dynstr_size) {
1181 goto beach;
1182 }
1183 #if 1
1184 sdb_vernaux = sdb_new0 ();
1185 if (!sdb_vernaux) {
1186 goto beach;
1187 }
1188 sdb_num_set (sdb_vernaux, "idx", isum, 0);
1189 if (aux->vna_name > 0 && aux->vna_name + 8 < bin->dynstr_size) {
1190 char name [16];
1191 strncpy (name, &bin->dynstr[aux->vna_name], sizeof (name)-1);
1192 name[sizeof(name)-1] = 0;
1193 sdb_set (sdb_vernaux, "name", name, 0);
1194 }
1195 sdb_set (sdb_vernaux, "flags", get_ver_flags (aux->vna_flags), 0);
1196 sdb_num_set (sdb_vernaux, "version", aux->vna_other, 0);
1197 isum += aux->vna_next;
1198 vstart += aux->vna_next;
1199 snprintf (key, sizeof (key), "vernaux%d", j);
1200 sdb_ns_set (sdb_version, key, sdb_vernaux);
1201 #else
1202 char *key = r_str_newf ("vernaux%d", j);
1203 char *val = r_str_newf ("%d,%s", isum, get_ver_flags (aux->vna_flags));
1204 sdb_set (sdb_version, key, val, 0);
1205 free (key);
1206 free (val);
1207 #endif
1208 }
1209 if ((int)entry->vn_next < 0) {
1210 bprintf ("Invalid vn_next\n");
1211 break;
1212 }
1213 i += entry->vn_next;
1214 snprintf (key, sizeof (key), "version%d", cnt );
1215 sdb_ns_set (sdb, key, sdb_version);
1216 //if entry->vn_next is 0 it iterate infinitely
1217 if (!entry->vn_next) {
1218 break;
1219 }
1220 }
1221 free (need);
1222 return sdb;
1223 beach:
1224 free (need);
1225 sdb_free (sdb_vernaux);
1226 sdb_free (sdb_version);
1227 sdb_free (sdb);
1228 return NULL;
1229 }
1230
1231 static Sdb *store_versioninfo(ELFOBJ *bin) {
1232 Sdb *sdb_versioninfo = NULL;
1233 int num_verdef = 0;
1234 int num_verneed = 0;
1235 int num_versym = 0;
1236 size_t i;
1237
1238 if (!bin || !bin->shdr) {
1239 return NULL;
1240 }
1241 if (!(sdb_versioninfo = sdb_new0 ())) {
1242 return NULL;
1243 }
1244
1245 for (i = 0; i < bin->ehdr.e_shnum; i++) {
1246 Sdb *sdb = NULL;
1247 char key[32] = {0};
1248 int size = bin->shdr[i].sh_size;
1249
1250 if (size - (i * sizeof (Elf_(Shdr)) > bin->size)) {
1251 size = bin->size - (i*sizeof(Elf_(Shdr)));
1252 }
1253 int left = size - (i * sizeof (Elf_(Shdr)));
1254 left = R_MIN (left, bin->shdr[i].sh_size);
1255 if (left < 0) {
1256 break;
1257 }
1258 switch (bin->shdr[i].sh_type) {
1259 case SHT_GNU_verdef:
1260 sdb = store_versioninfo_gnu_verdef (bin, &bin->shdr[i], left);
1261 snprintf (key, sizeof (key), "verdef%d", num_verdef++);
1262 sdb_ns_set (sdb_versioninfo, key, sdb);
1263 break;
1264 case SHT_GNU_verneed:
1265 sdb = store_versioninfo_gnu_verneed (bin, &bin->shdr[i], left);
1266 snprintf (key, sizeof (key), "verneed%d", num_verneed++);
1267 sdb_ns_set (sdb_versioninfo, key, sdb);
1268 break;
1269 case SHT_GNU_versym:
1270 sdb = store_versioninfo_gnu_versym (bin, &bin->shdr[i], left);
1271 snprintf (key, sizeof (key), "versym%d", num_versym++);
1272 sdb_ns_set (sdb_versioninfo, key, sdb);
1273 break;
1274 }
1275 }
1276
1277 return sdb_versioninfo;
1278 }
1279
1280 static bool init_dynstr(ELFOBJ *bin) {
1281 int i, r;
1282 const char *section_name = NULL;
1283 if (!bin || !bin->shdr) {
1284 return false;
1285 }
1286 if (!bin->shstrtab) {
1287 return false;
1288 }
1289 for (i = 0; i < bin->ehdr.e_shnum; i++) {
1290 if (bin->shdr[i].sh_name > bin->shstrtab_size) {
1291 return false;
1292 }
1293 section_name = &bin->shstrtab[bin->shdr[i].sh_name];
1294 if (bin->shdr[i].sh_type == SHT_STRTAB && !strcmp (section_name, ".dynstr")) {
1295 if (!(bin->dynstr = (char*) calloc (bin->shdr[i].sh_size + 1, sizeof (char)))) {
1296 bprintf("Cannot allocate memory for dynamic strings\n");
1297 return false;
1298 }
1299 if (bin->shdr[i].sh_offset > bin->size) {
1300 return false;
1301 }
1302 if (bin->shdr[i].sh_offset + bin->shdr[i].sh_size > bin->size) {
1303 return false;
1304 }
1305 if (bin->shdr[i].sh_offset + bin->shdr[i].sh_size < bin->shdr[i].sh_size) {
1306 return false;
1307 }
1308 r = r_buf_read_at (bin->b, bin->shdr[i].sh_offset, (ut8*)bin->dynstr, bin->shdr[i].sh_size);
1309 if (r < 1) {
1310 R_FREE (bin->dynstr);
1311 bin->dynstr_size = 0;
1312 return false;
1313 }
1314 bin->dynstr_size = bin->shdr[i].sh_size;
1315 return true;
1316 }
1317 }
1318 return false;
1319 }
1320
1321 static HtUP *rel_cache_new(RBinElfReloc *relocs, ut32 reloc_num) {
1322 if (!relocs || reloc_num == 0) {
1323 return NULL;
1324 }
1325 const int htsize = R_MIN (reloc_num, 1024);
1326 HtUP *rel_cache = ht_up_new_size (htsize, NULL, NULL, NULL);
1327 if (rel_cache) {
1328 size_t i;
1329 for (i = 0; i < reloc_num; i++) {
1330 RBinElfReloc *tmp = relocs + i;
1331 ht_up_insert (rel_cache, tmp->sym, tmp);
1332 }
1333 }
1334 return rel_cache;
1335 }
1336
1337 static bool elf_init(ELFOBJ *bin) {
1338 /* bin is not an ELF */
1339 if (!init_ehdr (bin)) {
1340 return false;
1341 }
1342 if (!init_phdr (bin) && !is_bin_etrel (bin)) {
1343 bprintf ("Cannot initialize program headers\n");
1344 }
1345 if (bin->ehdr.e_type != ET_CORE) {
1346 if (!init_shdr (bin)) {
1347 bprintf ("Cannot initialize section headers\n");
1348 }
1349 if (!init_strtab (bin)) {
1350 bprintf ("Cannot initialize strings table\n");
1351 }
1352 if (!init_dynstr (bin) && !is_bin_etrel (bin)) {
1353 bprintf ("Cannot initialize dynamic strings\n");
1354 }
1355 bin->baddr = Elf_(r_bin_elf_get_baddr) (bin);
1356 if (!init_dynamic_section (bin) && !Elf_(r_bin_elf_is_static) (bin) && !is_bin_etrel (bin)) {
1357 bprintf ("Cannot initialize dynamic section\n");
1358 }
1359 }
1360
1361 bin->imports_by_ord_size = 0;
1362 bin->imports_by_ord = NULL;
1363 bin->symbols_by_ord_size = 0;
1364 bin->symbols_by_ord = NULL;
1365 bin->g_sections = Elf_(r_bin_elf_get_sections) (bin);
1366 bin->boffset = Elf_(r_bin_elf_get_boffset) (bin);
1367 bin->g_relocs = Elf_(r_bin_elf_get_relocs) (bin);
1368 bin->rel_cache = rel_cache_new (bin->g_relocs, bin->g_reloc_num);
1369 sdb_ns_set (bin->kv, "versioninfo", store_versioninfo (bin));
1370 return true;
1371 }
1372
1373 ut64 Elf_(r_bin_elf_get_section_offset)(ELFOBJ *bin, const char *section_name) {
1374 RBinElfSection *section = get_section_by_name (bin, section_name);
1375 return section? section->offset: UT64_MAX;
1376 }
1377
1378 ut64 Elf_(r_bin_elf_get_section_addr)(ELFOBJ *bin, const char *section_name) {
1379 RBinElfSection *section = get_section_by_name (bin, section_name);
1380 return section? section->rva: UT64_MAX;
1381 }
1382
1383 ut64 Elf_(r_bin_elf_get_section_addr_end)(ELFOBJ *bin, const char *section_name) {
1384 RBinElfSection *section = get_section_by_name (bin, section_name);
1385 return section? section->rva + section->size: UT64_MAX;
1386 }
1387
1388 static ut64 get_got_entry(ELFOBJ *bin, RBinElfReloc *rel) {
1389 if (!rel->rva) {
1390 return UT64_MAX;
1391 }
1392
1393 ut64 p_sym_got_addr = Elf_(r_bin_elf_v2p_new) (bin, rel->rva);
1394 ut64 addr = R_BIN_ELF_BREADWORD (bin->b, p_sym_got_addr);
1395
1396 return (!addr || addr == R_BIN_ELF_WORD_MAX) ? UT64_MAX : addr;
1397 }
1398
1399 static bool is_thumb_symbol(ut64 plt_addr) {
1400 return plt_addr & 1;
1401 }
1402
1403 static ut64 get_import_addr_arm(ELFOBJ *bin, RBinElfReloc *rel) {
1404 ut64 got_addr = bin->dyn_info.dt_pltgot;
1405 if (got_addr == R_BIN_ELF_ADDR_MAX) {
1406 return UT64_MAX;
1407 }
1408
1409 ut64 plt_addr = get_got_entry (bin, rel);
1410 if (plt_addr == UT64_MAX) {
1411 return UT64_MAX;
1412 }
1413
1414 ut64 pos = COMPUTE_PLTGOT_POSITION (rel, got_addr, 0x3);
1415
1416 switch (rel->type) {
1417 case R_ARM_JUMP_SLOT:
1418 plt_addr += pos * 12 + 20;
1419 if (is_thumb_symbol (plt_addr)) {
1420 plt_addr--;
1421 }
1422 return plt_addr;
1423 case R_AARCH64_RELATIVE:
1424 eprintf ("Unsupported relocation type for imports %d\n", rel->type);
1425 return UT64_MAX;
1426 case R_AARCH64_IRELATIVE:
1427 if (rel->addend > plt_addr) { // start
1428 return (plt_addr + pos * 16 + 32) + rel->addend;
1429 }
1430 // same as fallback to JUMP_SLOT
1431 return plt_addr + pos * 16 + 32;
1432 case R_AARCH64_JUMP_SLOT:
1433 return plt_addr + pos * 16 + 32;
1434 default:
1435 bprintf ("Unsupported relocation type for imports %d\n", rel->type);
1436 return UT64_MAX;
1437 }
1438 return UT64_MAX;
1439 }
1440
1441 static ut64 get_import_addr_mips(ELFOBJ *bin, RBinElfReloc *rel) {
1442 ut64 jmprel_addr = bin->dyn_info.dt_jmprel;
1443 ut64 got_addr = bin->dyn_info.dt_mips_pltgot;
1444
1445 if (jmprel_addr == R_BIN_ELF_ADDR_MAX || got_addr == R_BIN_ELF_ADDR_MAX) {
1446 return UT64_MAX;
1447 }
1448
1449 ut64 pos = COMPUTE_PLTGOT_POSITION(rel, got_addr, 0x2);
1450
1451 ut8 buf[1024];
1452 ut64 plt_addr = jmprel_addr + bin->dyn_info.dt_pltrelsz;
1453 ut64 p_plt_addr = Elf_(r_bin_elf_v2p_new) (bin, plt_addr);
1454 int res = r_buf_read_at (bin->b, p_plt_addr, buf, sizeof (buf));
1455 if (res != sizeof (buf)) {
1456 return UT64_MAX;
1457 }
1458
1459 const ut8 *base = r_mem_mem_aligned (buf, sizeof (buf), (const ut8 *)"\x3c\x0f\x00", 3, 4);
1460 plt_addr += base? (int)(size_t) (base - buf): MIPS_PLT_OFFSET + 8; // HARDCODED HACK
1461 plt_addr += pos * 16;
1462
1463 return plt_addr;
1464 }
1465
1466 static size_t get_size_rel_mode(Elf_(Xword) rel_mode) {
1467 return rel_mode == DT_RELA? sizeof (Elf_(Rela)): sizeof (Elf_(Rel));
1468 }
1469
1470 static ut64 get_num_relocs_dynamic_plt(ELFOBJ *bin) {
1471 if (bin->dyn_info.dt_pltrelsz) {
1472 const ut64 size = bin->dyn_info.dt_pltrelsz;
1473 const ut64 relsize = get_size_rel_mode (bin->dyn_info.dt_pltrel);
1474 return size / relsize;
1475 }
1476 return 0;
1477 }
1478
1479 static ut64 get_import_addr_riscv(ELFOBJ *bin, RBinElfReloc *rel) {
1480 ut64 got_addr = bin->dyn_info.dt_pltgot;
1481 if (got_addr == R_BIN_ELF_ADDR_MAX) {
1482 return UT64_MAX;
1483 }
1484
1485 ut64 plt_addr = get_got_entry (bin, rel);
1486 if (plt_addr == UT64_MAX) {
1487 return UT64_MAX;
1488 }
1489
1490 ut64 pos = COMPUTE_PLTGOT_POSITION(rel, got_addr, 0x2);
1491 return plt_addr + RISCV_PLT_OFFSET + pos * RISCV_PLT_ENTRY_SIZE;
1492 }
1493
1494 static ut64 get_import_addr_sparc(ELFOBJ *bin, RBinElfReloc *rel) {
1495 if (rel->type != R_SPARC_JMP_SLOT) {
1496 bprintf ("Unknown sparc reloc type %d\n", rel->type);
1497 return UT64_MAX;
1498 }
1499 ut64 tmp = get_got_entry (bin, rel);
1500
1501 return (tmp == UT64_MAX) ? UT64_MAX : tmp + SPARC_OFFSET_PLT_ENTRY_FROM_GOT_ADDR;
1502 }
1503
1504 static ut64 get_import_addr_ppc(ELFOBJ *bin, RBinElfReloc *rel) {
1505 ut64 plt_addr = bin->dyn_info.dt_pltgot;
1506 if (plt_addr == R_BIN_ELF_ADDR_MAX) {
1507 return UT64_MAX;
1508 }
1509 ut64 p_plt_addr = Elf_(r_bin_elf_v2p_new) (bin, plt_addr);
1510 if (p_plt_addr == UT64_MAX) {
1511 return UT64_MAX;
1512 }
1513
1514 ut64 base = r_buf_read_ble32_at (bin->b, p_plt_addr, bin->endian);
1515 if (base == UT32_MAX) {
1516 return UT64_MAX;
1517 }
1518
1519 ut64 nrel = get_num_relocs_dynamic_plt (bin);
1520 ut64 pos = COMPUTE_PLTGOT_POSITION(rel, plt_addr, 0x0);
1521
1522 if (bin->endian) {
1523 base -= (nrel * 16);
1524 base += (pos * 16);
1525 return base;
1526 }
1527
1528 base -= (nrel * 12) + 20;
1529 base += (pos * 8);
1530 return base;
1531 }
1532
1533 static ut64 get_import_addr_x86_manual(ELFOBJ *bin, RBinElfReloc *rel) {
1534 ut64 got_addr = bin->dyn_info.dt_pltgot;
1535 if (got_addr == R_BIN_ELF_ADDR_MAX) {
1536 return UT64_MAX;
1537 }
1538
1539 ut64 got_offset = Elf_(r_bin_elf_v2p_new) (bin, got_addr);
1540 if (got_offset == UT64_MAX) {
1541 return UT64_MAX;
1542 }
1543
1544 //XXX HACK ALERT!!!! full relro?? try to fix it
1545 //will there always be .plt.got, what would happen if is .got.plt?
1546 RBinElfSection *s = get_section_by_name (bin, ".plt.got");
1547 if (Elf_(r_bin_elf_has_relro) (bin) < R_ELF_PART_RELRO || !s) {
1548 return UT64_MAX;
1549 }
1550
1551 ut8 buf[sizeof (Elf_(Addr))] = { 0 };
1552
1553 ut64 plt_addr = s->offset;
1554 ut64 plt_sym_addr;
1555
1556 while (plt_addr + 2 + 4 < s->offset + s->size) {
1557 /*we try to locate the plt entry that correspond with the relocation
1558 since got does not point back to .plt. In this case it has the following
1559 form
1560 ff253a152000 JMP QWORD [RIP + 0x20153A]
1561 6690 NOP
1562 ----
1563 ff25ec9f0408 JMP DWORD [reloc.puts_236]
1564 plt_addr + 2 to remove jmp opcode and get the imm reading 4
1565 and if RIP (plt_addr + 6) + imm == rel->offset
1566 return plt_addr, that will be our sym addr
1567 perhaps this hack doesn't work on 32 bits
1568 */
1569 int res = r_buf_read_at (bin->b, plt_addr + 2, buf, sizeof (ut32));
1570 if (res < 0) {
1571 return UT64_MAX;
1572 }
1573
1574 size_t i = 0;
1575 plt_sym_addr = R_BIN_ELF_READWORD (buf, i);
1576
1577 //relative address
1578 if ((plt_addr + 6 + Elf_(r_bin_elf_v2p) (bin, plt_sym_addr)) == rel->rva) {
1579 return plt_addr;
1580 }
1581 if (plt_sym_addr == rel->rva) {
1582 return plt_addr;
1583 }
1584 plt_addr += 8;
1585 }
1586
1587 return UT64_MAX;
1588 }
1589
1590 static ut64 get_import_addr_x86(ELFOBJ *bin, RBinElfReloc *rel) {
1591 ut64 tmp = get_got_entry (bin, rel);
1592 if (tmp == UT64_MAX) {
1593 return get_import_addr_x86_manual (bin, rel);
1594 }
1595
1596 RBinElfSection *pltsec_section = get_section_by_name (bin, ".plt.sec");
1597 if (pltsec_section) {
1598 ut64 got_addr = bin->dyn_info.dt_pltgot;
1599 ut64 pos = COMPUTE_PLTGOT_POSITION (rel, got_addr, 0x3);
1600 return pltsec_section->rva + pos * X86_PLT_ENTRY_SIZE;
1601 }
1602
1603 return tmp + X86_OFFSET_PLT_ENTRY_FROM_GOT_ADDR;
1604 }
1605
1606 static ut64 get_import_addr(ELFOBJ *bin, int sym) {
1607 if ((!bin->shdr || !bin->strtab) && !bin->phdr) {
1608 return UT64_MAX;
1609 }
1610
1611 if (!bin->rel_cache) {
1612 return UT64_MAX;
1613 }
1614
1615 // lookup the right rel/rela entry
1616 RBinElfReloc *rel = ht_up_find (bin->rel_cache, sym, NULL);
1617 if (!rel) {
1618 return UT64_MAX;
1619 }
1620
1621 switch (bin->ehdr.e_machine) {
1622 case EM_ARM:
1623 case EM_AARCH64:
1624 return get_import_addr_arm (bin, rel);
1625 case EM_MIPS: // MIPS32 BIG ENDIAN relocs
1626 return get_import_addr_mips (bin, rel);
1627 case EM_RISCV:
1628 return get_import_addr_riscv (bin, rel);
1629 case EM_SPARC:
1630 case EM_SPARCV9:
1631 case EM_SPARC32PLUS:
1632 return get_import_addr_sparc (bin, rel);
1633 case EM_PPC:
1634 case EM_PPC64:
1635 return get_import_addr_ppc (bin, rel);
1636 case EM_386:
1637 case EM_X86_64:
1638 return get_import_addr_x86 (bin, rel);
1639 default:
1640 eprintf ("Unsupported relocs type %" PFMT64u " for arch %d\n",
1641 (ut64) rel->type, bin->ehdr.e_machine);
1642 return UT64_MAX;
1643 }
1644 }
1645
1646 int Elf_(r_bin_elf_has_nx)(ELFOBJ *bin) {
1647 r_return_val_if_fail (bin, 0);
1648 int i;
1649 if (bin && bin->phdr) {
1650 for (i = 0; i < bin->ehdr.e_phnum; i++) {
1651 if (bin->phdr[i].p_type == PT_GNU_STACK) {
1652 return (!(bin->phdr[i].p_flags & 1))? 1: 0;
1653 }
1654 }
1655 }
1656 return 0;
1657 }
1658
1659 int Elf_(r_bin_elf_has_relro)(ELFOBJ *bin) {
1660 r_return_val_if_fail (bin, R_ELF_NO_RELRO);
1661 bool haveBindNow = false;
1662 bool haveGnuRelro = false;
1663
1664 if (bin->dyn_info.dt_bind_now) {
1665 haveBindNow = true;
1666 } else if (bin->dyn_info.dt_flags != R_BIN_ELF_XWORD_MAX && bin->dyn_info.dt_flags != R_BIN_ELF_XWORD_MAX) {
1667 haveBindNow = bin->dyn_info.dt_flags_1 & DF_1_NOW;
1668 }
1669
1670 if (bin->phdr) {
1671 size_t i;
1672 for (i = 0; i < bin->ehdr.e_phnum; i++) {
1673 if (bin->phdr[i].p_type == PT_GNU_RELRO) {
1674 haveGnuRelro = true;
1675 break;
1676 }
1677 }
1678 }
1679 if (haveGnuRelro) {
1680 if (haveBindNow) {
1681 return R_ELF_FULL_RELRO;
1682 }
1683 return R_ELF_PART_RELRO;
1684 }
1685 return R_ELF_NO_RELRO;
1686 }
1687
1688 /*
1689 To compute the base address, one determines the memory
1690 address associated with the lowest p_vaddr value for a
1691 PT_LOAD segment. One then obtains the base address by
1692 truncating the memory address to the nearest multiple
1693 of the maximum page size
1694 */
1695
1696 ut64 Elf_(r_bin_elf_get_baddr)(ELFOBJ *bin) {
1697 ut64 tmp, base = UT64_MAX;
1698 if (!bin) {
1699 return 0;
1700 }
1701 if (bin->phdr) {
1702 size_t i;
1703 for (i = 0; i < bin->ehdr.e_phnum; i++) {
1704 if (bin->phdr[i].p_type == PT_LOAD) {
1705 tmp = (ut64)bin->phdr[i].p_vaddr & ELF_PAGE_MASK;
1706 tmp = tmp - (tmp % (1 << ELF_PAGE_SIZE));
1707 if (tmp < base) {
1708 base = tmp;
1709 }
1710 }
1711 }
1712 }
1713 if (base == UT64_MAX && is_bin_etrel (bin)) {
1714 //we return our own base address for ET_REL type
1715 //we act as a loader for ELF
1716 return 0x08000000;
1717 }
1718 return base == UT64_MAX? 0: base;
1719 }
1720
1721 ut64 Elf_(r_bin_elf_get_boffset)(ELFOBJ *bin) {
1722 ut64 tmp, base = UT64_MAX;
1723 r_return_val_if_fail (bin, 0);
1724
1725 if (!bin->phdr) {
1726 return 0;
1727 }
1728
1729 size_t i;
1730 for (i = 0; i < bin->ehdr.e_phnum; i++) {
1731 if (bin->phdr[i].p_type == PT_LOAD) {
1732 tmp = (ut64)bin->phdr[i].p_offset & ELF_PAGE_MASK;
1733 tmp = tmp - (tmp % (1 << ELF_PAGE_SIZE));
1734 if (tmp < base) {
1735 base = tmp;
1736 }
1737 }
1738 }
1739 return base == UT64_MAX? 0: base;
1740 }
1741
1742 ut64 Elf_(r_bin_elf_get_init_offset)(ELFOBJ *bin) {
1743 ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1744 ut8 buf[128];
1745 if (!bin || entry == UT64_MAX) {
1746 return UT64_MAX;
1747 }
1748 if (r_buf_read_at (bin->b, entry + 16, buf, sizeof (buf)) < 1) {
1749 bprintf ("read (init_offset)\n");
1750 return 0;
1751 }
1752 if (buf[0] == 0x68) { // push // x86 only
1753 ut64 addr;
1754 memmove (buf, buf + 1, 4);
1755 addr = (ut64)r_read_le32 (buf);
1756 return Elf_(r_bin_elf_v2p) (bin, addr);
1757 }
1758 return 0;
1759 }
1760
1761 ut64 Elf_(r_bin_elf_get_fini_offset)(ELFOBJ *bin) {
1762 r_return_val_if_fail (bin, UT64_MAX);
1763 ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1764 if (entry == UT64_MAX) {
1765 return UT64_MAX;
1766 }
1767 ut8 buf[512];
1768 if (r_buf_read_at (bin->b, entry + 11, buf, sizeof (buf)) == -1) {
1769 bprintf ("read (get_fini)\n");
1770 return 0;
1771 }
1772 if (*buf == 0x68) { // push // x86/32 only
1773 memmove (buf, buf + 1, 4);
1774 ut64 addr = (ut64)r_read_le32 (buf);
1775 return Elf_(r_bin_elf_v2p) (bin, addr);
1776 }
1777 return 0;
1778 }
1779
1780 ut64 Elf_(r_bin_elf_get_entry_offset)(ELFOBJ *bin) {
1781 r_return_val_if_fail (bin, UT64_MAX);
1782 ut64 entry = bin->ehdr.e_entry;
1783 if (!entry) {
1784 if (!Elf_(r_bin_elf_is_executable) (bin)) {
1785 return UT64_MAX;
1786 }
1787 entry = Elf_(r_bin_elf_get_section_offset)(bin, ".init.text");
1788 if (entry != UT64_MAX) {
1789 return entry;
1790 }
1791 entry = Elf_(r_bin_elf_get_section_offset)(bin, ".text");
1792 if (entry != UT64_MAX) {
1793 return entry;
1794 }
1795 return Elf_(r_bin_elf_get_section_offset)(bin, ".init");
1796 }
1797 return Elf_(r_bin_elf_v2p) (bin, entry);
1798 }
1799
1800 static ut64 getmainsymbol(ELFOBJ *bin) {
1801 struct r_bin_elf_symbol_t *symbol = Elf_(r_bin_elf_get_symbols) (bin);
1802 if (symbol) {
1803 size_t i;
1804 for (i = 0; !symbol[i].last; i++) {
1805 if (!strcmp (symbol[i].name, "main")) {
1806 return symbol[i].offset;
1807 }
1808 }
1809 }
1810 return UT64_MAX;
1811 }
1812
1813 ut64 Elf_(r_bin_elf_get_main_offset)(ELFOBJ *bin) {
1814 r_return_val_if_fail (bin, UT64_MAX);
1815 ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1816 if (entry == UT64_MAX) {
1817 return UT64_MAX;
1818 }
1819 ut8 buf[256];
1820 if (entry > bin->size || (entry + sizeof (buf)) > bin->size) {
1821 return UT64_MAX;
1822 }
1823 // unnecessary to read 512 bytes imho
1824 if (r_buf_read_at (bin->b, entry, buf, sizeof (buf)) < 1) {
1825 bprintf ("read (main)\n");
1826 return UT64_MAX;
1827 }
1828 // ARM64
1829 if (buf[0x18+3] == 0x58 && buf[0x2f] == 0x00) {
1830 ut32 entry_vaddr = Elf_(r_bin_elf_p2v) (bin, entry);
1831 ut32 main_addr = r_read_le32 (&buf[0x30]);
1832 if ((main_addr >> 16) == (entry_vaddr >> 16)) {
1833 return Elf_(r_bin_elf_v2p) (bin, main_addr);
1834 }
1835 }
1836
1837 // TODO: Use arch to identify arch before memcmp's
1838
1839 // ARM Glibc
1840 if (entry & 1) {
1841 int delta = 0;
1842 /* thumb entry points */
1843 if (!memcmp (buf, "\xf0\x00\x0b\x4f\xf0\x00\x0e\x02\xbc\x6a\x46", 11)) {
1844 /* newer versions of gcc use push/pop */
1845 delta = 0x28;
1846 } else if (!memcmp (buf, "\xf0\x00\x0b\x4f\xf0\x00\x0e\x5d\xf8\x04\x1b", 11)) {
1847 /* older versions of gcc (4.5.x) use ldr/str */
1848 delta = 0x30;
1849 }
1850 if (delta) {
1851 ut64 pa = Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[delta-1]) & ~1);
1852 if (pa < r_buf_size (bin->b)) {
1853 return pa;
1854 }
1855 }
1856 } else {
1857 /* non-thumb entry points */
1858 if (!memcmp (buf, "\x00\xb0\xa0\xe3\x00\xe0\xa0\xe3", 8)) {
1859 return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0x34]) & ~1);
1860 }
1861 if (!memcmp (buf, "\x24\xc0\x9f\xe5\x00\xb0\xa0\xe3", 8)) {
1862 return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0x30]) & ~1);
1863 }
1864 }
1865
1866 // MIPS
1867 /* get .got, calculate offset of main symbol */
1868 if (!memcmp (buf, "\x21\x00\xe0\x03\x01\x00\x11\x04", 8)) {
1869
1870 /*
1871 assuming the startup code looks like
1872 got = gp-0x7ff0
1873 got[index__libc_start_main] ( got[index_main] );
1874
1875 looking for the instruction generating the first argument to find main
1876 lw a0, offset(gp)
1877 */
1878
1879 ut64 got_offset;
1880 if ((got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got")) != -1 ||
1881 (got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got.plt")) != -1)
1882 {
1883 const ut64 gp = got_offset + 0x7ff0;
1884 size_t i, len = sizeof (buf) / sizeof (buf[0]);
1885 for (i = 0; i < len; i += 4) {
1886 const ut32 instr = r_read_le32 (&buf[i]);
1887 if ((instr & 0xffff0000) == 0x8f840000) { // lw a0, offset(gp)
1888 const short delta = instr & 0x0000ffff;
1889 r_buf_read_at (bin->b, /* got_entry_offset = */ gp + delta, buf, 4);
1890 return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0]));
1891 }
1892 }
1893 }
1894
1895 return 0;
1896 }
1897 // X86-CGC
1898 if (buf[0] == 0xe8 && !memcmp (buf + 5, "\x50\xe8\x00\x00\x00\x00\xb8\x01\x00\x00\x00\x53", 12)) {
1899 size_t SIZEOF_CALL = 5;
1900 ut64 rel_addr = (ut64)((int)(buf[1] + (buf[2] << 8) + (buf[3] << 16) + (buf[4] << 24)));
1901 ut64 addr = Elf_(r_bin_elf_p2v)(bin, entry + SIZEOF_CALL);
1902 addr += rel_addr;
1903 return Elf_(r_bin_elf_v2p) (bin, addr);
1904 }
1905 // X86-PIE
1906 if (buf[0x00] == 0x48 && buf[0x1e] == 0x8d && buf[0x11] == 0xe8) {
1907 ut32 *pmain = (ut32*)(buf + 0x30);
1908 ut64 vmain = Elf_(r_bin_elf_p2v) (bin, (ut64)*pmain);
1909 ut64 ventry = Elf_(r_bin_elf_p2v) (bin, entry);
1910 if (vmain >> 16 == ventry >> 16) {
1911 return (ut64)vmain;
1912 }
1913 }
1914 // X86-PIE
1915 if (buf[0x1d] == 0x48 && buf[0x1e] == 0x8b) {
1916 if (!memcmp (buf, "\x31\xed\x49\x89", 4)) {// linux
1917 ut64 maddr, baddr;
1918 ut8 n32s[sizeof (ut32)] = {0};
1919 maddr = entry + 0x24 + r_read_le32 (buf + 0x20);
1920 if (r_buf_read_at (bin->b, maddr, n32s, sizeof (ut32)) == -1) {
1921 bprintf ("read (maddr) 2\n");
1922 return 0;
1923 }
1924 maddr = (ut64)r_read_le32 (&n32s[0]);
1925 baddr = (bin->ehdr.e_entry >> 16) << 16;
1926 if (bin->phdr) {
1927 baddr = Elf_(r_bin_elf_get_baddr) (bin);
1928 }
1929 maddr += baddr;
1930 return maddr;
1931 }
1932 }
1933 // X86-NONPIE
1934 #if R_BIN_ELF64
1935 if (!memcmp (buf, "\x49\x89\xd9", 3) && buf[156] == 0xe8) { // openbsd
1936 return r_read_le32 (&buf[157]) + entry + 156 + 5;
1937 }
1938 if (!memcmp (buf+29, "\x48\xc7\xc7", 3)) { // linux
1939 ut64 addr = (ut64)r_read_le32 (&buf[29 + 3]);
1940 return Elf_(r_bin_elf_v2p) (bin, addr);
1941 }
1942 #else
1943 if (buf[23] == '\x68') {
1944 ut64 addr = (ut64)r_read_le32 (&buf[23 + 1]);
1945 return Elf_(r_bin_elf_v2p) (bin, addr);
1946 }
1947 #endif
1948 /* linux64 pie main -- probably buggy in some cases */
1949 int bo = 29; // Begin offset may vary depending on the entry prelude
1950 // endbr64 - fedora bins have this
1951 if (buf[0] == 0xf3 && buf[1] == 0x0f && buf[2] == 0x1e && buf[3] == 0xfa) {
1952 // Change begin offset if binary starts with 'endbr64'
1953 bo = 33;
1954 }
1955 if (buf[bo] == 0x48) {
1956 ut8 ch = buf[bo + 1];
1957 if (ch == 0x8d) { // lea rdi, qword [rip-0x21c4]
1958 ut8 *p = buf + bo + 3;
1959 st32 maindelta = (st32)r_read_le32 (p);
1960 ut64 vmain = (ut64)(entry + bo + maindelta) + 7;
1961 ut64 ventry = Elf_(r_bin_elf_p2v) (bin, entry);
1962 if (vmain>>16 == ventry>>16) {
1963 return (ut64)vmain;
1964 }
1965 } else if (0xc7) { // mov rdi, 0xADDR
1966 ut8 *p = buf + bo + 3;
1967 return (ut64)(ut32)r_read_le32 (p);
1968 }
1969 }
1970
1971 /* find sym.main if possible */
1972 {
1973 ut64 m = getmainsymbol (bin);
1974 if (m != UT64_MAX) {
1975 return m;
1976 }
1977 }
1978 return UT64_MAX;
1979 }
1980
1981 bool Elf_(r_bin_elf_get_stripped)(ELFOBJ *bin) {
1982 if (!bin->shdr) {
1983 return false;
1984 }
1985 size_t i;
1986 for (i = 0; i < bin->ehdr.e_shnum; i++) {
1987 if (bin->shdr[i].sh_type == SHT_SYMTAB) {
1988 return false;
1989 }
1990 }
1991 return true;
1992 }
1993
1994 char *Elf_(r_bin_elf_intrp)(ELFOBJ *bin) {
1995 int i;
1996 if (!bin || !bin->phdr) {
1997 return NULL;
1998 }
1999 for (i = 0; i < bin->ehdr.e_phnum; i++) {
2000 if (bin->phdr[i].p_type == PT_INTERP) {
2001 ut64 addr = bin->phdr[i].p_offset;
2002 int sz = bin->phdr[i].p_filesz;
2003 sdb_num_set (bin->kv, "elf_header.intrp_addr", addr, 0);
2004 sdb_num_set (bin->kv, "elf_header.intrp_size", sz, 0);
2005 if (sz < 1 || sz > r_buf_size (bin->b)) {
2006 return NULL;
2007 }
2008 char *str = malloc (sz + 1);
2009 if (!str) {
2010 return NULL;
2011 }
2012 if (r_buf_read_at (bin->b, addr, (ut8*)str, sz) < 1) {
2013 bprintf ("read (main)\n");
2014 free (str);
2015 return 0;
2016 }
2017 str[sz] = 0;
2018 sdb_set (bin->kv, "elf_header.intrp", str, 0);
2019 return str;
2020 }
2021 }
2022 return NULL;
2023 }
2024
2025 bool Elf_(r_bin_elf_is_static)(ELFOBJ *bin) {
2026 size_t i;
2027 if (!bin->phdr) {
2028 return false;
2029 }
2030 for (i = 0; i < bin->ehdr.e_phnum; i++) {
2031 if (bin->phdr[i].p_type == PT_INTERP ||
2032 bin->phdr[i].p_type == PT_DYNAMIC) {
2033 return false;
2034 }
2035 }
2036 return true;
2037 }
2038
2039 char* Elf_(r_bin_elf_get_data_encoding)(ELFOBJ *bin) {
2040 switch (bin->ehdr.e_ident[EI_DATA]) {
2041 case ELFDATANONE: return strdup ("none");
2042 case ELFDATA2LSB: return strdup ("2's complement, little endian");
2043 case ELFDATA2MSB: return strdup ("2's complement, big endian");
2044 default: return r_str_newf ("<unknown: %x>", bin->ehdr.e_ident[EI_DATA]);
2045 }
2046 }
2047
2048 int Elf_(r_bin_elf_has_va)(ELFOBJ *bin) {
2049 return true;
2050 }
2051
2052 char* Elf_(r_bin_elf_get_arch)(ELFOBJ *bin) {
2053 switch (bin->ehdr.e_machine) {
2054 case EM_ARC:
2055 case EM_ARC_A5:
2056 return strdup ("arc");
2057 case EM_AVR: return strdup ("avr");
2058 case EM_BA2_NON_STANDARD:
2059 case EM_BA2: return strdup ("ba2");
2060 case EM_CRIS: return strdup ("cris");
2061 case EM_68K: return strdup ("m68k");
2062 case EM_MIPS:
2063 case EM_MIPS_RS3_LE:
2064 case EM_MIPS_X:
2065 return strdup ("mips");
2066 case EM_MCST_ELBRUS:
2067 return strdup ("elbrus");
2068 case EM_TRICORE:
2069 return strdup ("tricore");
2070 case EM_RCE:
2071 return strdup ("mcore");
2072 case EM_ARM:
2073 case EM_AARCH64:
2074 return strdup ("arm");
2075 case EM_QDSP6: // EM_HEXAGON
2076 return strdup ("hexagon");
2077 case EM_BLACKFIN:
2078 return strdup ("blackfin");
2079 case EM_SPARC:
2080 case EM_SPARC32PLUS:
2081 case EM_SPARCV9:
2082 return strdup ("sparc");
2083 case EM_PPC:
2084 case EM_PPC64:
2085 return strdup ("ppc");
2086 case EM_PARISC:
2087 return strdup ("hppa");
2088 case EM_PROPELLER:
2089 return strdup ("propeller");
2090 case EM_MICROBLAZE:
2091 return strdup ("microblaze.gnu");
2092 case EM_RISCV:
2093 return strdup ("riscv");
2094 case EM_VAX:
2095 return strdup ("vax");
2096 case EM_XTENSA:
2097 return strdup ("xtensa");
2098 case EM_LANAI:
2099 return strdup ("lanai");
2100 case EM_VIDEOCORE3:
2101 case EM_VIDEOCORE4:
2102 return strdup ("vc4");
2103 case EM_MSP430:
2104 return strdup ("msp430");
2105 case EM_SH:
2106 return strdup ("sh");
2107 case EM_V800:
2108 return strdup ("v850");
2109 case EM_V850:
2110 return strdup ("v850");
2111 case EM_IA_64:
2112 return strdup ("ia64");
2113 case EM_S390:
2114 return strdup ("sysz");
2115 default: return strdup ("x86");
2116 }
2117 }
2118 char* Elf_(r_bin_elf_get_abi)(ELFOBJ *bin) {
2119 Elf_(Ehdr)* ehdr = (Elf_(Ehdr) *) &bin->ehdr;
2120
2121 if (ehdr->e_machine == EM_MIPS) {
2122 if (is_elfclass64 (ehdr)) {
2123 return strdup ("n64");
2124 }
2125 if (is_mips_n32 (ehdr)) {
2126 return strdup ("n32");
2127 }
2128 if (is_mips_o32 (ehdr)) {
2129 return strdup ("o32");
2130 }
2131 }
2132 return NULL;
2133 }
2134
2135 char* Elf_(r_bin_elf_get_cpu)(ELFOBJ *bin) {
2136 if (bin->phdr && bin->ehdr.e_machine == EM_MIPS) {
2137 const ut32 mipsType = bin->ehdr.e_flags & EF_MIPS_ARCH;
2138 switch (mipsType) {
2139 case EF_MIPS_ARCH_1: return strdup ("mips1");
2140 case EF_MIPS_ARCH_2: return strdup ("mips2");
2141 case EF_MIPS_ARCH_3: return strdup ("mips3");
2142 case EF_MIPS_ARCH_4: return strdup ("mips4");
2143 case EF_MIPS_ARCH_5: return strdup ("mips5");
2144 case EF_MIPS_ARCH_32: return strdup ("mips32");
2145 case EF_MIPS_ARCH_64: return strdup ("mips64");
2146 case EF_MIPS_ARCH_32R2: return strdup ("mips32r2");
2147 case EF_MIPS_ARCH_64R2: return strdup ("mips64r2");
2148 default : return strdup (" Unknown mips ISA");
2149 }
2150 }
2151 return NULL;
2152 }
2153
2154 char* Elf_(r_bin_elf_get_head_flag)(ELFOBJ *bin) {
2155 char *head_flag = NULL;
2156 char *str = Elf_(r_bin_elf_get_cpu) (bin);
2157 if (str) {
2158 head_flag = r_str_append (head_flag, str);
2159 }
2160 str = Elf_(r_bin_elf_get_abi) (bin);
2161 if (str) {
2162 head_flag = r_str_appendf (head_flag, " %s", str);
2163 }
2164 if (R_STR_ISEMPTY (head_flag)) {
2165 head_flag = r_str_append (head_flag, "unknown_flag");
2166 }
2167 return head_flag;
2168 }
2169
2170 // http://www.sco.com/developers/gabi/latest/ch4.eheader.html
2171
2172 char* Elf_(r_bin_elf_get_machine_name)(ELFOBJ *bin) {
2173 switch (bin->ehdr.e_machine) {
2174 case EM_NONE: return strdup ("No machine");
2175 case EM_M32: return strdup ("AT&T WE 32100");
2176 case EM_SPARC: return strdup ("SUN SPARC");
2177 case EM_386: return strdup ("Intel 80386");
2178 case EM_68K: return strdup ("Motorola m68k family");
2179 case EM_88K: return strdup ("Motorola m88k family");
2180 case EM_860: return strdup ("Intel 80860");
2181 case EM_MIPS: return strdup ("MIPS R3000");
2182 case EM_S370: return strdup ("IBM System/370");
2183 case EM_MIPS_RS3_LE: return strdup ("MIPS R3000 little-endian");
2184 case EM_PARISC: return strdup ("HPPA");
2185 case EM_VPP500: return strdup ("Fujitsu VPP500");
2186 case EM_SPARC32PLUS: return strdup ("Sun's \"v8plus\"");
2187 case EM_960: return strdup ("Intel 80960");
2188 case EM_PPC: return strdup ("PowerPC");
2189 case EM_PPC64: return strdup ("PowerPC 64-bit");
2190 case EM_S390: return strdup ("IBM S390");
2191 case EM_V800: return strdup ("NEC V800 series");
2192 case EM_FR20: return strdup ("Fujitsu FR20");
2193 case EM_RH32: return strdup ("TRW RH-32");
2194 case EM_RCE: return strdup ("Motorola RCE");
2195 case EM_ARM: return strdup ("ARM");
2196 case EM_BLACKFIN: return strdup ("Analog Devices Blackfin");
2197 case EM_FAKE_ALPHA: return strdup ("Digital Alpha");
2198 case EM_SH: return strdup ("Hitachi SH");
2199 case EM_SPARCV9: return strdup ("SPARC v9 64-bit");
2200 case EM_TRICORE: return strdup ("Siemens Tricore");
2201 case EM_ARC: return strdup ("Argonaut RISC Core");
2202 case EM_H8_300: return strdup ("Hitachi H8/300");
2203 case EM_H8_300H: return strdup ("Hitachi H8/300H");
2204 case EM_H8S: return strdup ("Hitachi H8S");
2205 case EM_H8_500: return strdup ("Hitachi H8/500");
2206 case EM_IA_64: return strdup ("Intel Merced");
2207 case EM_MIPS_X: return strdup ("Stanford MIPS-X");
2208 case EM_COLDFIRE: return strdup ("Motorola Coldfire");
2209 case EM_68HC12: return strdup ("Motorola M68HC12");
2210 case EM_MMA: return strdup ("Fujitsu MMA Multimedia Accelerator");
2211 case EM_PCP: return strdup ("Siemens PCP");
2212 case EM_NCPU: return strdup ("Sony nCPU embeeded RISC");
2213 case EM_NDR1: return strdup ("Denso NDR1 microprocessor");
2214 case EM_STARCORE: return strdup ("Motorola Start*Core processor");
2215 case EM_ME16: return strdup ("Toyota ME16 processor");
2216 case EM_ST100: return strdup ("STMicroelectronic ST100 processor");
2217 case EM_TINYJ: return strdup ("Advanced Logic Corp. Tinyj emb.fam");
2218 case EM_X86_64: return strdup ("AMD x86-64 architecture");
2219 case EM_LANAI: return strdup ("32bit LANAI architecture");
2220 case EM_PDSP: return strdup ("Sony DSP Processor");
2221 case EM_PDP10: return strdup ("Digital Equipment Corp. PDP-10");
2222 case EM_PDP11: return strdup ("Digital Equipment Corp. PDP-11");
2223 case EM_FX66: return strdup ("Siemens FX66 microcontroller");
2224 case EM_ST9PLUS: return strdup ("STMicroelectronics ST9+ 8/16 mc");
2225 case EM_ST7: return strdup ("STmicroelectronics ST7 8 bit mc");
2226 case EM_68HC16: return strdup ("Motorola MC68HC16 microcontroller");
2227 case EM_68HC11: return strdup ("Motorola MC68HC11 microcontroller");
2228 case EM_68HC08: return strdup ("Motorola MC68HC08 microcontroller");
2229 case EM_68HC05: return strdup ("Motorola MC68HC05 microcontroller");
2230 case EM_SVX: return strdup ("Silicon Graphics SVx");
2231 case EM_ST19: return strdup ("STMicroelectronics ST19 8 bit mc");
2232 case EM_VAX: return strdup ("Digital VAX");
2233 case EM_CRIS: return strdup ("Axis Communications 32-bit embedded processor");
2234 case EM_JAVELIN: return strdup ("Infineon Technologies 32-bit embedded processor");
2235 case EM_FIREPATH: return strdup ("Element 14 64-bit DSP Processor");
2236 case EM_ZSP: return strdup ("LSI Logic 16-bit DSP Processor");
2237 case EM_MMIX: return strdup ("Donald Knuth's educational 64-bit processor");
2238 case EM_HUANY: return strdup ("Harvard University machine-independent object files");
2239 case EM_PRISM: return strdup ("SiTera Prism");
2240 case EM_AVR: return strdup ("Atmel AVR 8-bit microcontroller");
2241 case EM_FR30: return strdup ("Fujitsu FR30");
2242 case EM_D10V: return strdup ("Mitsubishi D10V");
2243 case EM_D30V: return strdup ("Mitsubishi D30V");
2244 case EM_V850: return strdup ("NEC v850");
2245 case EM_M32R: return strdup ("Mitsubishi M32R");
2246 case EM_MN10300: return strdup ("Matsushita MN10300");
2247 case EM_MN10200: return strdup ("Matsushita MN10200");
2248 case EM_PJ: return strdup ("picoJava");
2249 case EM_OPENRISC: return strdup ("OpenRISC 32-bit embedded processor");
2250 case EM_ARC_A5: return strdup ("ARC Cores Tangent-A5");
2251 case EM_XTENSA: return strdup ("Tensilica Xtensa Architecture");
2252 case EM_AARCH64: return strdup ("ARM aarch64");
2253 case EM_PROPELLER: return strdup ("Parallax Propeller");
2254 case EM_MICROBLAZE: return strdup ("Xilinx MicroBlaze");
2255 case EM_RISCV: return strdup ("RISC V");
2256 case EM_VIDEOCORE3: return strdup ("VideoCore III");
2257 case EM_VIDEOCORE4: return strdup ("VideoCore IV");
2258 case EM_LATTICEMICO32: return strdup ("RISC processor for Lattice FPGA architecture");
2259 case EM_SE_C17: return strdup ("Seiko Epson C17 family");
2260 case EM_TI_C6000: return strdup ("The Texas Instruments TMS320C6000 DSP family");
2261 case EM_TI_C2000: return strdup ("The Texas Instruments TMS320C2000 DSP family");
2262 case EM_TI_C5500: return strdup ("The Texas Instruments TMS320C55x DSP family");
2263 case EM_TI_ARP32: return strdup ("Texas Instruments Application Specific RISC Processor, 32bit fetch");
2264 case EM_TI_PRU: return strdup ("Texas Instruments Programmable Realtime Unit");
2265 case EM_MMDSP_PLUS: return strdup ("STMicroelectronics 64bit VLIW Data Signal Processor");
2266 case EM_CYPRESS_M8C: return strdup ("Cypress M8C microprocessor");
2267 case EM_R32C: return strdup ("Renesas R32C series microprocessors");
2268 case EM_TRIMEDIA: return strdup ("NXP Semiconductors TriMedia architecture family");
2269 case EM_QDSP6: return strdup ("QUALCOMM DSP6 Processor"); // Nonstandard
2270 case EM_8051: return strdup ("Intel 8051 and variants");
2271 case EM_STXP7X: return strdup ("STMicroelectronics STxP7x family of configurable and extensible RISC processors");
2272 case EM_NDS32: return strdup ("Andes Technology compact code size embedded RISC processor family");
2273 case EM_ECOG1: return strdup ("Cyan Technology eCOG1X family");
2274 // case EM_ECOG1X: return strdup ("Cyan Technology eCOG1X family"); // Nonstandard
2275 case EM_MAXQ30: return strdup ("Dallas Semiconductor MAXQ30 Core Micro-controllers");
2276 case EM_XIMO16: return strdup ("New Japan Radio (NJR) 16-bit DSP Processor");
2277 case EM_MANIK: return strdup ("M2000 Reconfigurable RISC Microprocessor");
2278 case EM_CRAYNV2: return strdup ("Cray Inc. NV2 vector architecture");
2279 case EM_RX: return strdup ("Renesas RX family");
2280 case EM_METAG: return strdup ("Imagination Technologies META processor architecture");
2281 case EM_MCST_ELBRUS: return strdup ("MCST Elbrus general purpose hardware architecture");
2282 case EM_ECOG16: return strdup ("Cyan Technology eCOG16 family");
2283 case EM_CR16: return strdup ("National Semiconductor CompactRISC CR16 16-bit microprocessor");
2284 case EM_ETPU: return strdup ("Freescale Extended Time Processing Unit");
2285 case EM_SLE9X: return strdup ("Infineon Technologies SLE9X core");
2286 case EM_L10M: return strdup ("Intel L10M");
2287 case EM_K10M: return strdup ("Intel K10M");
2288 // case EM_AARCH64: return strdup ("ARM 64-bit architecture (AARCH64)"); // Nonstandard
2289 case EM_AVR32: return strdup ("Atmel Corporation 32-bit microprocessor family");
2290 case EM_STM8: return strdup ("STMicroeletronics STM8 8-bit microcontroller");
2291 case EM_TILE64: return strdup ("Tilera TILE64 multicore architecture family");
2292 case EM_TILEPRO: return strdup ("Tilera TILEPro multicore architecture family");
2293 // case EM_MICROBLAZE: return strdup ("Xilinx MicroBlaze 32-bit RISC soft processor core"); // Nonstandard
2294 case EM_CUDA: return strdup ("NVIDIA CUDA architecture");
2295 case EM_TILEGX: return strdup ("Tilera TILE-Gx multicore architecture family");
2296 case EM_CLOUDSHIELD: return strdup ("CloudShield architecture family");
2297 case EM_COREA_1ST: return strdup ("KIPO-KAIST Core-A 1st generation processor family");
2298 case EM_COREA_2ND: return strdup ("KIPO-KAIST Core-A 2nd generation processor family");
2299 case EM_ARC_COMPACT2: return strdup ("Synopsys ARCompact V2");
2300 case EM_OPEN8: return strdup ("Open8 8-bit RISC soft processor core");
2301 case EM_RL78: return strdup ("Renesas RL78 family");
2302 case EM_VIDEOCORE5: return strdup ("Broadcom VideoCore V processor");
2303 case EM_78KOR: return strdup ("Renesas 78KOR family");
2304 // case EM_56800EX: return strdup ("Freescale 56800EX Digital Signal Controller (DSC)"); // Nonstandard
2305 case EM_BA1: return strdup ("Beyond BA1 CPU architecture");
2306 case EM_BA2_NON_STANDARD:
2307 case EM_BA2: return strdup ("Beyond BA2 CPU architecture");
2308 case EM_XCORE: return strdup ("XMOS xCORE processor family");
2309 case EM_MCHP_PIC: return strdup ("Microchip 8-bit PIC(r) family");
2310 case EM_INTEL205: return strdup ("Reserved by Intel");
2311 case EM_INTEL206: return strdup ("Reserved by Intel");
2312 case EM_INTEL207: return strdup ("Reserved by Intel");
2313 case EM_INTEL208: return strdup ("Reserved by Intel");
2314 case EM_INTEL209: return strdup ("Reserved by Intel");
2315 case EM_KM32: return strdup ("KM211 KM32 32-bit processor");
2316 case EM_KMX32: return strdup ("KM211 KMX32 32-bit processor");
2317 case EM_KMX16: return strdup ("KM211 KMX16 16-bit processor");
2318 case EM_KMX8: return strdup ("KM211 KMX8 8-bit processor");
2319 case EM_KVARC: return strdup ("KM211 KVARC processor");
2320 case EM_CDP: return strdup ("Paneve CDP architecture family");
2321 case EM_COGE: return strdup ("Cognitive Smart Memory Processor");
2322 case EM_COOL: return strdup ("Bluechip Systems CoolEngine");
2323 case EM_NORC: return strdup ("Nanoradio Optimized RISC");
2324 case EM_CSR_KALIMBA: return strdup ("CSR Kalimba architecture family");
2325 case EM_Z80: return strdup ("Zilog Z80");
2326 case EM_VISIUM: return strdup ("Controls and Data Services VISIUMcore processor");
2327 case EM_FT32: return strdup ("FTDI Chip FT32 high performance 32-bit RISC architecture");
2328 case EM_MOXIE: return strdup ("Moxie processor family");
2329 case EM_AMDGPU: return strdup ("AMD GPU architecture");
2330
2331 default: return r_str_newf ("<unknown>: 0x%x", bin->ehdr.e_machine);
2332 }
2333 }
2334
2335 char* Elf_(r_bin_elf_get_file_type)(ELFOBJ *bin) {
2336 r_return_val_if_fail (bin, NULL);
2337 ut32 e_type = (ut32)bin->ehdr.e_type; // cast to avoid warn in iphone-gcc, must be ut16
2338 switch (e_type) {
2339 case ET_NONE: return strdup ("NONE (None)");
2340 case ET_REL: return strdup ("REL (Relocatable file)");
2341 case ET_EXEC: return strdup ("EXEC (Executable file)");
2342 case ET_DYN: return strdup ("DYN (Shared object file)");
2343 case ET_CORE: return strdup ("CORE (Core file)");
2344 }
2345 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC)) {
2346 return r_str_newf ("Processor Specific: %x", e_type);
2347 }
2348 if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS)) {
2349 return r_str_newf ("OS Specific: %x", e_type);
2350 }
2351 return r_str_newf ("<unknown>: %x", e_type);
2352 }
2353
2354 char* Elf_(r_bin_elf_get_elf_class)(ELFOBJ *bin) {
2355 switch (bin->ehdr.e_ident[EI_CLASS]) {
2356 case ELFCLASSNONE: return strdup ("none");
2357 case ELFCLASS32: return strdup ("ELF32");
2358 case ELFCLASS64: return strdup ("ELF64");
2359 default: return r_str_newf ("<unknown: %x>", bin->ehdr.e_ident[EI_CLASS]);
2360 }
2361 }
2362
2363 int Elf_(r_bin_elf_get_bits)(ELFOBJ *bin) {
2364 /* Hack for ARCompact */
2365 if (bin->ehdr.e_machine == EM_ARC_A5) {
2366 return 16;
2367 }
2368 /* Hack for Ps2 */
2369 if (bin->phdr && bin->ehdr.e_machine == EM_MIPS) {
2370 const ut32 mipsType = bin->ehdr.e_flags & EF_MIPS_ARCH;
2371 if (bin->ehdr.e_type == ET_EXEC) {
2372 int i;
2373 bool haveInterp = false;
2374 for (i = 0; i < bin->ehdr.e_phnum; i++) {
2375 if (bin->phdr[i].p_type == PT_INTERP) {
2376 haveInterp = true;
2377 }
2378 }
2379 if (!haveInterp && mipsType == EF_MIPS_ARCH_3) {
2380 // Playstation2 Hack
2381 return 64;
2382 }
2383 }
2384 // TODO: show this specific asm.cpu somewhere in bininfo (mips1, mips2, mips3, mips32r2, ...)
2385 switch (mipsType) {
2386 case EF_MIPS_ARCH_1:
2387 case EF_MIPS_ARCH_2:
2388 case EF_MIPS_ARCH_3:
2389 case EF_MIPS_ARCH_4:
2390 case EF_MIPS_ARCH_5:
2391 case EF_MIPS_ARCH_32:
2392 return 32;
2393 case EF_MIPS_ARCH_64:
2394 return 64;
2395 case EF_MIPS_ARCH_32R2:
2396 return 32;
2397 case EF_MIPS_ARCH_64R2:
2398 return 64;
2399 break;
2400 }
2401 return 32;
2402 }
2403 /* Hack for Thumb */
2404 if (bin->ehdr.e_machine == EM_ARM) {
2405 if (bin->ehdr.e_type != ET_EXEC) {
2406 struct r_bin_elf_symbol_t *symbol;
2407 if ((symbol = Elf_(r_bin_elf_get_symbols) (bin))) {
2408 int i = 0;
2409 for (i = 0; !symbol[i].last; i++) {
2410 ut64 paddr = symbol[i].offset;
2411 if (paddr & 1) {
2412 return 16;
2413 }
2414 }
2415 }
2416 }
2417 ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
2418 if (entry & 1) {
2419 return 16;
2420 }
2421 }
2422 switch (bin->ehdr.e_ident[EI_CLASS]) {
2423 case ELFCLASS32: return 32;
2424 case ELFCLASS64: return 64;
2425 case ELFCLASSNONE:
2426 default: return 32; // defaults
2427 }
2428 }
2429
2430 static inline int noodle(ELFOBJ *bin, const char *s) {
2431 if (r_buf_size (bin->b) <= 64) {
2432 return 0;
2433 }
2434 ut8 tmp[64];
2435 r_buf_read_at (bin->b, r_buf_size (bin->b) - 64, tmp, 64);
2436 return r_mem_mem (tmp, 64, (const ut8 *)s, strlen (s)) != NULL;
2437 }
2438
2439 static inline int needle(ELFOBJ *bin, const char *s) {
2440 if (bin->shstrtab) {
2441 ut32 len = bin->shstrtab_size;
2442 if (len > 4096) {
2443 len = 4096; // avoid slow loading .. can be buggy?
2444 }
2445 return r_mem_mem ((const ut8*)bin->shstrtab, len,
2446 (const ut8*)s, strlen (s)) != NULL;
2447 }
2448 return 0;
2449 }
2450
2451 // TODO: must return const char * all those strings must be const char os[LINUX] or so
2452 char* Elf_(r_bin_elf_get_osabi_name)(ELFOBJ *bin) {
2453 size_t i;
2454 size_t num = bin->ehdr.e_shnum;
2455 const char *section_name = NULL;
2456 switch (bin->ehdr.e_ident[EI_OSABI]) {
2457 case ELFOSABI_LINUX: return strdup("linux");
2458 case ELFOSABI_SOLARIS: return strdup("solaris");
2459 case ELFOSABI_FREEBSD: return strdup("freebsd");
2460 case ELFOSABI_HPUX: return strdup("hpux");
2461 }
2462
2463 if (bin->shdr && bin->shstrtab) {
2464 for (i = 0; i < num; i++) {
2465 if (bin->shdr[i].sh_type == SHT_NOTE && bin->shdr[i].sh_name < bin->shstrtab_size) {
2466 section_name = &bin->shstrtab[bin->shdr[i].sh_name];
2467 if (!strcmp (section_name, ".note.openbsd.ident")) {
2468 return strdup ("openbsd");
2469 }
2470 if (!strcmp (section_name, ".note.minix.ident")) {
2471 return strdup ("minix");
2472 }
2473 if (!strcmp (section_name, ".note.netbsd.ident")) {
2474 return strdup ("netbsd");
2475 }
2476 if (!strcmp (section_name, ".note.android.ident")) {
2477 return strdup ("android");
2478 }
2479 }
2480 }
2481 }
2482 /* Hack to identify OS */
2483 if (needle (bin, "freebsd")) {
2484 return strdup ("freebsd");
2485 }
2486 if (noodle (bin, "BEOS:APP_VERSION")) {
2487 return strdup ("beos");
2488 }
2489 if (needle (bin, "GNU")) {
2490 return strdup ("linux");
2491 }
2492 return strdup ("linux");
2493 }
2494
2495 ut8 *Elf_(r_bin_elf_grab_regstate)(ELFOBJ *bin, int *len) {
2496 if (bin->phdr) {
2497 size_t i;
2498 int num = bin->ehdr.e_phnum;
2499 for (i = 0; i < num; i++) {
2500 if (bin->phdr[i].p_type != PT_NOTE) {
2501 continue;
2502 }
2503 int bits = Elf_(r_bin_elf_get_bits)(bin);
2504 int elf_nhdr_size = (bits == 64) ? sizeof (Elf64_Nhdr) : sizeof (Elf32_Nhdr);
2505 void *elf_nhdr = calloc (elf_nhdr_size, 1);
2506 bool regs_found = false;
2507 ut64 offset = 0;
2508
2509 while (!regs_found) {
2510 ut32 n_descsz, n_namesz, n_type;
2511 int ret;
2512 ret = r_buf_read_at (bin->b, bin->phdr[i].p_offset + offset, elf_nhdr, elf_nhdr_size);
2513 if (ret != elf_nhdr_size) {
2514 bprintf ("Cannot read NOTES hdr from CORE file\n");
2515 free (elf_nhdr);
2516 return NULL;
2517 }
2518 if (bits == 64) {
2519 n_descsz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_descsz);
2520 n_namesz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_namesz);
2521 n_type = ((Elf64_Nhdr *)elf_nhdr)->n_type;
2522 } else {
2523 n_descsz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_descsz);
2524 n_namesz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_namesz);
2525 n_type = ((Elf32_Nhdr *)elf_nhdr)->n_type;
2526 }
2527 if (n_type == NT_PRSTATUS) {
2528 regs_found = true;
2529 free (elf_nhdr);
2530 } else {
2531 offset += elf_nhdr_size + n_descsz + n_namesz;
2532 }
2533 }
2534
2535 int regdelta = 0;
2536 int regsize = 0;
2537 switch (bin->ehdr.e_machine) {
2538 case EM_AARCH64:
2539 regsize = reginf[AARCH64].regsize;
2540 regdelta = reginf[AARCH64].regdelta;
2541 break;
2542 case EM_ARM:
2543 regsize = reginf[ARM].regsize;
2544 regdelta = reginf[ARM].regdelta;
2545 break;
2546 case EM_386:
2547 regsize = reginf[X86].regsize;
2548 regdelta = reginf[X86].regdelta;
2549 break;
2550 case EM_X86_64:
2551 regsize = reginf[X86_64].regsize;
2552 regdelta = reginf[X86_64].regdelta;
2553 break;
2554 }
2555 ut8 *buf = malloc (regsize);
2556 if (r_buf_read_at (bin->b, bin->phdr[i].p_offset + offset + regdelta, buf, regsize) != regsize) {
2557 free (buf);
2558 bprintf ("Cannot read register state from CORE file\n");
2559 return NULL;
2560 }
2561 if (len) {
2562 *len = regsize;
2563 }
2564 return buf;
2565 }
2566 }
2567 bprintf ("Cannot find NOTE section\n");
2568 return NULL;
2569 }
2570
2571 int Elf_(r_bin_elf_is_big_endian)(ELFOBJ *bin) {
2572 return (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB);
2573 }
2574
2575 /* XXX Init dt_strtab? */
2576 char *Elf_(r_bin_elf_get_rpath)(ELFOBJ *bin) {
2577 r_return_val_if_fail (bin, NULL);
2578 char *ret;
2579 Elf_(Xword) val;
2580
2581 if (!bin->phdr || !bin->strtab) {
2582 return NULL;
2583 }
2584
2585 if (bin->dyn_info.dt_rpath != R_BIN_ELF_XWORD_MAX) {
2586 val = bin->dyn_info.dt_rpath;
2587 } else if (bin->dyn_info.dt_runpath != R_BIN_ELF_XWORD_MAX) {
2588 val = bin->dyn_info.dt_runpath;
2589 } else {
2590 return NULL;
2591 }
2592
2593 if (val > bin->strtab_size) {
2594 return NULL;
2595 }
2596
2597 if (!(ret = calloc (1, ELF_STRING_LENGTH))) {
2598 return NULL;
2599 }
2600
2601 r_str_ncpy (ret, bin->strtab + val, ELF_STRING_LENGTH);
2602
2603 return ret;
2604 }
2605
2606 static bool has_valid_section_header(ELFOBJ *bin, size_t pos) {
2607 return bin->g_sections[pos].info < bin->ehdr.e_shnum && bin->shdr;
2608 }
2609
2610 static void fix_rva_and_offset_relocable_file(ELFOBJ *bin, RBinElfReloc *r, size_t pos) {
2611 if (has_valid_section_header (bin, pos)) {
2612 r->rva = bin->shdr[bin->g_sections[pos].info].sh_offset + r->offset;
2613 r->rva = Elf_(r_bin_elf_p2v) (bin, r->rva);
2614 } else {
2615 r->rva = r->offset;
2616 }
2617 }
2618
2619 static void fix_rva_and_offset_exec_file(ELFOBJ *bin, RBinElfReloc *r) {
2620 r->rva = r->offset;
2621 r->offset = Elf_(r_bin_elf_v2p) (bin, r->offset);
2622 }
2623
2624 static void fix_rva_and_offset(ELFOBJ *bin, RBinElfReloc *r, size_t pos) {
2625 if (is_bin_etrel (bin)) {
2626 fix_rva_and_offset_relocable_file (bin, r, pos);
2627 } else {
2628 fix_rva_and_offset_exec_file (bin, r);
2629 }
2630 }
2631
2632 static bool read_reloc(ELFOBJ *bin, RBinElfReloc *r, Elf_(Xword) rel_mode, ut64 vaddr) {
2633 ut64 offset = Elf_(r_bin_elf_v2p_new) (bin, vaddr);
2634 if (offset == UT64_MAX) {
2635 return false;
2636 }
2637
2638 size_t size_struct = get_size_rel_mode (rel_mode);
2639
2640 ut8 buf[sizeof (Elf_(Rela))] = { 0 };
2641 int res = r_buf_read_at (bin->b, offset, buf, size_struct);
2642 if (res != size_struct) {
2643 return false;
2644 }
2645
2646 size_t i = 0;
2647 Elf_(Rela) reloc_info;
2648
2649 reloc_info.r_offset = R_BIN_ELF_READWORD (buf, i);
2650 reloc_info.r_info = R_BIN_ELF_READWORD (buf, i);
2651
2652 if (rel_mode == DT_RELA) {
2653 reloc_info.r_addend = R_BIN_ELF_READWORD (buf, i);
2654 r->addend = reloc_info.r_addend;
2655 }
2656
2657 r->rel_mode = rel_mode;
2658 r->last = 0;
2659 r->offset = reloc_info.r_offset;
2660 r->sym = ELF_R_SYM (reloc_info.r_info);
2661 r->type = ELF_R_TYPE (reloc_info.r_info);
2662
2663 return true;
2664 }
2665
2666 static size_t get_num_relocs_dynamic(ELFOBJ *bin) {
2667 size_t res = 0;
2668
2669 if (bin->dyn_info.dt_relaent) {
2670 res += bin->dyn_info.dt_relasz / bin->dyn_info.dt_relaent;
2671 }
2672
2673 if (bin->dyn_info.dt_relent) {
2674 res += bin->dyn_info.dt_relsz / bin->dyn_info.dt_relent;
2675 }
2676
2677 return res + get_num_relocs_dynamic_plt (bin);
2678 }
2679
2680 static bool sectionIsValid(ELFOBJ *bin, RBinElfSection *sect) {
2681 return (sect->offset + sect->size <= bin->size);
2682 }
2683
2684 static Elf_(Xword) get_section_mode(ELFOBJ *bin, size_t pos) {
2685 if (r_str_startswith (bin->g_sections[pos].name, ".rela.")) {
2686 return DT_RELA;
2687 }
2688 if (r_str_startswith (bin->g_sections[pos].name, ".rel.")) {
2689 return DT_REL;
2690 }
2691 return 0;
2692 }
2693
2694 static bool is_reloc_section(Elf_(Xword) rel_mode) {
2695 return rel_mode == DT_REL || rel_mode == DT_RELA;
2696 }
2697
2698 static size_t get_num_relocs_sections(ELFOBJ *bin) {
2699 size_t i, size, ret = 0;
2700 Elf_(Xword) rel_mode;
2701
2702 if (!bin->g_sections) {
2703 return 0;
2704 }
2705
2706 for (i = 0; !bin->g_sections[i].last; i++) {
2707 if (!sectionIsValid (bin, &bin->g_sections[i])) {
2708 continue;
2709 }
2710 rel_mode = get_section_mode (bin, i);
2711 if (!is_reloc_section (rel_mode)) {
2712 continue;
2713 }
2714 size = get_size_rel_mode (rel_mode);
2715 ret += NUMENTRIES_ROUNDUP (bin->g_sections[i].size, size);
2716 }
2717
2718 return ret;
2719 }
2720
2721 static size_t get_num_relocs_approx(ELFOBJ *bin) {
2722 return get_num_relocs_dynamic (bin) + get_num_relocs_sections (bin);
2723 }
2724
2725 static size_t populate_relocs_record_from_dynamic(ELFOBJ *bin, RBinElfReloc *relocs, size_t pos, size_t num_relocs) {
2726 size_t offset;
2727 size_t size = get_size_rel_mode (bin->dyn_info.dt_pltrel);
2728
2729 for (offset = 0; offset < bin->dyn_info.dt_pltrelsz && pos < num_relocs; offset += size, pos++) {
2730 if (!read_reloc (bin, relocs + pos, bin->dyn_info.dt_pltrel, bin->dyn_info.dt_jmprel + offset)) {
2731 break;
2732 }
2733 fix_rva_and_offset_exec_file (bin, relocs + pos);
2734 }
2735
2736 for (offset = 0; offset < bin->dyn_info.dt_relasz && pos < num_relocs; offset += bin->dyn_info.dt_relaent, pos++) {
2737 if (!read_reloc (bin, relocs + pos, DT_RELA, bin->dyn_info.dt_rela + offset)) {
2738 break;
2739 }
2740 fix_rva_and_offset_exec_file (bin, relocs + pos);
2741 }
2742
2743 for (offset = 0; offset < bin->dyn_info.dt_relsz && pos < num_relocs; offset += bin->dyn_info.dt_relent, pos++) {
2744 if (!read_reloc (bin, relocs + pos, DT_REL, bin->dyn_info.dt_rel + offset)) {
2745 break;
2746 }
2747 fix_rva_and_offset_exec_file (bin, relocs + pos);
2748 }
2749
2750 return pos;
2751 }
2752
2753 static size_t get_next_not_analysed_offset(ELFOBJ *bin, size_t section_vaddr, size_t offset) {
2754 size_t gvaddr = section_vaddr + offset;
2755
2756 if (bin->dyn_info.dt_rela != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_rela <= gvaddr
2757 && gvaddr < bin->dyn_info.dt_rela + bin->dyn_info.dt_relasz) {
2758 return bin->dyn_info.dt_rela + bin->dyn_info.dt_relasz - section_vaddr;
2759 }
2760
2761 if (bin->dyn_info.dt_rel != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_rel <= gvaddr
2762 && gvaddr < bin->dyn_info.dt_rel + bin->dyn_info.dt_relsz) {
2763 return bin->dyn_info.dt_rel + bin->dyn_info.dt_relsz - section_vaddr;
2764 }
2765
2766 if (bin->dyn_info.dt_jmprel != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_jmprel <= gvaddr
2767 && gvaddr < bin->dyn_info.dt_jmprel + bin->dyn_info.dt_pltrelsz) {
2768 return bin->dyn_info.dt_jmprel + bin->dyn_info.dt_pltrelsz - section_vaddr;
2769 }
2770
2771 return offset;
2772 }
2773
2774 static size_t populate_relocs_record_from_section(ELFOBJ *bin, RBinElfReloc *relocs, size_t pos, size_t num_relocs) {
2775 size_t size, i, j;
2776 Elf_(Xword) rel_mode;
2777
2778 if (!bin->g_sections) {
2779 return pos;
2780 }
2781
2782 for (i = 0; !bin->g_sections[i].last; i++) {
2783 rel_mode = get_section_mode (bin, i);
2784
2785 if (!is_reloc_section (rel_mode) || bin->g_sections[i].size > bin->size || bin->g_sections[i].offset > bin->size) {
2786 continue;
2787 }
2788
2789 size = get_size_rel_mode (rel_mode);
2790
2791 for (j = get_next_not_analysed_offset (bin, bin->g_sections[i].rva, 0);
2792 j < bin->g_sections[i].size && pos < num_relocs;
2793 j = get_next_not_analysed_offset (bin, bin->g_sections[i].rva, j + size)) {
2794
2795 if (!read_reloc (bin, relocs + pos, rel_mode, bin->g_sections[i].rva + j)) {
2796 break;
2797 }
2798
2799 fix_rva_and_offset (bin, relocs + pos, i);
2800 pos++;
2801 }
2802 }
2803
2804 return pos;
2805 }
2806
2807 static RBinElfReloc *populate_relocs_record(ELFOBJ *bin) {
2808 size_t i = 0;
2809 size_t num_relocs = get_num_relocs_approx (bin);
2810 RBinElfReloc *relocs = R_NEWS0 (RBinElfReloc, num_relocs + 1);
2811 if (!relocs) {
2812 // In case we can't allocate enough memory for all the claimed
2813 // relocation entries, try to parse only the ones specified in
2814 // the dynamic segment.
2815 num_relocs = get_num_relocs_dynamic (bin);
2816 relocs = R_NEWS0 (RBinElfReloc, num_relocs + 1);
2817 if (!relocs) {
2818 return NULL;
2819 }
2820 }
2821
2822 i = populate_relocs_record_from_dynamic (bin, relocs, i, num_relocs);
2823 i = populate_relocs_record_from_section (bin, relocs, i, num_relocs);
2824 relocs[i].last = 1;
2825
2826 bin->g_reloc_num = i;
2827 return relocs;
2828 }
2829
2830 RBinElfReloc* Elf_(r_bin_elf_get_relocs) (ELFOBJ *bin) {
2831 if (!bin) {
2832 return NULL;
2833 }
2834
2835 if (!bin->g_relocs) {
2836 bin->g_relocs = populate_relocs_record (bin);
2837 }
2838 return bin->g_relocs;
2839 }
2840
2841 RBinElfLib* Elf_(r_bin_elf_get_libs)(ELFOBJ *bin) {
2842 RBinElfLib *ret = NULL;
2843 Elf_(Off) *it = NULL;
2844 size_t k = 0;
2845
2846 if (!bin || !bin->phdr || !bin->strtab || *(bin->strtab+1) == '0') {
2847 return NULL;
2848 }
2849
2850 r_vector_foreach(&bin->dyn_info.dt_needed, it) {
2851 Elf_(Off) val = *it;
2852
2853 RBinElfLib *r = realloc (ret, (k + 1) * sizeof (RBinElfLib));
2854 if (!r) {
2855 perror ("realloc (libs)");
2856 free (ret);
2857 return NULL;
2858 }
2859 ret = r;
2860 if (val > bin->strtab_size) {
2861 free (ret);
2862 return NULL;
2863 }
2864 strncpy (ret[k].name, bin->strtab + val, ELF_STRING_LENGTH);
2865 ret[k].name[ELF_STRING_LENGTH - 1] = '\0';
2866 ret[k].last = 0;
2867 if (ret[k].name[0]) {
2868 k++;
2869 }
2870 }
2871
2872 RBinElfLib *r = realloc (ret, (k + 1) * sizeof (RBinElfLib));
2873 if (!r) {
2874 perror ("realloc (libs)");
2875 free (ret);
2876 return NULL;
2877 }
2878 ret = r;
2879 ret[k].last = 1;
2880 return ret;
2881 }
2882
2883 static void create_section_from_phdr(ELFOBJ *bin, RBinElfSection *ret, size_t *i, const char *name, ut64 addr, ut64 sz) {
2884 if (!addr) {
2885 return;
2886 }
2887
2888 ret[*i].offset = Elf_(r_bin_elf_v2p_new) (bin, addr);
2889 ret[*i].rva = addr;
2890 ret[*i].size = sz;
2891 strncpy (ret[*i].name, name, R_ARRAY_SIZE (ret[*i].name) - 1);
2892 ret[*i].name[R_ARRAY_SIZE (ret[*i].name) - 1] = '\0';
2893 ret[*i].last = 0;
2894 *i = *i + 1;
2895 }
2896
2897 static RBinElfSection *get_sections_from_phdr(ELFOBJ *bin) {
2898 RBinElfSection *ret;
2899 size_t num_sections = 0;
2900 ut64 reldyn = 0, relava = 0, pltgotva = 0, relva = 0;
2901 ut64 reldynsz = 0, relasz = 0, pltgotsz = 0;
2902 r_return_val_if_fail (bin && bin->phdr, NULL);
2903
2904 if (!bin->ehdr.e_phnum) {
2905 return NULL;
2906 }
2907
2908 if (bin->dyn_info.dt_rel != R_BIN_ELF_ADDR_MAX) {
2909 reldyn = bin->dyn_info.dt_rel;
2910 num_sections++;
2911 }
2912 if (bin->dyn_info.dt_rela != R_BIN_ELF_ADDR_MAX) {
2913 relva = bin->dyn_info.dt_rela;
2914 num_sections++;
2915 }
2916 if (bin->dyn_info.dt_relsz) {
2917 reldynsz = bin->dyn_info.dt_relsz;
2918 }
2919 if (bin->dyn_info.dt_relasz) {
2920 relasz = bin->dyn_info.dt_relasz;
2921 }
2922 if (bin->dyn_info.dt_pltgot != R_BIN_ELF_ADDR_MAX) {
2923 pltgotva = bin->dyn_info.dt_pltgot;
2924 num_sections++;
2925 }
2926 if (bin->dyn_info.dt_pltrelsz) {
2927 pltgotsz = bin->dyn_info.dt_pltrelsz;
2928 }
2929 if (bin->dyn_info.dt_jmprel != R_BIN_ELF_ADDR_MAX) {
2930 relava = bin->dyn_info.dt_jmprel;
2931 num_sections++;
2932 }
2933
2934 ret = calloc (num_sections + 1, sizeof (RBinElfSection));
2935 if (!ret) {
2936 return NULL;
2937 }
2938
2939 size_t i = 0;
2940 create_section_from_phdr (bin, ret, &i, ".rel.dyn", reldyn, reldynsz);
2941 create_section_from_phdr (bin, ret, &i, ".rela.plt", relava, pltgotsz);
2942 create_section_from_phdr (bin, ret, &i, ".rel.plt", relva, relasz);
2943 create_section_from_phdr (bin, ret, &i, ".got.plt", pltgotva, pltgotsz);
2944 ret[i].last = 1;
2945
2946 return ret;
2947 }
2948
2949 RBinElfSection* Elf_(r_bin_elf_get_sections)(ELFOBJ *bin) {
2950 RBinElfSection *ret = NULL;
2951 char unknown_s[32], invalid_s[32];
2952 int i, nidx, unknown_c=0, invalid_c=0;
2953
2954 r_return_val_if_fail (bin, NULL);
2955 if (bin->g_sections) {
2956 return bin->g_sections;
2957 }
2958 if (!bin->shdr && bin->phdr) {
2959 //we don't give up search in phdr section
2960 return get_sections_from_phdr (bin);
2961 }
2962 if (!bin->shdr) {
2963 return NULL;
2964 }
2965 if (!(ret = calloc ((bin->ehdr.e_shnum + 1), sizeof (RBinElfSection)))) {
2966 return NULL;
2967 }
2968 for (i = 0; i < bin->ehdr.e_shnum; i++) {
2969 ret[i].offset = bin->shdr[i].sh_offset;
2970 ret[i].size = bin->shdr[i].sh_size;
2971 ret[i].align = bin->shdr[i].sh_addralign;
2972 ret[i].flags = bin->shdr[i].sh_flags;
2973 ret[i].link = bin->shdr[i].sh_link;
2974 ret[i].info = bin->shdr[i].sh_info;
2975 ret[i].type = bin->shdr[i].sh_type;
2976 if (is_bin_etrel (bin)) {
2977 ret[i].rva = bin->baddr + bin->shdr[i].sh_offset;
2978 } else {
2979 ret[i].rva = bin->shdr[i].sh_addr;
2980 }
2981
2982 const int SHNAME = (int)bin->shdr[i].sh_name;
2983 const int SHSIZE = (int)bin->shstrtab_size;
2984 nidx = SHNAME;
2985 if (nidx < 0 || !bin->shstrtab_section || !bin->shstrtab_size || nidx > bin->shstrtab_size) {
2986 snprintf (invalid_s, sizeof (invalid_s), "invalid%d", invalid_c);
2987 strncpy (ret[i].name, invalid_s, sizeof (ret[i].name) - 1);
2988 invalid_c++;
2989 } else if (bin->shstrtab && (SHNAME > 0) && (SHNAME < SHSIZE)) {
2990 strncpy (ret[i].name, &bin->shstrtab[SHNAME], sizeof (ret[i].name) - 1);
2991 } else if (bin->shdr[i].sh_type == SHT_NULL) {
2992 //to follow the same behaviour as readelf
2993 ret[i].name[0] = '\0';
2994 } else {
2995 snprintf (unknown_s, sizeof (unknown_s), "unknown%d", unknown_c);
2996 strncpy (ret[i].name, unknown_s, sizeof (ret[i].name) - 1);
2997 unknown_c++;
2998 }
2999 ret[i].name[ELF_STRING_LENGTH - 1] = '\0';
3000 ret[i].last = 0;
3001 }
3002 ret[i].last = 1;
3003 return ret;
3004 }
3005
3006 static bool is_special_arm_symbol(ELFOBJ *bin, Elf_(Sym) *sym, const char *name) {
3007 if (name[0] != '$') {
3008 return false;
3009 }
3010 switch (name[1]) {
3011 case 'a':
3012 case 't':
3013 case 'd':
3014 case 'x':
3015 return (name[2] == '\0' || name[2] == '.') &&
3016 ELF_ST_TYPE (sym->st_info) == STT_NOTYPE &&
3017 ELF_ST_BIND (sym->st_info) == STB_LOCAL &&
3018 ELF_ST_VISIBILITY (sym->st_info) == STV_DEFAULT;
3019 default:
3020 return false;
3021 }
3022 }
3023
3024 static bool is_special_symbol(ELFOBJ *bin, Elf_(Sym) *sym, const char *name) {
3025 switch (bin->ehdr.e_machine) {
3026 case EM_ARM:
3027 case EM_AARCH64:
3028 return is_special_arm_symbol (bin, sym, name);
3029 default:
3030 return false;
3031 }
3032 }
3033
3034 static const char *bind2str(Elf_(Sym) *sym) {
3035 switch (ELF_ST_BIND (sym->st_info)) {
3036 case STB_LOCAL: return R_BIN_BIND_LOCAL_STR;
3037 case STB_GLOBAL: return R_BIN_BIND_GLOBAL_STR;
3038 case STB_WEAK: return R_BIN_BIND_WEAK_STR;
3039 case STB_NUM: return R_BIN_BIND_NUM_STR;
3040 case STB_LOOS: return R_BIN_BIND_LOOS_STR;
3041 case STB_HIOS: return R_BIN_BIND_HIOS_STR;
3042 case STB_LOPROC: return R_BIN_BIND_LOPROC_STR;
3043 case STB_HIPROC: return R_BIN_BIND_HIPROC_STR;
3044 default: return R_BIN_BIND_UNKNOWN_STR;
3045 }
3046 }
3047
3048 static const char *type2str(ELFOBJ *bin, struct r_bin_elf_symbol_t *ret, Elf_(Sym) *sym) {
3049 if (bin && ret && is_special_symbol (bin, sym, ret->name)) {
3050 return R_BIN_TYPE_SPECIAL_SYM_STR;
3051 }
3052 switch (ELF_ST_TYPE (sym->st_info)) {
3053 case STT_NOTYPE: return R_BIN_TYPE_NOTYPE_STR;
3054 case STT_OBJECT: return R_BIN_TYPE_OBJECT_STR;
3055 case STT_FUNC: return R_BIN_TYPE_FUNC_STR;
3056 case STT_SECTION: return R_BIN_TYPE_SECTION_STR;
3057 case STT_FILE: return R_BIN_TYPE_FILE_STR;
3058 case STT_COMMON: return R_BIN_TYPE_COMMON_STR;
3059 case STT_TLS: return R_BIN_TYPE_TLS_STR;
3060 case STT_NUM: return R_BIN_TYPE_NUM_STR;
3061 case STT_LOOS: return R_BIN_TYPE_LOOS_STR;
3062 case STT_HIOS: return R_BIN_TYPE_HIOS_STR;
3063 case STT_LOPROC: return R_BIN_TYPE_LOPROC_STR;
3064 case STT_HIPROC: return R_BIN_TYPE_HIPROC_STR;
3065 default: return R_BIN_TYPE_UNKNOWN_STR;
3066 }
3067 }
3068
3069 static void fill_symbol_bind_and_type(ELFOBJ *bin, struct r_bin_elf_symbol_t *ret, Elf_(Sym) *sym) {
3070 ret->bind = bind2str (sym);
3071 ret->type = type2str (bin, ret, sym);
3072 }
3073
3074 static RBinElfSymbol* get_symbols_from_phdr(ELFOBJ *bin, int type) {
3075 Elf_(Sym) *sym = NULL;
3076 Elf_(Addr) addr_sym_table = 0;
3077 ut8 s[sizeof (Elf_(Sym))] = {0};
3078 RBinElfSymbol *ret = NULL;
3079 int i, r, tsize, nsym, ret_ctr;
3080 ut64 toffset = 0, tmp_offset;
3081 ut32 size, sym_size = 0;
3082
3083 if (!bin || !bin->phdr || !bin->ehdr.e_phnum) {
3084 return NULL;
3085 }
3086
3087 if (bin->dyn_info.dt_symtab == R_BIN_ELF_ADDR_MAX || !bin->dyn_info.dt_syment) {
3088 return NULL;
3089 }
3090
3091 addr_sym_table = Elf_(r_bin_elf_v2p) (bin, bin->dyn_info.dt_symtab);
3092 sym_size = bin->dyn_info.dt_syment;
3093 if (!sym_size) {
3094 goto beach;
3095 }
3096
3097 //since ELF doesn't specify the symbol table size we may read until the end of the buffer
3098 nsym = (bin->size - addr_sym_table) / sym_size;
3099 if (!UT32_MUL (&size, nsym, sizeof (Elf_ (Sym)))) {
3100 goto beach;
3101 }
3102 if (size < 1) {
3103 goto beach;
3104 }
3105 if (addr_sym_table > bin->size || addr_sym_table + size > bin->size) {
3106 goto beach;
3107 }
3108 if (nsym < 1) {
3109 return NULL;
3110 }
3111 // we reserve room for 4096 and grow as needed.
3112 size_t capacity1 = 4096;
3113 size_t capacity2 = 4096;
3114 sym = (Elf_(Sym)*) calloc (capacity1, sym_size);
3115 ret = (RBinElfSymbol *) calloc (capacity2, sizeof (struct r_bin_elf_symbol_t));
3116 if (!sym || !ret) {
3117 goto beach;
3118 }
3119 for (i = 1, ret_ctr = 0; i < nsym; i++) {
3120 if (i >= capacity1) { // maybe grow
3121 // You take what you want, but you eat what you take.
3122 Elf_(Sym)* temp_sym = (Elf_(Sym)*) realloc (sym, (capacity1 * GROWTH_FACTOR) * sym_size);
3123 if (!temp_sym) {
3124 goto beach;
3125 }
3126 sym = temp_sym;
3127 capacity1 *= GROWTH_FACTOR;
3128 }
3129 if (ret_ctr >= capacity2) { // maybe grow
3130 RBinElfSymbol *temp_ret = realloc (ret, capacity2 * GROWTH_FACTOR * sizeof (struct r_bin_elf_symbol_t));
3131 if (!temp_ret) {
3132 goto beach;
3133 }
3134 ret = temp_ret;
3135 capacity2 *= GROWTH_FACTOR;
3136 }
3137 // read in one entry
3138 r = r_buf_read_at (bin->b, addr_sym_table + i * sizeof (Elf_ (Sym)), s, sizeof (Elf_ (Sym)));
3139 if (r < 1) {
3140 goto beach;
3141 }
3142 int j = 0;
3143 #if R_BIN_ELF64
3144 sym[i].st_name = READ32 (s, j);
3145 sym[i].st_info = READ8 (s, j);
3146 sym[i].st_other = READ8 (s, j);
3147 sym[i].st_shndx = READ16 (s, j);
3148 sym[i].st_value = READ64 (s, j);
3149 sym[i].st_size = READ64 (s, j);
3150 #else
3151 sym[i].st_name = READ32 (s, j);
3152 sym[i].st_value = READ32 (s, j);
3153 sym[i].st_size = READ32 (s, j);
3154 sym[i].st_info = READ8 (s, j);
3155 sym[i].st_other = READ8 (s, j);
3156 sym[i].st_shndx = READ16 (s, j);
3157 #endif
3158 bool is_sht_null = false;
3159 bool is_vaddr = false;
3160 // zero symbol is always empty
3161 // Examine entry and maybe store
3162 if (type == R_BIN_ELF_IMPORT_SYMBOLS && sym[i].st_shndx == SHT_NULL) {
3163 if (sym[i].st_value) {
3164 toffset = sym[i].st_value;
3165 } else if ((toffset = get_import_addr (bin, i)) == -1){
3166 toffset = 0;
3167 }
3168 tsize = 16;
3169 } else if (type == R_BIN_ELF_ALL_SYMBOLS) {
3170 tsize = sym[i].st_size;
3171 toffset = (ut64) sym[i].st_value;
3172 is_sht_null = sym[i].st_shndx == SHT_NULL;
3173 } else {
3174 continue;
3175 }
3176 // since we don't know the size of the sym table in this case,
3177 // let's stop at the first invalid entry
3178 if (!strcmp (bind2str (&sym[i]), R_BIN_BIND_UNKNOWN_STR) ||
3179 !strcmp (type2str (NULL, NULL, &sym[i]), R_BIN_TYPE_UNKNOWN_STR)) {
3180 goto done;
3181 }
3182 tmp_offset = Elf_(r_bin_elf_v2p_new) (bin, toffset);
3183 if (tmp_offset == UT64_MAX) {
3184 tmp_offset = toffset;
3185 is_vaddr = true;
3186 }
3187 if (sym[i].st_name + 2 > bin->strtab_size) {
3188 // Since we are reading beyond the symbol table what's happening
3189 // is that some entry is trying to dereference the strtab beyond its capacity
3190 // is not a symbol so is the end
3191 goto done;
3192 }
3193 ret[ret_ctr].offset = tmp_offset;
3194 ret[ret_ctr].size = tsize;
3195 {
3196 int rest = ELF_STRING_LENGTH - 1;
3197 int st_name = sym[i].st_name;
3198 int maxsize = R_MIN (bin->size, bin->strtab_size);
3199 if (st_name < 0 || st_name >= maxsize) {
3200 ret[ret_ctr].name[0] = 0;
3201 } else {
3202 const int len = __strnlen (bin->strtab + st_name, rest);
3203 memcpy (ret[ret_ctr].name, &bin->strtab[st_name], len);
3204 }
3205 }
3206 ret[ret_ctr].ordinal = i;
3207 ret[ret_ctr].in_shdr = false;
3208 ret[ret_ctr].name[ELF_STRING_LENGTH - 2] = '\0';
3209 fill_symbol_bind_and_type (bin, &ret[ret_ctr], &sym[i]);
3210 ret[ret_ctr].is_sht_null = is_sht_null;
3211 ret[ret_ctr].is_vaddr = is_vaddr;
3212 ret[ret_ctr].last = 0;
3213 ret_ctr++;
3214 }
3215 done:
3216 // Size everything down to only what is used
3217 {
3218 nsym = i > 0? i: 1;
3219 Elf_(Sym) *temp_sym = (Elf_(Sym) *)realloc (sym, (nsym * GROWTH_FACTOR) * sym_size);
3220 if (!temp_sym) {
3221 goto beach;
3222 }
3223 sym = temp_sym;
3224 }
3225 {
3226 ret_ctr = ret_ctr > 0? ret_ctr: 1;
3227 RBinElfSymbol *p = (RBinElfSymbol *)realloc (ret, (ret_ctr + 1) * sizeof (RBinElfSymbol));
3228 if (!p) {
3229 goto beach;
3230 }
3231 ret = p;
3232 }
3233 ret[ret_ctr].last = 1;
3234 if (type == R_BIN_ELF_IMPORT_SYMBOLS && !bin->imports_by_ord_size) {
3235 bin->imports_by_ord_size = ret_ctr + 1;
3236 if (ret_ctr > 0) {
3237 bin->imports_by_ord = (RBinImport * *) calloc (ret_ctr + 1, sizeof (RBinImport*));
3238 } else {
3239 bin->imports_by_ord = NULL;
3240 }
3241 } else if (type == R_BIN_ELF_ALL_SYMBOLS && !bin->symbols_by_ord_size && ret_ctr) {
3242 bin->symbols_by_ord_size = ret_ctr + 1;
3243 if (ret_ctr > 0) {
3244 bin->symbols_by_ord = (RBinSymbol * *) calloc (ret_ctr + 1, sizeof (RBinSymbol*));
3245 } else {
3246 bin->symbols_by_ord = NULL;
3247 }
3248 }
3249 free (sym);
3250 return ret;
3251 beach:
3252 free (sym);
3253 free (ret);
3254 return NULL;
3255 }
3256
3257 static RBinElfSymbol *Elf_(r_bin_elf_get_phdr_symbols)(ELFOBJ *bin) {
3258 if (!bin) {
3259 return NULL;
3260 }
3261 if (bin->phdr_symbols) {
3262 return bin->phdr_symbols;
3263 }
3264 bin->phdr_symbols = get_symbols_from_phdr (bin, R_BIN_ELF_ALL_SYMBOLS);
3265 return bin->phdr_symbols;
3266 }
3267
3268 static RBinElfSymbol *Elf_(r_bin_elf_get_phdr_imports)(ELFOBJ *bin) {
3269 r_return_val_if_fail (bin, NULL);
3270 if (!bin->phdr_imports) {
3271 bin->phdr_imports = get_symbols_from_phdr (bin, R_BIN_ELF_IMPORT_SYMBOLS);
3272 }
3273 return bin->phdr_imports;
3274 }
3275
3276 static RBinElfSymbol *Elf_(get_phdr_symbols)(ELFOBJ *bin, int type) {
3277 return (type != R_BIN_ELF_IMPORT_SYMBOLS)
3278 ? Elf_(r_bin_elf_get_phdr_symbols) (bin)
3279 : Elf_(r_bin_elf_get_phdr_imports) (bin);
3280 }
3281
3282 static int Elf_(fix_symbols)(ELFOBJ *bin, int nsym, int type, RBinElfSymbol **sym) {
3283 int count = 0;
3284 int result = -1;
3285 RBinElfSymbol *ret = *sym;
3286 RBinElfSymbol *phdr_symbols = Elf_(get_phdr_symbols) (bin, type);
3287 RBinElfSymbol *tmp, *p;
3288 HtUP *phd_offset_map = ht_up_new0 ();
3289 HtUP *phd_ordinal_map = ht_up_new0 ();
3290 if (phdr_symbols) {
3291 RBinElfSymbol *d = ret;
3292 while (!d->last) {
3293 ht_up_insert (phd_offset_map, d->offset, d);
3294 ht_up_insert (phd_ordinal_map, d->ordinal, d);
3295 d++;
3296 }
3297 p = phdr_symbols;
3298 while (!p->last) {
3299 /* find match in phdr */
3300 d = ht_up_find (phd_offset_map, p->offset, NULL);
3301 if (!d) {
3302 d = ht_up_find (phd_ordinal_map, p->ordinal, NULL);
3303 }
3304 if (d) {
3305 p->in_shdr = true;
3306 if (*p->name && *d->name && r_str_startswith (d->name, "$")) {
3307 strcpy (d->name, p->name);
3308 }
3309 }
3310 p++;
3311 }
3312 p = phdr_symbols;
3313 while (!p->last) {
3314 if (!p->in_shdr) {
3315 count++;
3316 }
3317 p++;
3318 }
3319 /*Take those symbols that are not present in the shdr but yes in phdr*/
3320 /*This should only should happen with fucked up binaries*/
3321 if (count > 0) {
3322 /*what happens if a shdr says it has only one symbol? we should look anyway into phdr*/
3323 tmp = (RBinElfSymbol*)realloc (ret, (nsym + count + 1) * sizeof (RBinElfSymbol));
3324 if (!tmp) {
3325 result = -1;
3326 goto done;
3327 }
3328 ret = tmp;
3329 ret[nsym--].last = 0;
3330 p = phdr_symbols;
3331 while (!p->last) {
3332 if (!p->in_shdr) {
3333 memcpy (&ret[++nsym], p, sizeof (RBinElfSymbol));
3334 }
3335 p++;
3336 }
3337 ret[nsym + 1].last = 1;
3338 }
3339 *sym = ret;
3340 result = nsym + 1;
3341 goto done;
3342 }
3343 result = nsym;
3344 done:
3345 ht_up_free (phd_offset_map);
3346 ht_up_free (phd_ordinal_map);
3347 return result;
3348 }
3349
3350 static bool is_section_local_sym(ELFOBJ *bin, Elf_(Sym) *sym) {
3351 if (sym->st_name != 0) {
3352 return false;
3353 }
3354 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) {
3355 return false;
3356 }
3357 if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) {
3358 return false;
3359 }
3360 if (!is_shidx_valid (bin, sym->st_shndx)) {
3361 return false;
3362 }
3363 Elf_(Word) sh_name = bin->shdr[sym->st_shndx].sh_name;
3364 return bin->shstrtab && sh_name < bin->shstrtab_size;
3365 }
3366
3367 static void setsymord(ELFOBJ* eobj, ut32 ord, RBinSymbol *ptr) {
3368 if (!eobj->symbols_by_ord || ord >= eobj->symbols_by_ord_size) {
3369 return;
3370 }
3371 r_bin_symbol_free (eobj->symbols_by_ord[ord]);
3372 eobj->symbols_by_ord[ord] = ptr;
3373 }
3374
3375 static void _set_arm_thumb_bits(struct Elf_(r_bin_elf_obj_t) *bin, RBinSymbol **sym) {
3376 int bin_bits = Elf_(r_bin_elf_get_bits) (bin);
3377 RBinSymbol *ptr = *sym;
3378 int len = strlen (ptr->name);
3379 if (ptr->name[0] == '$' && (len >= 2 && !ptr->name[2])) {
3380 switch (ptr->name[1]) {
3381 case 'a' : //arm
3382 ptr->bits = 32;
3383 break;
3384 case 't': //thumb
3385 ptr->bits = 16;
3386 if (ptr->vaddr & 1) {
3387 ptr->vaddr--;
3388 }
3389 if (ptr->paddr & 1) {
3390 ptr->paddr--;
3391 }
3392 break;
3393 case 'd': //data
3394 break;
3395 default:
3396 goto arm_symbol;
3397 }
3398 } else {
3399 arm_symbol:
3400 ptr->bits = bin_bits;
3401 if (bin_bits != 64) {
3402 ptr->bits = 32;
3403 if (ptr->paddr != UT64_MAX) {
3404 if (ptr->vaddr & 1) {
3405 ptr->vaddr--;
3406 ptr->bits = 16;
3407 }
3408 if (ptr->paddr & 1) {
3409 ptr->paddr--;
3410 ptr->bits = 16;
3411 }
3412 }
3413 }
3414 }
3415 }
3416
3417 RBinSymbol *Elf_(_r_bin_elf_convert_symbol)(struct Elf_(r_bin_elf_obj_t) *bin,
3418 struct r_bin_elf_symbol_t *symbol,
3419 const char *namefmt) {
3420 ut64 paddr, vaddr;
3421 RBinSymbol *ptr = NULL;
3422 if (symbol->is_vaddr) {
3423 paddr = UT64_MAX;
3424 vaddr = symbol->offset;
3425 } else {
3426 paddr = symbol->offset;
3427 vaddr = Elf_(r_bin_elf_p2v_new) (bin, paddr);
3428 }
3429
3430 if (!(ptr = R_NEW0 (RBinSymbol))) {
3431 return NULL;
3432 }
3433 ptr->name = symbol->name[0] ? r_str_newf (namefmt, &symbol->name[0]) : strdup ("");
3434 ptr->forwarder = "NONE";
3435 ptr->bind = symbol->bind;
3436 ptr->type = symbol->type;
3437 ptr->is_imported = symbol->is_imported;
3438 ptr->paddr = paddr;
3439 ptr->vaddr = vaddr;
3440 ptr->size = symbol->size;
3441 ptr->ordinal = symbol->ordinal;
3442 // detect thumb
3443 if (bin->ehdr.e_machine == EM_ARM && *ptr->name) {
3444 _set_arm_thumb_bits (bin, &ptr);
3445 }
3446
3447 return ptr;
3448 }
3449
3450 static ut32 hashRBinElfSymbol(const void * obj) {
3451 const RBinElfSymbol *symbol = (const RBinElfSymbol *)obj;
3452 int hash = sdb_hash (symbol->name);
3453 hash ^= sdb_hash (symbol->type);
3454 hash ^= (symbol->offset >> 32);
3455 hash ^= (symbol->offset & 0xffffffff);
3456 return hash;
3457 }
3458
3459 static int cmp_RBinElfSymbol(const RBinElfSymbol *a, const RBinElfSymbol *b) {
3460 int result = 0;
3461 if (a->offset != b->offset) {
3462 return 1;
3463 }
3464 result = strcmp(a->name, b->name);
3465 if (result != 0) {
3466 return result;
3467 }
3468 return strcmp(a->type, b->type);
3469 }
3470
3471 // TODO: return RList<RBinSymbol*> .. or run a callback with that symbol constructed, so we don't have to do it twice
3472 static RBinElfSymbol* Elf_(_r_bin_elf_get_symbols_imports)(ELFOBJ *bin, int type) {
3473 ut32 shdr_size;
3474 int tsize, nsym, ret_ctr = 0, i, j, r, k, newsize;
3475 ut64 toffset;
3476 ut32 size = 0;
3477 RBinElfSymbol *ret = NULL, *import_ret = NULL;
3478 RBinSymbol *import_sym_ptr = NULL;
3479 size_t ret_size = 0, prev_ret_size = 0, import_ret_ctr = 0;
3480 Elf_(Shdr) *strtab_section = NULL;
3481 Elf_(Sym) *sym = NULL;
3482 ut8 s[sizeof (Elf_(Sym))] = { 0 };
3483 char *strtab = NULL;
3484 HtPP *symbol_map = NULL;
3485 HtPPOptions symbol_map_options = {
3486 .cmp = (HtPPListComparator)cmp_RBinElfSymbol,
3487 .hashfn = hashRBinElfSymbol,
3488 .dupkey = NULL,
3489 .calcsizeK = NULL,
3490 .calcsizeV = NULL,
3491 .freefn = NULL,
3492 .elem_size = sizeof (HtPPKv),
3493 };
3494
3495 if (!bin || !bin->shdr || !bin->ehdr.e_shnum || bin->ehdr.e_shnum == 0xffff) {
3496 return Elf_(get_phdr_symbols) (bin, type);
3497 }
3498 if (!UT32_MUL (&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) {
3499 return false;
3500 }
3501 if (shdr_size + 8 > bin->size) {
3502 return false;
3503 }
3504 for (i = 0; i < bin->ehdr.e_shnum; i++) {
3505 if (((type & R_BIN_ELF_SYMTAB_SYMBOLS) && bin->shdr[i].sh_type == SHT_SYMTAB) ||
3506 ((type & R_BIN_ELF_DYNSYM_SYMBOLS) && bin->shdr[i].sh_type == SHT_DYNSYM)) {
3507 if (bin->shdr[i].sh_link < 1) {
3508 /* oops. fix out of range pointers */
3509 continue;
3510 }
3511 // hack to avoid asan cry
3512 if ((bin->shdr[i].sh_link * sizeof(Elf_(Shdr))) >= shdr_size) {
3513 /* oops. fix out of range pointers */
3514 continue;
3515 }
3516 strtab_section = &bin->shdr[bin->shdr[i].sh_link];
3517 if (strtab_section->sh_size > ST32_MAX || strtab_section->sh_size+8 > bin->size) {
3518 bprintf ("size (syms strtab)");
3519 free (ret);
3520 free (strtab);
3521 return NULL;
3522 }
3523 if (!strtab) {
3524 if (!(strtab = (char *)calloc (1, 8 + strtab_section->sh_size))) {
3525 bprintf ("malloc (syms strtab)");
3526 goto beach;
3527 }
3528 if (strtab_section->sh_offset > bin->size ||
3529 strtab_section->sh_offset + strtab_section->sh_size > bin->size) {
3530 goto beach;
3531 }
3532 if (r_buf_read_at (bin->b, strtab_section->sh_offset,
3533 (ut8*)strtab, strtab_section->sh_size) == -1) {
3534 bprintf ("read (syms strtab)\n");
3535 goto beach;
3536 }
3537 }
3538
3539 newsize = 1 + bin->shdr[i].sh_size;
3540 if (newsize < 0 || newsize > bin->size) {
3541 bprintf ("invalid shdr %d size\n", i);
3542 goto beach;
3543 }
3544 nsym = (int)(bin->shdr[i].sh_size / sizeof (Elf_(Sym)));
3545 if (nsym < 0) {
3546 goto beach;
3547 }
3548 {
3549 ut64 sh_begin = bin->shdr[i].sh_offset;
3550 ut64 sh_end = sh_begin + bin->shdr[i].sh_size;
3551 if (sh_begin > bin->size) {
3552 goto beach;
3553 }
3554 if (sh_end > bin->size) {
3555 st64 newshsize = bin->size - sh_begin;
3556 nsym = (int)(newshsize / sizeof (Elf_(Sym)));
3557 }
3558 }
3559 if (!(sym = (Elf_(Sym) *)calloc (nsym, sizeof (Elf_(Sym))))) {
3560 bprintf ("calloc (syms)");
3561 goto beach;
3562 }
3563 if (!UT32_MUL (&size, nsym, sizeof (Elf_(Sym)))) {
3564 goto beach;
3565 }
3566 if (size < 1 || size > bin->size) {
3567 goto beach;
3568 }
3569 if (bin->shdr[i].sh_offset > bin->size) {
3570 goto beach;
3571 }
3572 if (bin->shdr[i].sh_offset + size > bin->size) {
3573 goto beach;
3574 }
3575 for (j = 0; j < nsym; j++) {
3576 int k = 0;
3577 r = r_buf_read_at (bin->b, bin->shdr[i].sh_offset + j * sizeof (Elf_(Sym)), s, sizeof (Elf_(Sym)));
3578 if (r < 1) {
3579 bprintf ("read (sym)\n");
3580 goto beach;
3581 }
3582 #if R_BIN_ELF64
3583 sym[j].st_name = READ32 (s, k);
3584 sym[j].st_info = READ8 (s, k);
3585 sym[j].st_other = READ8 (s, k);
3586 sym[j].st_shndx = READ16 (s, k);
3587 sym[j].st_value = READ64 (s, k);
3588 sym[j].st_size = READ64 (s, k);
3589 #else
3590 sym[j].st_name = READ32 (s, k);
3591 sym[j].st_value = READ32 (s, k);
3592 sym[j].st_size = READ32 (s, k);
3593 sym[j].st_info = READ8 (s, k);
3594 sym[j].st_other = READ8 (s, k);
3595 sym[j].st_shndx = READ16 (s, k);
3596 #endif
3597 }
3598 ret = realloc (ret, (ret_size + nsym) * sizeof (RBinElfSymbol));
3599 if (!ret) {
3600 bprintf ("Cannot allocate %d symbols\n", nsym);
3601 goto beach;
3602 }
3603 memset (ret + ret_size, 0, nsym * sizeof (RBinElfSymbol));
3604 prev_ret_size = ret_size;
3605 ret_size += nsym;
3606 symbol_map = ht_pp_new_opt (&symbol_map_options);
3607 for (k = 0; k < prev_ret_size; k++) {
3608 if (ret[k].name[0]) {
3609 ht_pp_insert (symbol_map, ret + k, ret + k);
3610 }
3611 }
3612 for (k = 1; k < nsym; k++) {
3613 bool is_sht_null = false;
3614 bool is_vaddr = false;
3615 bool is_imported = false;
3616 if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3617 if (sym[k].st_value) {
3618 toffset = sym[k].st_value;
3619 } else if ((toffset = get_import_addr (bin, k)) == -1) {
3620 toffset = 0;
3621 }
3622 tsize = 16;
3623 is_imported = sym[k].st_shndx == STN_UNDEF;
3624 } else {
3625 tsize = sym[k].st_size;
3626 toffset = (ut64)sym[k].st_value;
3627 is_sht_null = sym[k].st_shndx == SHT_NULL;
3628 }
3629 if (is_bin_etrel (bin)) {
3630 if (sym[k].st_shndx < bin->ehdr.e_shnum) {
3631 ret[ret_ctr].offset = sym[k].st_value + bin->shdr[sym[k].st_shndx].sh_offset;
3632 }
3633 } else {
3634 ret[ret_ctr].offset = Elf_(r_bin_elf_v2p_new) (bin, toffset);
3635 if (ret[ret_ctr].offset == UT64_MAX) {
3636 ret[ret_ctr].offset = toffset;
3637 is_vaddr = true;
3638 }
3639 }
3640 ret[ret_ctr].size = tsize;
3641 if (sym[k].st_name + 1 > strtab_section->sh_size) {
3642 bprintf ("index out of strtab range\n");
3643 continue;
3644 }
3645 {
3646 int st_name = sym[k].st_name;
3647 int maxsize = R_MIN (r_buf_size (bin->b), strtab_section->sh_size);
3648 if (is_section_local_sym (bin, &sym[k])) {
3649 const char *shname = &bin->shstrtab[bin->shdr[sym[k].st_shndx].sh_name];
3650 r_str_ncpy (ret[ret_ctr].name, shname, ELF_STRING_LENGTH);
3651 } else if (st_name <= 0 || st_name >= maxsize) {
3652 ret[ret_ctr].name[0] = 0;
3653 } else {
3654 r_str_ncpy(ret[ret_ctr].name, &strtab[st_name], ELF_STRING_LENGTH);
3655 ret[ret_ctr].type = type2str (bin, &ret[ret_ctr], &sym[k]);
3656
3657 if (ht_pp_find (symbol_map, &ret[ret_ctr], NULL)) {
3658 memset (ret + ret_ctr, 0, sizeof (RBinElfSymbol));
3659 continue;
3660 }
3661 }
3662 }
3663 ret[ret_ctr].ordinal = k;
3664 ret[ret_ctr].name[ELF_STRING_LENGTH - 2] = '\0';
3665 fill_symbol_bind_and_type (bin, &ret[ret_ctr], &sym[k]);
3666 ret[ret_ctr].is_sht_null = is_sht_null;
3667 ret[ret_ctr].is_vaddr = is_vaddr;
3668 ret[ret_ctr].last = 0;
3669 ret[ret_ctr].is_imported = is_imported;
3670 ret_ctr++;
3671 if (type == R_BIN_ELF_IMPORT_SYMBOLS && is_imported) {
3672 import_ret_ctr++;
3673 }
3674 }
3675 R_FREE (strtab);
3676 R_FREE (sym);
3677 ht_pp_free (symbol_map);
3678 symbol_map = NULL;
3679 if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3680 break;
3681 }
3682 }
3683 }
3684 if (!ret) {
3685 return Elf_(get_phdr_symbols) (bin, type);
3686 }
3687 ret[ret_ctr].last = 1; // ugly dirty hack :D
3688 int max = -1;
3689 RBinElfSymbol *aux = NULL;
3690 nsym = Elf_(fix_symbols) (bin, ret_ctr, type, &ret);
3691 if (nsym == -1) {
3692 goto beach;
3693 }
3694
3695 // Elf_(fix_symbols) may find additional symbols, some of which could be
3696 // imported symbols. Let's reserve additional space for them.
3697 r_warn_if_fail (nsym >= ret_ctr);
3698 import_ret_ctr += nsym - ret_ctr;
3699
3700 aux = ret;
3701 while (!aux->last) {
3702 if ((int)aux->ordinal > max) {
3703 max = aux->ordinal;
3704 }
3705 aux++;
3706 }
3707 nsym = max;
3708 if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3709 R_FREE (bin->imports_by_ord);
3710 bin->imports_by_ord_size = nsym + 1;
3711 bin->imports_by_ord = (RBinImport**)calloc (R_MAX (1, nsym + 1), sizeof (RBinImport*));
3712 R_FREE (bin->symbols_by_ord);
3713 bin->symbols_by_ord_size = nsym + 1;
3714 bin->symbols_by_ord = (RBinSymbol**)calloc (R_MAX (1, nsym + 1), sizeof (RBinSymbol*));
3715 import_ret = calloc (import_ret_ctr + 1, sizeof (RBinElfSymbol));
3716 if (!import_ret) {
3717 bprintf ("Cannot allocate %d symbols\n", nsym);
3718 goto beach;
3719 }
3720 import_ret_ctr = 0;
3721 i = -1;
3722 while (!ret[++i].last) {
3723 if (!(import_sym_ptr = Elf_(_r_bin_elf_convert_symbol) (bin, &ret[i], "%s"))) {
3724 continue;
3725 }
3726 setsymord (bin, import_sym_ptr->ordinal, import_sym_ptr);
3727 if (ret[i].is_imported) {
3728 memcpy (&import_ret[import_ret_ctr], &ret[i], sizeof (RBinElfSymbol));
3729 ++import_ret_ctr;
3730 }
3731 }
3732 import_ret[import_ret_ctr].last = 1;
3733 R_FREE (ret);
3734 return import_ret;
3735 }
3736 return ret;
3737 beach:
3738 free (ret);
3739 free (sym);
3740 free (strtab);
3741 ht_pp_free (symbol_map);
3742 return NULL;
3743 }
3744
3745 RBinElfSymbol *Elf_(r_bin_elf_get_symbols)(ELFOBJ *bin) {
3746 if (!bin->g_symbols) {
3747 bin->g_symbols = Elf_(_r_bin_elf_get_symbols_imports) (bin, R_BIN_ELF_ALL_SYMBOLS);
3748 }
3749 return bin->g_symbols;
3750 }
3751
3752 RBinElfSymbol *Elf_(r_bin_elf_get_imports)(ELFOBJ *bin) {
3753 if (!bin->g_imports) {
3754 bin->g_imports = Elf_(_r_bin_elf_get_symbols_imports) (bin, R_BIN_ELF_IMPORT_SYMBOLS);
3755 }
3756 return bin->g_imports;
3757 }
3758
3759 RBinElfField* Elf_(r_bin_elf_get_fields)(ELFOBJ *bin) {
3760 RBinElfField *ret = NULL;
3761 int i = 0, j;
3762 if (!bin || !(ret = calloc ((bin->ehdr.e_phnum + 3 + 1), sizeof (RBinElfField)))) {
3763 return NULL;
3764 }
3765 strncpy (ret[i].name, "ehdr", ELF_STRING_LENGTH);
3766 ret[i].offset = 0;
3767 ret[i++].last = 0;
3768 strncpy (ret[i].name, "shoff", ELF_STRING_LENGTH);
3769 ret[i].offset = bin->ehdr.e_shoff;
3770 ret[i++].last = 0;
3771 strncpy (ret[i].name, "phoff", ELF_STRING_LENGTH);
3772 ret[i].offset = bin->ehdr.e_phoff;
3773 ret[i++].last = 0;
3774 for (j = 0; bin->phdr && j < bin->ehdr.e_phnum; i++, j++) {
3775 snprintf (ret[i].name, ELF_STRING_LENGTH, "phdr_%i", j);
3776 ret[i].offset = bin->phdr[j].p_offset;
3777 ret[i].last = 0;
3778 }
3779 ret[i].last = 1;
3780 return ret;
3781 }
3782
3783 void Elf_(r_bin_elf_free)(ELFOBJ* bin) {
3784 if (!bin) {
3785 return;
3786 }
3787 free (bin->phdr);
3788 free (bin->shdr);
3789 free (bin->strtab);
3790 free (bin->shstrtab);
3791 free (bin->dynstr);
3792 r_vector_fini (&bin->dyn_info.dt_needed);
3793 //free (bin->strtab_section);
3794 size_t i;
3795 if (bin->imports_by_ord) {
3796 for (i = 0; i<bin->imports_by_ord_size; i++) {
3797 free (bin->imports_by_ord[i]);
3798 }
3799 free (bin->imports_by_ord);
3800 }
3801 if (bin->symbols_by_ord) {
3802 for (i = 0; i<bin->symbols_by_ord_size; i++) {
3803 r_bin_symbol_free (bin->symbols_by_ord[i]);
3804 }
3805 free (bin->symbols_by_ord);
3806 }
3807 r_buf_free (bin->b);
3808 if (bin->g_symbols != bin->phdr_symbols) {
3809 R_FREE (bin->phdr_symbols);
3810 }
3811 if (bin->g_imports != bin->phdr_imports) {
3812 R_FREE (bin->phdr_imports);
3813 }
3814 R_FREE (bin->g_sections);
3815 R_FREE (bin->g_symbols);
3816 R_FREE (bin->g_imports);
3817 R_FREE (bin->g_relocs);
3818 ht_up_free (bin->rel_cache);
3819 bin->rel_cache = NULL;
3820 free (bin);
3821 }
3822
3823 ELFOBJ* Elf_(r_bin_elf_new_buf)(RBuffer *buf, bool verbose) {
3824 ELFOBJ *bin = R_NEW0 (ELFOBJ);
3825 if (bin) {
3826 bin->kv = sdb_new0 ();
3827 bin->size = r_buf_size (buf);
3828 bin->verbose = verbose;
3829 bin->b = r_buf_ref (buf);
3830 if (!elf_init (bin)) {
3831 Elf_(r_bin_elf_free) (bin);
3832 return NULL;
3833 }
3834 }
3835 return bin;
3836 }
3837
3838 static int is_in_pphdr(Elf_(Phdr) * p, ut64 addr) {
3839 return addr >= p->p_offset && addr < p->p_offset + p->p_filesz;
3840 }
3841
3842 static int is_in_vphdr(Elf_(Phdr) * p, ut64 addr) {
3843 return addr >= p->p_vaddr && addr < p->p_vaddr + p->p_filesz;
3844 }
3845
3846 /* Deprecated temporarily. Use r_bin_elf_p2v_new in new code for now. */
3847 ut64 Elf_(r_bin_elf_p2v) (ELFOBJ *bin, ut64 paddr) {
3848 size_t i;
3849
3850 r_return_val_if_fail (bin, 0);
3851 if (!bin->phdr) {
3852 if (is_bin_etrel (bin)) {
3853 return bin->baddr + paddr;
3854 }
3855 return paddr;
3856 }
3857 for (i = 0; i < bin->ehdr.e_phnum; i++) {
3858 Elf_(Phdr) *p = &bin->phdr[i];
3859 if (p->p_type == PT_LOAD && is_in_pphdr (p, paddr)) {
3860 if (!p->p_vaddr && !p->p_offset) {
3861 continue;
3862 }
3863 return p->p_vaddr + paddr - p->p_offset;
3864 }
3865 }
3866
3867 return paddr;
3868 }
3869
3870 /* Deprecated temporarily. Use r_bin_elf_v2p_new in new code for now. */
3871 ut64 Elf_(r_bin_elf_v2p) (ELFOBJ *bin, ut64 vaddr) {
3872 r_return_val_if_fail (bin, 0);
3873 if (!bin->phdr) {
3874 if (is_bin_etrel (bin)) {
3875 return vaddr - bin->baddr;
3876 }
3877 return vaddr;
3878 }
3879
3880 size_t i;
3881 for (i = 0; i < bin->ehdr.e_phnum; i++) {
3882 Elf_(Phdr) *p = &bin->phdr[i];
3883 if (p->p_type == PT_LOAD && is_in_vphdr (p, vaddr)) {
3884 if (!p->p_offset && !p->p_vaddr) {
3885 continue;
3886 }
3887 return p->p_offset + vaddr - p->p_vaddr;
3888 }
3889 }
3890 return vaddr;
3891 }
3892
3893 /* converts a physical address to the virtual address, looking
3894 * at the program headers in the binary bin */
3895 ut64 Elf_(r_bin_elf_p2v_new) (ELFOBJ *bin, ut64 paddr) {
3896 size_t i;
3897
3898 r_return_val_if_fail (bin, UT64_MAX);
3899 if (!bin->phdr) {
3900 if (is_bin_etrel (bin)) {
3901 return bin->baddr + paddr;
3902 }
3903 return UT64_MAX;
3904 }
3905 for (i = 0; i < bin->ehdr.e_phnum; i++) {
3906 Elf_(Phdr) *p = &bin->phdr[i];
3907 if (p->p_type == PT_LOAD && is_in_pphdr (p, paddr)) {
3908 return p->p_vaddr + paddr - p->p_offset;
3909 }
3910 }
3911
3912 return UT64_MAX;
3913 }
3914
3915 /* converts a virtual address to the relative physical address, looking
3916 * at the program headers in the binary bin */
3917 ut64 Elf_(r_bin_elf_v2p_new) (ELFOBJ *bin, ut64 vaddr) {
3918 size_t i;
3919
3920 r_return_val_if_fail (bin, UT64_MAX);
3921 if (!bin->phdr) {
3922 if (is_bin_etrel (bin)) {
3923 return vaddr - bin->baddr;
3924 }
3925 return UT64_MAX;
3926 }
3927 for (i = 0; i < bin->ehdr.e_phnum; i++) {
3928 Elf_(Phdr) *p = &bin->phdr[i];
3929 if (p->p_type == PT_LOAD && is_in_vphdr (p, vaddr)) {
3930 return p->p_offset + vaddr - p->p_vaddr;
3931 }
3932 }
3933 return UT64_MAX;
3934 }
3935
3936 static bool get_nt_file_maps (ELFOBJ *bin, RList *core_maps) {
3937 ut16 ph, ph_num = bin->ehdr.e_phnum;
3938
3939 for (ph = 0; ph < ph_num; ph++) {
3940 Elf_(Phdr) *p = &bin->phdr[ph];
3941 if (p->p_type == PT_NOTE) {
3942 int bits = Elf_(r_bin_elf_get_bits)(bin);
3943 int elf_nhdr_size = (bits == 64) ? sizeof (Elf64_Nhdr) : sizeof (Elf32_Nhdr);
3944 int size_of = (bits == 64) ? sizeof (ut64) : sizeof (ut32);
3945 void *elf_nhdr = calloc (elf_nhdr_size, 1);
3946 ut64 offset = 0;
3947 bool found = false;
3948
3949 while (!found) {
3950 int ret;
3951 ut32 n_descsz, n_namesz, n_type;
3952 ret = r_buf_read_at (bin->b,
3953 bin->phdr[ph].p_offset + offset,
3954 elf_nhdr, elf_nhdr_size);
3955 if (ret != elf_nhdr_size) {
3956 eprintf ("Cannot read more NOTES header from CORE\n");
3957 free (elf_nhdr);
3958 goto fail;
3959 }
3960 if (bits == 64) {
3961 n_descsz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_descsz);
3962 n_namesz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_namesz);
3963 n_type = ((Elf64_Nhdr *)elf_nhdr)->n_type;
3964 } else {
3965 n_descsz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_descsz);
3966 n_namesz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_namesz);
3967 n_type = ((Elf32_Nhdr *)elf_nhdr)->n_type;
3968 }
3969
3970 if (n_type == NT_FILE) {
3971 found = true;
3972 offset += elf_nhdr_size + n_namesz;
3973 free (elf_nhdr);
3974 } else {
3975 offset += elf_nhdr_size + n_descsz + n_namesz;
3976 }
3977 }
3978 ut64 i = bin->phdr[ph].p_offset + offset;
3979 ut64 n_maps;
3980 if (bits == 64) {
3981 n_maps = BREAD64 (bin->b, i);
3982 (void)BREAD64 (bin->b, i);
3983 } else {
3984 n_maps = BREAD32 (bin->b, i);
3985 (void)BREAD32 (bin->b, i);
3986 }
3987 ut64 jump = ((size_of * 3) * n_maps) + i;
3988 int len_str = 0;
3989 while (n_maps > 0) {
3990 ut64 addr;
3991 if (bits == 64) {
3992 addr = BREAD64 (bin->b, i);
3993 } else {
3994 addr = BREAD32 (bin->b, i);
3995 }
3996 if (addr == UT64_MAX) {
3997 break;
3998 }
3999 char str[512] = {0};
4000 r_buf_read_at (bin->b, jump + len_str, (ut8*)str, sizeof (str) - 1);
4001 str[sizeof (str) - 1] = 0; // null terminate string
4002 RListIter *iter;
4003 RBinMap *p;
4004 r_list_foreach (core_maps, iter, p) {
4005 if (p->addr == addr) {
4006 p->file = strdup (str);
4007 }
4008 }
4009 len_str += strlen (str) + 1;
4010 n_maps--;
4011 i += (size_of * 2);
4012 }
4013 }
4014 }
4015
4016 return true;
4017 fail:
4018 return false;
4019 }
4020
4021 static void r_bin_elf_map_free(RBinMap *map) {
4022 if (map) {
4023 free (map->file);
4024 free (map);
4025 }
4026 }
4027
4028 RList *Elf_(r_bin_elf_get_maps)(ELFOBJ *bin) {
4029 ut16 ph, ph_num = bin->ehdr.e_phnum; //Skip PT_NOTE
4030 if (!bin->phdr) {
4031 return NULL;
4032 }
4033 RList *maps = r_list_newf ((RListFree)r_bin_elf_map_free);
4034 for (ph = 0; ph < ph_num; ph++) {
4035 Elf_(Phdr) *p = &bin->phdr[ph];
4036 if (p->p_type == PT_LOAD) {
4037 RBinMap *map = R_NEW0 (RBinMap);
4038 if (map) {
4039 map->addr = p->p_vaddr;
4040 map->size = p->p_memsz;
4041 map->perms = p->p_flags;
4042 map->offset = p->p_offset;
4043 map->file = NULL;
4044 r_list_append (maps, map);
4045 }
4046 }
4047 }
4048
4049 if (!r_list_empty (maps)) {
4050 if (!get_nt_file_maps (bin, maps)) {
4051 eprintf ("Could not retrieve the names of all maps from NT_FILE\n");
4052 }
4053 }
4054
4055 return maps;
4056 }
4057
4058 char *Elf_(r_bin_elf_compiler)(ELFOBJ *bin) {
4059 RBinElfSection *section = get_section_by_name (bin, ".comment");
4060 if (!section) {
4061 return NULL;
4062 }
4063 ut64 off = section->offset;
4064 ut32 sz = R_MIN (section->size, 128);
4065 if (sz < 1) {
4066 return NULL;
4067 }
4068 char *buf = malloc (sz + 1);
4069 if (!buf) {
4070 return NULL;
4071 }
4072 if (r_buf_read_at (bin->b, off, (ut8*)buf, sz) < 1) {
4073 free (buf);
4074 return NULL;
4075 }
4076 buf[sz] = 0;
4077 const size_t buflen = strlen (buf);
4078 char *nullbyte = buf + buflen;
4079 if (buflen != sz && nullbyte[1] && buflen < sz) {
4080 nullbyte[0] = ' ';
4081 }
4082 buf[sz] = 0;
4083 r_str_trim (buf);
4084 char * res = r_str_escape (buf);
4085 free (buf);
4086 return res;
4087 }
4088
4089 bool Elf_(r_bin_elf_is_executable)(ELFOBJ *bin) {
4090 const int t = bin->ehdr.e_type;
4091 return t == ET_EXEC || t == ET_DYN;
4092 }
4093