int binary_diff(int fd1, int fd2, char *sections, int verbose) { Elf *elf1, *elf2; Elf_Kind kind1, kind2; if (elf_version(EV_CURRENT) == EV_NONE) { if (verbose) fprintf(stderr, "elfdiff: ELF Version mismatch\n"); return ED_ELFFAIL; } if ((elf1 = elf_begin(fd1, ELF_C_READ, NULL)) != NULL) { kind1 = elf_kind(elf1); elf_end(elf1); } else { if (verbose) fprintf(stderr, "elfdiff: Error reading ELF information from first input file.\n"); return ED_NOELF1; } if ((elf2 = elf_begin(fd2, ELF_C_READ, NULL)) != NULL) { kind2 = elf_kind(elf2); elf_end(elf2); } else { if (verbose) fprintf(stderr, "elfdiff: Error reading ELF information from second input file.\n"); return ED_NOELF2; } if ((kind1 == ELF_K_ELF) && (kind2 == ELF_K_ELF)){ return elf_diff (fd1, fd2, sections, verbose); } else if ((kind1 == ELF_K_AR) && (kind2 == ELF_K_AR)) { return ar_diff (fd1, fd2, sections, verbose); } else { if (verbose) fprintf(stderr, "elfdiff: The specified files are not of matching/supported types.\n"); return ED_ELFFAIL; } }
static int read_archive(int fd, Elf *elf, char *file, char *label, read_cb_f *func, void *arg, int require_ctf) { Elf *melf; Elf_Cmd cmd = ELF_C_READ; Elf_Arhdr *arh; int secnum = 1, found = 0; while ((melf = elf_begin(fd, cmd, elf)) != NULL) { int rc = 0; if ((arh = elf_getarhdr(melf)) == NULL) { elfterminate(file, "Can't get archive header for " "member %d", secnum); } /* skip special sections - their names begin with "/" */ if (*arh->ar_name != '/') { size_t memlen = strlen(file) + 1 + strlen(arh->ar_name) + 1 + 1; char *memname = xmalloc(memlen); snprintf(memname, memlen, "%s(%s)", file, arh->ar_name); switch (elf_kind(melf)) { case ELF_K_AR: rc = read_archive(fd, melf, memname, label, func, arg, require_ctf); break; case ELF_K_ELF: rc = read_file(melf, memname, label, func, arg, require_ctf); break; default: terminate("%s: Unknown elf kind %d\n", memname, elf_kind(melf)); } free(memname); } cmd = elf_next(melf); (void) elf_end(melf); secnum++; if (rc < 0) return (rc); else found += rc; } return (found); }
static void process_elf(Elf *elf, char *file, int fd, int member) { Elf_Cmd cmd; Elf *_elf; switch (elf_kind(elf)) { case ELF_K_ELF: /* * This is an ELF file, now attempt to find it's * .comment section and to display it. */ print_symtab(elf, file); break; case ELF_K_AR: /* * Archives contain multiple ELF files, which can each * in turn be examined with libelf. * * The below loop will iterate over each member of the * archive and recursively call process_elf(). */ cmd = ELF_C_READ; while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { Elf_Arhdr *arhdr; char buffer[1024]; arhdr = elf_getarhdr(_elf); /* * Build up file names based off of * 'archivename(membername)'. */ (void) snprintf(buffer, 1024, "%s(%s)", file, arhdr->ar_name); /* * Recursively process the ELF members. */ process_elf(_elf, buffer, fd, 1); cmd = elf_next(_elf); (void) elf_end(_elf); } break; default: if (!member) (void) fprintf(stderr, "%s: unexpected elf_kind(): 0x%x\n", file, elf_kind(elf)); return; } }
/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD. When we return success, FILE->elf and FILE->bias are set up. */ static inline Dwfl_Error open_elf (Dwfl_Module *mod, struct dwfl_file *file) { if (file->elf == NULL) { /* If there was a pre-primed file name left that the callback left behind, try to open that file name. */ if (file->fd < 0 && file->name != NULL) file->fd = TEMP_FAILURE_RETRY (open64 (file->name, O_RDONLY)); if (file->fd < 0) return CBFAIL; file->elf = elf_begin (file->fd, ELF_C_READ_MMAP_PRIVATE, NULL); } if (unlikely (elf_kind (file->elf) != ELF_K_ELF)) { close (file->fd); file->fd = -1; return DWFL_E_BADELF; } GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem); if (ehdr == NULL) { elf_error: close (file->fd); file->fd = -1; return DWFL_E (LIBELF, elf_errno ()); } /* The addresses in an ET_EXEC file are absolute. The lowest p_vaddr of the main file can differ from that of the debug file due to prelink. But that doesn't not change addresses that symbols, debuginfo, or sh_addr of any program sections refer to. */ file->bias = 0; if (mod->e_type != ET_EXEC) for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i) { GElf_Phdr ph_mem; GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem); if (ph == NULL) goto elf_error; if (ph->p_type == PT_LOAD) { file->bias = ((mod->low_addr & -ph->p_align) - (ph->p_vaddr & -ph->p_align)); break; } } mod->e_type = ehdr->e_type; /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN. */ if (mod->e_type == ET_EXEC && file->bias != 0) mod->e_type = ET_DYN; return DWFL_E_NOERROR; }
int ELF_initial(char *input_file){ if(elf_version(EV_CURRENT) == EV_NONE){ fprintf(stderr, "ELF library initialization failed: %s.\n", elf_errmsg(-1)); exit(1); } if((fd = open(input_file, O_RDONLY, 0)) < 0){ fprintf(stderr, "Open \"%s\" failed.\n", input_file); exit(1); } if((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL){ fprintf(stderr, "elf_begin() failed: %s.\n", elf_errmsg(-1)); exit(1); } if(elf_kind(e) != ELF_K_ELF){ fprintf(stderr, "\"%s\" is not an ELF object.\n", input_file); exit(1); } if(gelf_getehdr(e, &ehdr) == NULL){ fprintf(stderr, "getehdr() failed: %s.\n", elf_errmsg(-1)); exit(1); } if(ehdr.e_flags != 2){ fprintf(stderr, "\"%s\" is not an execution file.\n", input_file); exit(1); } phdr_index = 0; // printf("Entry point: 0x%jx\n", ehdr.e_entry); // printf("Flags: %d\n", ehdr.e_flags); return 0; }
std::string get_embedded_repo() { GElf_Shdr shdr; size_t shstrndx; char *name; Elf_Scn *scn; if (elf_version(EV_CURRENT) == EV_NONE) return ""; int fd = open("/proc/self/exe", O_RDONLY, 0); if (fd < 0) return ""; Elf* e = elf_begin(fd, ELF_C_READ, nullptr); if (!e || elf_kind(e) != ELF_K_ELF || !elf_getshstrndx(e, &shstrndx)) { return ""; } scn = nullptr; while ((scn = elf_nextscn(e, scn)) != nullptr) { if (gelf_getshdr(scn, &shdr) != &shdr || !(name = elf_strptr(e, shstrndx , shdr.sh_name))) { return ""; } if (!strcmp("repo", name)) { GElf_Shdr ghdr; if (gelf_getshdr(scn, &ghdr) != &ghdr) return ""; char buf[512]; sprintf(buf, "/proc/self/exe:%lu:%lu", ghdr.sh_offset, ghdr.sh_size); sqlite3_embedded_initialize(nullptr, true); return buf; } } return ""; }
static Elf * get_elf (const gchar *file, gint *fd) { Elf *elf; if (elf_version (EV_CURRENT) == EV_NONE ) return NULL; *fd = g_open (file, O_RDONLY, 0); if (*fd < 0) return NULL; elf = elf_begin (*fd, ELF_C_READ, NULL); if (elf == NULL) { g_close (*fd, NULL); *fd = -1; return NULL; } if (elf_kind (elf) != ELF_K_ELF) { g_close (*fd, NULL); *fd = -1; return NULL; } return elf; }
static inline Dwfl_Error open_elf_file (Elf **elf, int *fd, char **name) { if (*elf == NULL) { /* CBFAIL uses errno if it's set, so clear it first in case we don't set it with an open failure below. */ errno = 0; /* If there was a pre-primed file name left that the callback left behind, try to open that file name. */ if (*fd < 0 && *name != NULL) *fd = TEMP_FAILURE_RETRY (open (*name, O_RDONLY)); if (*fd < 0) return CBFAIL; return __libdw_open_file (fd, elf, true, false); } else if (unlikely (elf_kind (*elf) != ELF_K_ELF)) { elf_end (*elf); *elf = NULL; close (*fd); *fd = -1; return DWFL_E_BADELF; } /* Elf file already open and looks fine. */ return DWFL_E_NOERROR; }
/* Below code adapted from libelf tutorial example */ static u32 extract_functions_internal (const char *str, func_entry *func_list) { Elf *e; Elf_Kind ek; Elf_Scn *scn; Elf_Data *edata; u32 fd, i, symbol_count; GElf_Sym sym; GElf_Shdr shdr; u32 func_count = 0; if(elf_version(EV_CURRENT) == EV_NONE) { printf("Error initializing ELF: %s\n", elf_errmsg(-1)); return -1; } if ((fd = open(str, O_RDONLY, 0)) < 0) { printf("Unable to open %s\n", str); return -1; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { printf("elf_begin failed: %s\n", elf_errmsg(-1)); } ek = elf_kind(e); if(ek != ELF_K_ELF) { printf("not an ELF object"); } else { scn = NULL; edata = NULL; while((scn = elf_nextscn(e, scn)) != NULL) { gelf_getshdr(scn, &shdr); if(shdr.sh_type == SHT_SYMTAB) { edata = elf_getdata(scn, edata); symbol_count = shdr.sh_size / shdr.sh_entsize; for(i = 0; i < symbol_count; i++) { gelf_getsym(edata, i, &sym); if(ELF32_ST_TYPE(sym.st_info) != STT_FUNC) { check_for_end_marker(elf_strptr(e, shdr.sh_link, sym.st_name), sym.st_value); continue; } if(sym.st_size == 0) continue; func_list[func_count].offset = sym.st_value; func_list[func_count++].func_name = strdup(elf_strptr(e, shdr.sh_link, sym.st_name)); if(func_count >= MAXFNS) { printf("Func limit (%"PRId32") reached, please increase MAXFNS & rebuild\n", MAXFNS); raise(SIGABRT); } // printf("%08x %08x\t%s\n", sym.st_value, sym.st_size, elf_strptr(e, shdr.sh_link, sym.st_name)); } } } } elf_end(e); close(fd); return func_count; }
static void test_one(const char *f, Elf *elf, int flags) { char *b = NULL; GElf_Ehdr ehdr; if (elf_kind(elf) != ELF_K_ELF) { if (flags & P_OTHER) goto out_print; return; } if (gelf_getehdr(elf, &ehdr) == NULL) return; if ((flags & P_BUILDID)) { size_t sz; uint8_t *data = get_buildid(elf, &sz); if (data) { b = alloca(sz * 2 + 1); data2hex(data, sz, b); goto out_print; } return; } if ((flags & P_REL) && (ehdr.e_type == ET_REL)) goto out_print; if ((flags & P_EXEC) && (ehdr.e_type == ET_EXEC)) goto out_print; if ((flags & P_DEBUG) && has_debuginfo(elf)) goto out_print; /* arguably should print if P_OTHER, but, nah. */ if (ehdr.e_type != ET_DYN) return; if (has_dt_debug(elf, &ehdr)) { if (flags & P_EXEC) { goto out_print; /* treat PIEs as executables */ } } else if (flags & P_DSO) { goto out_print; } return; out_print: write(1, f, strlen(f)); if (b) { write(1, " ", 1); write(1, b, strlen(b)); } write(1, (flags & P_NEWLINE) ? "\n" : "", 1); }
gboolean is_elf_file (const char *path, gboolean *is_shared, gboolean *is_stripped) { g_autofree char *filename = g_path_get_basename (path); struct stat stbuf; if (lstat (path, &stbuf) == -1) return FALSE; if (!S_ISREG (stbuf.st_mode)) return FALSE; /* Self-extracting .zip files can be ELF-executables, but shouldn't be treated like them - for example, stripping them breaks their operation */ if (g_str_has_suffix (filename, ".zip")) return FALSE; if ((strstr (filename, ".so.") != NULL || g_str_has_suffix (filename, ".so")) || (stbuf.st_mode & 0111) != 0) { glnx_fd_close int fd = -1; fd = open (path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd >= 0) { Elf *elf; GElf_Ehdr ehdr; gboolean res = FALSE; if (elf_version (EV_CURRENT) == EV_NONE ) return FALSE; elf = elf_begin (fd, ELF_C_READ, NULL); if (elf == NULL) return FALSE; if (elf_kind (elf) == ELF_K_ELF && gelf_getehdr (elf, &ehdr)) { if (is_shared) *is_shared = ehdr.e_type == ET_DYN; if (is_stripped) *is_stripped = !elf_has_symtab (elf); res = TRUE; } elf_end (elf); return res; } } return FALSE; }
ElfData::ElfData() { assert(elf_version(EV_CURRENT) != EV_NONE); assert((fd = open(__progname_full, O_RDONLY, 0)) >= 0); assert((e = elf_begin(fd, ELF_C_READ, NULL)) != NULL); assert(elf_kind(e) == ELF_K_ELF); }
/** * perform checks on the initial ELF binary and create an ELF descriptor * to perform direct manipulations within the file. */ int ElfInject::prepareElfBin() { info("prepare ELF binary: %s", bin.name.c_str()); /* open binary file */ bin.fd = open(bin.name.c_str(), O_RDWR, S_IRWXU); if (bin.fd < 0) { error("cannot open %s", bin.name.c_str()); return -1; } /* fstat binary */ if (fstat(bin.fd, &bin.stats)) { error("cannot fstat %s", bin.name.c_str()); return -1; } /* initialize ELF library */ if(elf_version(EV_CURRENT) == EV_NONE ) { error("ELF library initialization failed"); return -1; } /* create elf descriptor */ if ((bin.elf = elf_begin(bin.fd, ELF_C_RDWR_MMAP, NULL)) == NULL) { error("cannot initialize elf"); return -1; } /* check, whether the file is an ELF-file */ if (elf_kind(bin.elf) != ELF_K_ELF) { error("%s is not an ELF file", bin.name.c_str()); return -1; } debug("° correct ELF type"); if (gelf_getclass(bin.elf) != ELFCLASS32) { error("%s is not a 32-bit binary", bin.name.c_str()); return -1; } debug("° compiled for 32-bit systems"); /* allocate space for binary */ // if ((bin.basePtr = (char*)malloc(bin.stats.st_size)) == NULL) { // error("cannot allocate enough memory" << lend ; // } /* create elf descriptor for mem region */ // if ((bin.elfMem = elf_memory(bin.basePtr, bin.stats.st_size)) == NULL) {; // error("cannot initialize elfMem"); // } return 0; }
/* * Process member files of an archive. This function provides * a loop through an archive equivalent the processing of * each_file for individual object files. */ static void print_ar_files(int fd, Elf * elf_file, char *filename) { Elf_Arhdr *p_ar; Elf *arf; Elf_Cmd cmd; Elf_Kind file_type; cmd = ELF_C_READ; archive_name = filename; while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { p_ar = elf_getarhdr(arf); if (p_ar == NULL) { (void) fprintf(stderr, "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); return; } if (p_ar->ar_name[0] == '/') { cmd = elf_next(arf); (void) elf_end(arf); continue; } if (!h_flag & !P_flag) { if (p_flag) (void) printf("\n\n%s[%s]:\n", filename, p_ar->ar_name); else { if (A_flag != 0) (void) printf("\n\n%s%s[%s]:\n", A_header, filename, p_ar->ar_name); else (void) printf("\n\n%s[%s]:\n", filename, p_ar->ar_name); } } file_type = elf_kind(arf); if (file_type == ELF_K_ELF) { process(arf, p_ar->ar_name); } else { (void) fprintf(stderr, gettext( "%s: %s: invalid file type\n"), prog_name, p_ar->ar_name); cmd = elf_next(arf); (void) elf_end(arf); errflag++; continue; } cmd = elf_next(arf); (void) elf_end(arf); } /* end while */ }
static void init_libelf(int *fd, char const* bin) { if ((*fd = open(bin, O_RDONLY, 0)) == -1) exit_error("open() fail"); if (elf_version(EV_CURRENT) == EV_NONE) exit_error("elf_version() fail"); if ((e = elf_begin(*fd, ELF_C_READ, NULL)) == NULL) exit_error("elf_begin() fail"); if (elf_kind(e) != ELF_K_ELF) exit_error("file to execute is not an ELF file"); fd_bak = *fd; }
static Dwfl_Error what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *close_fd) { Dwfl_Error error = DWFL_E_NOERROR; *kind = elf_kind (*elfp); if (unlikely (*kind == ELF_K_NONE)) { if (unlikely (*elfp == NULL)) error = DWFL_E_LIBELF; else { error = decompress (fd, elfp); if (error == DWFL_E_NOERROR) { *close_fd = true; *kind = elf_kind (*elfp); } } } return error; }
uint8_t *load_elf_file(char *elf_file_name, int *size) { uint8_t *buf = NULL; char *id; if (elf_version(EV_CURRENT) == EV_NONE) return NULL; int fd = open(elf_file_name, O_RDONLY , 0); if (fd < 0) { printf("Can't open %s\n", elf_file_name); return NULL; } Elf *elf_object = elf_begin(fd , ELF_C_READ , NULL); if (elf_object == NULL) { printf("Problem while starting ELF parsing\n"); close(fd); return NULL; } if (elf_kind(elf_object) != ELF_K_ELF) { printf("%s is not an ELF file\n", elf_file_name); elf_end(elf_object); close(fd); return NULL; } if (( id = elf_getident (elf_object , NULL )) == NULL ) printf("getident() failed : %s.", elf_errmsg(-1)); if (id[EI_DATA] == ELFDATA2LSB) big_endian = 0; else if (id[EI_DATA] == ELFDATA2MSB) big_endian = 1; else { printf("%s has unknown endianness '%d'\n", elf_file_name, id[EI_DATA]); elf_end(elf_object); close(fd); return NULL; } buf = dump_program_data(elf_object, size); if (buf == NULL) buf = dump_section_data(elf_object, size); elf_end(elf_object); close(fd); return buf; }
void set_pt_flags(int fd, uint16_t pt_flags) { Elf *elf; GElf_Phdr phdr; size_t i, phnum; if(elf_version(EV_CURRENT) == EV_NONE) { PyErr_SetString(PaxError, "set_pt_flags: library out of date"); return; } if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) { PyErr_SetString(PaxError, "set_pt_flags: elf_begin() failed"); return; } if(elf_kind(elf) != ELF_K_ELF) { elf_end(elf); PyErr_SetString(PaxError, "set_pt_flags: elf_kind() failed: this is not an elf file."); return; } elf_getphdrnum(elf, &phnum); for(i=0; i<phnum; i++) { if(gelf_getphdr(elf, i, &phdr) != &phdr) { elf_end(elf); PyErr_SetString(PaxError, "set_pt_flags: gelf_getphdr() failed"); return; } if(phdr.p_type == PT_PAX_FLAGS) { phdr.p_flags = pt_flags; if(!gelf_update_phdr(elf, i, &phdr)) { elf_end(elf); PyErr_SetString(PaxError, "set_pt_flags: gelf_update_phdr() failed"); return; } } } elf_end(elf); }
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) { // If we don't have a valid ELF ID we can just fail. #if TARGET_ELF_ID < 1 return 0; #else // Is the library version incompatible with the header file? if (elf_version(EV_CURRENT) == EV_NONE) { DP("Incompatible ELF library!\n"); return 0; } char *img_begin = (char *)image->ImageStart; char *img_end = (char *)image->ImageEnd; size_t img_size = img_end - img_begin; // Obtain elf handler Elf *e = elf_memory(img_begin, img_size); if (!e) { DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1)); return 0; } // Check if ELF is the right kind if (elf_kind(e) != ELF_K_ELF) { DP("Unexpected ELF type!\n"); return 0; } Elf64_Ehdr *eh64 = elf64_getehdr(e); Elf32_Ehdr *eh32 = elf32_getehdr(e); if (!eh64 && !eh32) { DP("Unable to get machine ID from ELF file!\n"); elf_end(e); return 0; } uint16_t MachineID; if (eh64 && !eh32) MachineID = eh64->e_machine; else if (eh32 && !eh64) MachineID = eh32->e_machine; else { DP("Ambiguous ELF header!\n"); elf_end(e); return 0; } elf_end(e); return MachineID == TARGET_ELF_ID; #endif }
static int read_ctf_common(char *file, char *label, read_cb_f *func, void *arg, int require_ctf) { Elf *elf; int found = 0; int fd; debug(3, "Reading %s (label %s)\n", file, (label ? label : "NONE")); (void) elf_version(EV_CURRENT); if ((fd = open(file, O_RDONLY)) < 0) terminate("%s: Cannot open for reading", file); if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) elfterminate(file, "Cannot read"); switch (elf_kind(elf)) { case ELF_K_AR: found = read_archive(fd, elf, file, label, func, arg, require_ctf); break; case ELF_K_ELF: found = read_file(elf, file, label, func, arg, require_ctf); break; default: terminate("%s: Unknown elf kind %d\n", file, elf_kind(elf)); } (void) elf_end(elf); (void) close(fd); return (found); }
unsigned long long get_elf_entry(const char *path) { Elf *e; Elf_Kind ek; GElf_Ehdr ehdr; unsigned long long entrypoint; if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "Elf library initialization failed.\n"); exit(1); } int fd = open(path, O_RDONLY, 0); if (fd < 0) { fprintf(stderr, "Couldn't open the ELF at %s.\n", path); exit(1); } e = elf_begin(fd, ELF_C_READ, NULL); if (e == NULL) { fprintf(stderr, "elf_begin() failed.\n"); exit(1); } ek = elf_kind(e); if (ek != ELF_K_ELF) { fprintf(stderr, "Bad ELF file.\n"); exit(1); } if (gelf_getehdr(e, &ehdr) == NULL) { fprintf(stderr, "Couldn't get the ELF header.\n"); exit(1); } if (gelf_getclass(e) != ELFCLASS32) { fprintf(stderr, "Not a 32-bit ELF.\n"); exit(1); } entrypoint = ehdr.e_entry; elf_end(e); close(fd); return entrypoint; }
static const value_t * fn_kind(const value_t *this_fn, parser_state_t *state) { const value_t *resval = NULL; value_t *strval = (value_t *)parser_builtin_arg(state, 1); const char *filename; size_t filenamelen; if (value_string_get(strval, &filename, &filenamelen)) { int fd = fe_open(filename, "rb", 0); if (fd < 0) parser_report(state, "couldn't open ELF file to read - %s\n",filename); else { Elf *e = elf_begin(fd, ELF_C_READ, NULL); if (e == NULL) parser_report(state, "couldn't initialize ELF library - %s\n", elf_errmsg(-1)); else { Elf_Kind ek = elf_kind(e); switch (ek) { case ELF_K_AR: resval = value_string_new_measured("archive"); break; case ELF_K_ELF: resval = value_string_new_measured("elf"); break; case ELF_K_NONE: resval = value_string_new_measured("data"); break; default: resval = &value_null; } (void)elf_end(e); } (void)fe_close(fd); } } else parser_report_help(state, this_fn); return resval; }
static const value_t * genfn_with_elfhdr(const value_t *this_fn, parser_state_t *state, int file_arg, elf_hdr_fn_t *elf_fn, void *fn_arg) { const value_t *retval = NULL; value_t *strval = (value_t *)parser_builtin_arg(state, file_arg); const char *filename; size_t filenamelen; if (value_string_get(strval, &filename, &filenamelen)) { int fd = fe_open(filename, "rb", 0); if (fd < 0) parser_report(state, "couldn't open ELF file to read - %s\n",filename); else { Elf *e = elf_begin(fd, ELF_C_READ, NULL); if (e == NULL) parser_report(state, "couldn't initialize ELF library - %s\n", elf_errmsg(-1)); else { Elf_Kind ek = elf_kind(e); if (ek != ELF_K_ELF) parser_report(state, "not an ELF file - %s\n", elf_errmsg(-1)); else { GElf_Ehdr ehdr; if (gelf_getehdr(e, &ehdr) == NULL) parser_report(state, "no execution header in ELF file - %s\n", elf_errmsg(-1)); else { retval = (*elf_fn)(this_fn, state, filename, fd, e, &ehdr, fn_arg); } } (void)elf_end(e); } (void)fe_close(fd); } } else parser_report_help(state, this_fn); return retval; }
/* * Will analyse a file to see if it ELF, other files including ar(1), * core dumps are passed off and treated as flat binary files. Unlike * GNU size in FreeBSD this routine will not treat ELF object from * different archs as flat binary files(has to overridden using -a). */ int handle_elf(const char *name, int fd) { GElf_Ehdr elfhdr; GElf_Shdr shdr; Elf *elf; Elf_Scn *scn; int rc; rc = RETURN_OK; /* If entire file is choosen, treat it as a binary file */ if (entire_file) return (handle_binary(name, fd)); (void) lseek(fd, (off_t)0, SEEK_SET); elf = elf_begin(fd, ELF_C_READ, NULL); if (elf_kind(elf) != ELF_K_ELF) { (void) elf_end(elf); return (handle_binary(name, fd)); } if (gelf_getehdr(elf, &elfhdr) == NULL) { (void) elf_end(elf); warnx("%s: ELF file could not be processed", name); return (RETURN_SOFTWARE); } if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { (void) elf_end(elf); return (handle_binary(name, fd)); } else { scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) == NULL) continue; if (shdr.sh_type != SHT_NOBITS && (shdr.sh_flags & SHF_ALLOC) != 0) { rc = find_strings(name, shdr.sh_offset, shdr.sh_size); } } } (void) elf_end(elf); return (rc); }
int open_elf(struct ltelf *lte, const char *filename) { lte->fd = open(filename, O_RDONLY); if (lte->fd == -1) return 1; elf_version(EV_CURRENT); #ifdef HAVE_ELF_C_READ_MMAP lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); #else lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); #endif if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", filename); if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) error(EXIT_FAILURE, 0, "\"%s\" is not an ELF executable nor shared library", filename); if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS || lte->ehdr.e_machine != LT_ELF_MACHINE) #ifdef LT_ELF_MACHINE2 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 || lte->ehdr.e_machine != LT_ELF_MACHINE2) #endif #ifdef LT_ELF_MACHINE3 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 || lte->ehdr.e_machine != LT_ELF_MACHINE3) #endif ) error(EXIT_FAILURE, 0, "\"%s\" is ELF from incompatible architecture", filename); return 0; }
/** * Initialize the ELF file for a given executable. * * @param bin bin_info instance * @returns 0 on success, negative value on error. */ static int bin_info_set_elf_file(struct bin_info *bin) { int elf_fd = -1; Elf *elf_file = NULL; if (!bin) { goto error; } elf_fd = open(bin->elf_path, O_RDONLY); if (elf_fd < 0) { elf_fd = -errno; BT_LOGD("Failed to open ELF file: path=\"%s\"", bin->elf_path); goto error; } elf_file = elf_begin(elf_fd, ELF_C_READ, NULL); if (!elf_file) { BT_LOGD("elf_begin() failed: %s.", elf_errmsg(-1)); goto error; } if (elf_kind(elf_file) != ELF_K_ELF) { BT_LOGD("ELF file is not an ELF object: path=\"%s\"", bin->elf_path); goto error; } bin->elf_fd = elf_fd; bin->elf_file = elf_file; return 0; error: if (elf_fd >= 0) { close(elf_fd); elf_fd = -1; } elf_end(elf_file); return elf_fd; }
int main(int argc, char **argv) { int fd; Elf *e; lock_descr_t *lock_tab = NULL; int nb_entry = 0; if (argc < 3) errx ( EXIT_FAILURE , " usage : %s file_name section_name1 [sct_name2 ...]" , argv [0]); char *elf = argv[1]; /* Init and open of the elf file */ if ( elf_version ( EV_CURRENT ) == EV_NONE ) errx ( EXIT_FAILURE , " ELF library initialization failed : %s." , elf_errmsg ( -1)); if (( fd = open ( elf , O_RDONLY , 0)) < 0) errx ( EXIT_FAILURE , " open \" %s \" failed " , elf); if (( e = elf_begin ( fd , ELF_C_READ , NULL )) == NULL ) errx ( EXIT_FAILURE , " elf_begin () failed : %s.", elf_errmsg ( -1)); if ( elf_kind ( e ) != ELF_K_ELF ) errx ( EXIT_FAILURE , " %s is not an ELF object.", elf); /* init debug helper */ debug_helper_t *dh = dh_init(elf); int i; for (i=2 ; i<argc ; i++) { extract_lock_descr(e, argv[i], &lock_tab, &nb_entry); get_dwarf_location(dh, lock_tab, nb_entry); printf("%s:\n", argv[i]); print_lock_descr(lock_tab, nb_entry); printf("\n"); free(lock_tab); lock_tab = NULL; nb_entry = 0; } /* close */ dh_free(dh); elf_end(e); close(fd); return 0; }
static int is_prelinked(int fdno) { int prelinked = 0; #if HAVE_GELF_H && HAVE_LIBELF Elf *elf = NULL; Elf_Scn *scn = NULL; Elf_Data *data = NULL; GElf_Ehdr ehdr; GElf_Shdr shdr; GElf_Dyn dyn; (void) elf_version(EV_CURRENT); if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL || elf_kind(elf) != ELF_K_ELF || gelf_getehdr(elf, &ehdr) == NULL || !(ehdr.e_type == ET_DYN || ehdr.e_type == ET_EXEC)) goto exit; while (!prelinked && (scn = elf_nextscn(elf, scn)) != NULL) { (void) gelf_getshdr(scn, &shdr); if (shdr.sh_type != SHT_DYNAMIC) continue; while (!prelinked && (data = elf_getdata (scn, data)) != NULL) { int maxndx = data->d_size / shdr.sh_entsize; for (int ndx = 0; ndx < maxndx; ++ndx) { (void) gelf_getdyn (data, ndx, &dyn); if (!(dyn.d_tag == DT_GNU_PRELINKED || dyn.d_tag == DT_GNU_LIBLIST)) continue; prelinked = 1; break; } } } exit: if (elf) (void) elf_end(elf); #endif return prelinked; }
struct trap_file_t *open_trap_file(const char *filename) { if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "Cannot initialize ELF library: %s", elf_errmsg(-1)); struct trap_file_t *res = malloc(sizeof(struct trap_file_t)); if (!res) errx(EXIT_FAILURE, "Cannot allocate memory for trap_file_t"); res->fd = open(filename, O_RDONLY, 0); if (res->fd < 0) errx(EXIT_FAILURE, "Cannot open file: %s", filename); res->elf = elf_begin(res->fd, ELF_C_READ, NULL); if (res->elf == NULL) errx(EXIT_FAILURE, "Cannot read ELF file %s: %s", filename, elf_errmsg(-1)); if (elf_kind(res->elf) != ELF_K_ELF) errx(EXIT_FAILURE, "File is not ELF: %s", filename); return res; }
static int read_ehdr(struct elf32_info *info, FILE *in) { /* Read and check the ELF header */ char *id; rewind(in); if (elf_version(EV_CURRENT) == EV_NONE) { printc_err("elf32: elf_version failed"); return -1; } /* ELF_C_READ_MMAP* is not available in Mac OS X macports libelf @0.8.10_1 */ info->elf = elf_begin(fileno(in), ELF_C_READ, NULL); if (info->elf == 0) { printc_err("elf32: elf_begin failed"); return -1; } if (elf_kind(info->elf) != ELF_K_ELF) { printc_err("elf32: elf_kind is not ELF_K_ELF"); return -1; } if (gelf_getehdr(info->elf, &info->file_ehdr) == 0) { printc_err("elf32: couldn't get ELF header"); return -1; } if ((id = elf_getident(info->elf, NULL)) == 0) { printc_err("elf32: couldn't getident"); return -1; } if (memcmp(id, elf32_id, sizeof(elf32_id))) { printc_err("elf32: not an ELF32 file\n"); return -1; } return 0; }