struct _list * elf64_entries (const struct _buffer * buffer) { if (elf64_check(buffer)) return NULL; Elf64_Ehdr * ehdr = elf64_ehdr(buffer); if (ehdr == NULL) return NULL; struct _list * entries = list_create(); struct _index * index = index_create(ehdr->e_entry); list_append(entries, index); object_delete(index); size_t shdr_i; for (shdr_i = 0; shdr_i < ehdr->e_shnum; shdr_i++) { size_t sym_i = 0; Elf64_Sym * sym; while ((sym = elf64_sym(buffer, shdr_i, sym_i++)) != NULL) { if ( (ELF64_ST_TYPE(sym->st_info) == STT_FUNC) && (sym->st_value != 0)) { struct _index * index = index_create(sym->st_value); list_append(entries, index); object_delete(index); } } } return entries; }
/* Load elf64, and check the binary */ r_binfmt_err_e r_binfmt_elf64_load(r_binfmt_s *bin) { if(!elf64_is(bin)) return R_BINFMT_ERR_UNRECOGNIZED; bin->type = R_BINFMT_TYPE_ELF64; bin->arch = elf64_getarch(bin); bin->endian = elf64_getendian(bin); if(bin->arch == R_BINFMT_ARCH_UNDEF) return R_BINFMT_ERR_NOTSUPPORTED; if(bin->endian == R_BINFMT_ENDIAN_UNDEF) return R_BINFMT_ERR_NOTSUPPORTED; if(!elf64_check(bin)) return R_BINFMT_ERR_MALFORMEDFILE; bin->entry = r_binfmt_elf64_getentry(bin); bin->nx = r_binfmt_elf64_check_nx(bin); elf64_load_mlist(bin); return R_BINFMT_ERR_OK; }
struct _arch * elf64_arch (const struct _buffer * buffer) { if (elf64_check(buffer)) return NULL; Elf64_Ehdr * ehdr = elf64_ehdr(buffer); if (ehdr == NULL) return NULL; if (ehdr->e_machine == EM_X86_64) return &arch_amd64; return NULL; }
struct _map * elf64_memory_map (const struct _buffer * buffer) { if (elf64_check(buffer)) return NULL; struct _map * mem_map = map_create(); Elf64_Phdr * phdr; size_t i = 0; while ((phdr = elf64_phdr(buffer, i++)) != NULL) { // create a buffer for this page struct _buffer * buf = buffer_create_null(phdr->p_memsz); // are there contents we need to copy, IN the buffer? if ((phdr->p_filesz > 0) && (phdr->p_offset < buffer->size)) { // get the max size without violating bounds size_t size; if (phdr->p_filesz + phdr->p_offset > buffer->size) size = buffer->size - phdr->p_offset; else size = phdr->p_filesz; memcpy(buf->bytes, &(buffer->bytes[phdr->p_offset]), size); } // set permissions if (phdr->p_flags & PF_X) buf->permissions |= BUFFER_EXECUTE; if (phdr->p_flags & PF_W) buf->permissions |= BUFFER_WRITE; if (phdr->p_flags & PF_R) buf->permissions |= BUFFER_READ; // merge into mem map mem_map_set(mem_map, phdr->p_vaddr, buf); object_delete(buf); } return mem_map; }
int elf64_select (const struct _buffer * buffer) { return elf64_check(buffer) == 1 ? 0 : 1; }