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; } }
int xlate_named_init_fd(int fd, const char *section_name, xlate_table_con * ret_tab_ptr) { Elf *elf; xlate_table_con ltab = 0; int retstatus = XLATE_TB_STATUS_NO_ERROR; if(elf_version(EV_CURRENT) == EV_NONE) { return XLATE_TB_STATUS_ELF_VERSION_BAD; } #ifdef HAVE_ELF_C_READ_MMAP elf = elf_begin(fd,ELF_C_READ_MMAP,NULL); #else elf = elf_begin(fd,ELF_C_READ,NULL); #endif if(elf == NULL) { return XLATE_TB_STATUS_ELF_BEGIN_BAD; } retstatus = xlate_named_init_elf(elf,section_name,<ab); if(retstatus != XLATE_TB_STATUS_NO_ERROR) { (void)elf_end(elf); } else { ltab->xc_did_elf_begin = 1; *ret_tab_ptr = ltab; } return retstatus; }
int elf_diff(int fd1, int fd2, char *sections, int verbose) { int i = 0; int retval = ED_SUCCESS; Elf *elf[2]; if ((elf[0] = elf_begin(fd1,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading ELF information from first input file.\n"); return ED_ELFFAIL; } if ((elf[1] = elf_begin(fd2,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading ELF information from second input file.\n"); elf_end(elf[0]); return ED_ELFFAIL; } if (elf[0]->e_ehdrp->e_machine != elf[1]->e_ehdrp->e_machine) { if (verbose) fprintf(stderr, "elfdiff: Input files appear to be for different architectures.\n"); return ED_HDRFAIL; } else if (elf[0]->e_ehdrp->e_type != elf[1]->e_ehdrp->e_type) { if (verbose) fprintf(stderr, "elfdiff: Input files appear to be of different types.\n"); return ED_HDRFAIL; } else { if ((elf[0]->e_ehdrp->e_type == ET_REL)){ if (!(retval = ohdr_diff(elf, verbose))) { retval = shdr_diff(elf, sections, verbose); } } else if ((elf[0]->e_ehdrp->e_type == ET_EXEC) || (elf[0]->e_ehdrp->e_type == ET_DYN)){ if (!(retval = phdr_diff(elf, verbose))) { retval = shdr_diff(elf, sections, verbose); } } else { if(verbose) fprintf(stderr, "elfdiff: Files are of an unsupported type\n"); for (i=0;i<2;i++) { elf_end(elf[i]); } return ED_HDRFAIL; } } for (i=0;i<2;i++) { elf_end(elf[i]); } if (verbose) { if (retval) { fprintf(stderr, "elfdiff: Files do not match\n"); } else { printf("elfdiff: Files match.\n"); } } return retval; }
void get_syms(char *filename, mod_info_t *mi) { int fd; Elf *elf; if ((fd = open(filename, O_RDONLY)) == -1) { perror(filename); exit(ERR_SYSCALL); } if (elf_version(EV_CURRENT) == EV_NONE) { (void) fprintf(stderr, "%s: libelf out of date\n", cmdname); exit(ERR_ELF); } if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { (void) fprintf(stderr, "%s: elf_begin failed\n", cmdname); exit(ERR_ELF); } if (gelf_getclass(elf) != ELFCLASS64) { (void) fprintf(stderr, "%s: unsupported mon.out format for " "this class of object\n", cmdname); exit(ERR_ELF); } mi->txt_origin = get_txtorigin(elf, filename); fetch_symtab(elf, filename, mi); }
/* * get_elf_class - get the target executable elf class * i.e. ELFCLASS64 or ELFCLASS32. */ static int get_elf_class(char *filename) { int elfclass = -1; int elffd = get_executable(filename); Elf *elf; size_t size; char *ident; GElf_Ehdr ehdr; if (elffd < 0) return (elfclass); if (elf_version(EV_CURRENT) == EV_NONE) { (void) close(elffd); return (elfclass); } elf = elf_begin(elffd, ELF_C_READ, (Elf *) 0); /* * verify information in file header */ if (gelf_getehdr(elf, &ehdr) == (GElf_Ehdr *) 0) { close(elffd); return (elfclass); } ident = elf_getident(elf, &size); if (ident[EI_CLASS] == ELFCLASS32) elfclass = ELFCLASS32; if (ident[EI_CLASS] == ELFCLASS64) elfclass = ELFCLASS64; close(elffd); return (elfclass); }
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 int find_elf_core (Dwfl_Module *mod, void **userdata, const char *modname, Dwarf_Addr base, char **file_name, Elf **elfp) { int ret = -1; if (strcmp("[exe]", modname) == 0 || strcmp("[pie]", modname) == 0) { int fd = open(executable_file, O_RDONLY); if (fd < 0) return -1; *file_name = realpath(executable_file, NULL); *elfp = elf_begin(fd, ELF_C_READ_MMAP, NULL); if (*elfp == NULL) { warn("Unable to open executable '%s': %s", executable_file, elf_errmsg(-1)); close(fd); return -1; } ret = fd; } else { ret = dwfl_build_id_find_elf(mod, userdata, modname, base, file_name, elfp); } return ret; }
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; }
int main(int argc, char **argv) { Elf *elf; ctf_file_t *ctfp; int errp, fd; if (ctf_version(CTF_VERSION) == -1) errx(1, "mismatched libctf versions\n"); if (elf_version(EV_CURRENT) == EV_NONE) errx(1, "mismatched libelf versions\n"); if (argc != 2) errx(2, "usage: %s <file>\n", __progname); if ((ctfp = ctf_open(argv[1], &errp)) == NULL) errx(1, "failed to ctf_open file: %s: %s\n", argv[1], ctf_errmsg(errp)); if ((fd = open(argv[1], O_RDONLY)) == -1) errx(1, "could not open %s\n", argv[1]); if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) errx(1, "could not interpret ELF from %s\n", argv[1]); walk_symtab(elf, argv[1], ctfp, check_sym); (void) elf_end(elf); (void) close(fd); return (0); }
bool ElfWriter::initElfHeader() { if (elf_version(EV_CURRENT) == EV_NONE) { logError("ELF library initialization failed"); return false; } m_elf = elf_begin(m_fd, ELF_C_WRITE, 0); if (!m_elf) { logError("Unable to create elf with elf_begin()"); return false; } m_ehdr = elf64_newehdr(m_elf); if (!m_ehdr) { logError("Unable to create elf header with elf64_newehdr()"); return false; } m_ehdr->e_ident[EI_MAG0] = ELFMAG0; m_ehdr->e_ident[EI_MAG1] = ELFMAG1; m_ehdr->e_ident[EI_MAG2] = ELFMAG2; m_ehdr->e_ident[EI_MAG3] = ELFMAG3; m_ehdr->e_ident[EI_CLASS] = ELFCLASS64; m_ehdr->e_ident[EI_DATA] = ELFDATA2LSB; m_ehdr->e_ident[EI_VERSION] = EV_CURRENT; m_ehdr->e_machine = EM_X86_64; m_ehdr->e_type = ET_EXEC; m_ehdr->e_version = EV_CURRENT; return true; }
BinaryFile* ElfArchiveFile::GetMember(int i) { // Sanity checks on the index if (i < 0) return 0; if (i >= m_FileMap.size()) return 0; // Lazy creation. Check to see if already created if (i >= m_Members.size() || (m_Members[i] == 0)) { // Now we have to create one. We set the constructor argument // bArchive to true, so it knows it's an archive member BinaryFile* pBF = new ElfBinaryFile(true); if (pBF == 0) return 0; // Load the file for the user. First find the offset int iOffset = m_Offsets[i]; if (iOffset == 0) return 0; if (elf_rand(m_arf, iOffset) != iOffset) { return 0; } Elf* elf; // Elf handle for the new member if ((elf = elf_begin(m_filedes, ELF_C_READ, m_arf)) == 0) { return 0; } // We have to get our father to load the file, since he is a // friend of class BinaryFile, but we aren't if (PostLoadMember(pBF, elf) == 0) return 0; m_Members[i] = pBF; return pBF; } // Else already seen return m_Members[i]; }
/* 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; }
/* 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; }
ElfCreator *elfcreator_begin(char *path, Elf *elf) { ElfCreator *ctor = NULL; GElf_Ehdr ehdr_mem, *ehdr; GElf_Half machine; if (!(ctor = calloc(1, sizeof(*ctor)))) return NULL; clear(ctor, 0); ctor->path = path; ctor->oldelf = elf; ehdr = gelf_getehdr(elf, &ehdr_mem); machine = ehdr->e_machine; if ((ctor->fd = open(path, O_RDWR|O_CREAT|O_TRUNC, 0755)) < 0) { err: clear(ctor, 1); free(ctor); return NULL; } if (!(ctor->elf = elf_begin(ctor->fd, ELF_C_WRITE_MMAP, elf))) goto err; gelf_newehdr(ctor->elf, gelf_getclass(elf)); gelf_update_ehdr(ctor->elf, ehdr); if (!(ctor->ehdr = gelf_getehdr(ctor->elf, &ctor->ehdr_mem))) goto err; return ctor; }
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 ""; }
int find_symbol(char *fn, struct lsym *lsym, unsigned long baseaddr) { struct lsym *ls; int num = 0; for (ls = lsym; ls->name; ls++) num++; elf_version(EV_CURRENT); int fd = open(fn, O_RDONLY); if (fd < 0) return -1; long ret = -1; Elf *elf = elf_begin(fd, ELF_C_READ, NULL); if (elf == NULL) goto out; GElf_Ehdr header; if (!gelf_getehdr(elf, &header)) goto out_elf; Elf_Scn *section = NULL; int found = 0; while (found < num && (section = elf_nextscn(elf, section)) != 0) { GElf_Shdr shdr, *sh; sh = gelf_getshdr(section, &shdr); if (sh->sh_type == SHT_SYMTAB || sh->sh_type == SHT_DYNSYM) { Elf_Data *data = elf_getdata(section, NULL); GElf_Sym *sym, symbol; int j; unsigned numsym = sh->sh_size / sh->sh_entsize; for (j = 0; j < numsym; j++) { sym = gelf_getsymshndx(data, NULL, j, &symbol, NULL); char *symname = elf_strptr(elf, shdr.sh_link, sym->st_name); for (ls = lsym; ls->name; ls++) { if (!strcmp(symname, ls->name)) { Elf_Scn *oscn = elf_getscn(elf, sym->st_shndx); GElf_Shdr oshdr, *osh; osh = gelf_getshdr(oscn, &oshdr); ls->addr = (sym->st_value - osh->sh_addr) + osh->sh_offset + baseaddr; found++; if (found == num) break; } } } } } if (found == num) ret = 0; out_elf: elf_end(elf); out: close(fd); return ret; }
int nlist(const char *filename, struct nlist *nl) { int result = -1; unsigned oldver; Elf *elf; int fd; if ((oldver = elf_version(EV_CURRENT)) != EV_NONE) { if ((fd = open(filename, O_RDONLY)) != -1) { if ((elf = elf_begin(fd, ELF_C_READ, NULL))) { result = _elf_nlist(elf, nl); elf_end(elf); } close(fd); } elf_version(oldver); } if (result) { while (nl->n_name && *nl->n_name) { nl->n_value = 0; nl++; } } return result; }
static elf_info_s *elf_symbols(int fd) { /* Open Elf */ elf_version(EV_CURRENT); elf_info_s *elf = calloc(1, sizeof (elf_info_s)); elf->elf = elf_begin(fd, ELF_C_READ, NULL); gelf_getehdr(elf->elf, &elf->hdr); /* Iterate through the sections */ Elf_Scn *scn = NULL; while ((scn = elf_nextscn(elf->elf, scn)) != 0) { GElf_Shdr shdr; const char *name; /* get section header */ gelf_getshdr(scn, &shdr); /* get section name */ name = elf_strptr(elf->elf, elf->hdr.e_shstrndx, shdr.sh_name); //LOG(INFO, "Iter on %s", name); if (shdr.sh_type == SHT_DYNSYM) handle_dynsym_section(elf, scn, shdr); else if (shdr.sh_type == SHT_DYNAMIC) handle_dynamic_section(elf, scn, shdr); else if ((shdr.sh_type == SHT_PROGBITS || shdr.sh_type == SHT_NOBITS) && !strcmp(name, ".plt")) handle_plt_section(elf, shdr); else if (!strcmp(name, ".got.plt")) handle_gotplt_section(elf, shdr); } return elf; }
static AsmCtx_t * prepare_binary_output (AsmCtx_t *result, int machine, int klass, int data) { GElf_Ehdr *ehdr; GElf_Ehdr ehdr_mem; /* Create the ELF descriptor for the file. */ result->out.elf = elf_begin (result->fd, ELF_C_WRITE_MMAP, NULL); if (result->out.elf == NULL) { err_libelf: unlink (result->tmp_fname); close (result->fd); free (result); __libasm_seterrno (ASM_E_LIBELF); return NULL; } /* Create the ELF header for the output file. */ if (gelf_newehdr (result->out.elf, klass) == 0) goto err_libelf; ehdr = gelf_getehdr (result->out.elf, &ehdr_mem); /* If this failed we are in trouble. */ assert (ehdr != NULL); /* We create an object file. */ ehdr->e_type = ET_REL; /* Set the ELF version. */ ehdr->e_version = EV_CURRENT; /* Use the machine value the user provided. */ ehdr->e_machine = machine; /* Same for the class and endianness. */ ehdr->e_ident[EI_CLASS] = klass; ehdr->e_ident[EI_DATA] = data; memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); /* Write the ELF header information back. */ (void) gelf_update_ehdr (result->out.elf, ehdr); /* No section so far. */ result->section_list = NULL; /* Initialize the hash table. */ asm_symbol_tab_init (&result->symbol_tab, 67); result->nsymbol_tab = 0; /* And the string tables. */ result->section_strtab = ebl_strtabinit (true); result->symbol_strtab = ebl_strtabinit (true); /* We have no section groups so far. */ result->groups = NULL; result->ngroups = 0; return result; }
Dwarf * dwarf_begin (int fd, Dwarf_Cmd cmd) { Elf *elf; Elf_Cmd elfcmd; Dwarf *result = NULL; switch (cmd) { case DWARF_C_READ: elfcmd = ELF_C_READ_MMAP; break; case DWARF_C_WRITE: elfcmd = ELF_C_WRITE; break; case DWARF_C_RDWR: elfcmd = ELF_C_RDWR; break; default: /* No valid mode. */ __libdw_seterrno (DWARF_E_INVALID_CMD); return NULL; } /* We have to call `elf_version' here since the user might have not done it or initialized libelf with a different version. This would break libdwarf since we are using the ELF data structures in a certain way. */ elf_version (EV_CURRENT); /* Get an ELF descriptor. */ elf = elf_begin (fd, elfcmd, NULL); if (elf == NULL) { /* Test why the `elf_begin" call failed. */ struct stat64 st; if (fstat64 (fd, &st) == 0 && ! S_ISREG (st.st_mode)) __libdw_seterrno (DWARF_E_NO_REGFILE); else if (errno == EBADF) __libdw_seterrno (DWARF_E_INVALID_FILE); else __libdw_seterrno (DWARF_E_IO_ERROR); } else { /* Do the real work now that we have an ELF descriptor. */ result = INTUSE(dwarf_begin_elf) (elf, cmd, NULL); /* If this failed, free the resources. */ if (result == NULL) elf_end (elf); else result->free_elf = true; } return result; }
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; }
int main( int argc, char ** argv ) { int status = 0; int fid = -1; Elf * elfp = NULL; Dwarf_Error error = (Dwarf_Error) NULL; Dwarf_Debug dbg; Dwarf_Cie * cie_data = NULL; Dwarf_Fde * fde_data = NULL; Dwarf_Signed cie_count, fde_count; if( argc != 2 ) { fprintf( stderr, "usage: %s <binary>\n", argv[0] ); return 1; } fid = open( argv[1], O_RDONLY ); if( fid == -1 ) { fprintf( stderr, "failed to open( %s ).\n", argv[1] ); return 4; } if( elf_version( EV_CURRENT ) == EV_NONE ) { fprintf( stderr, "elf version check failed.\n" ); return 6; } #if defined( USE_ELF_POINTER ) elfp = elf_begin( fid, ELF_C_READ, (Elf *)NULL ); if( elfp == NULL ) { fprintf( stderr, "failed to elf_begin().\n" ); return 5; } status = dwarf_elf_init( elfp, DW_DLC_READ, NULL, NULL, & dbg, & error ); if( status != DW_DLV_OK ) { fprintf( stderr, "failed to dwarf_elf_init().\n" ); return 2; } #else status = dwarf_init( fid, DW_DLC_READ, NULL, NULL, & dbg, NULL ); if( status != DW_DLV_OK ) { fprintf( stderr, "failed to dwarf_init().\n" ); return 2; } #endif status = dwarf_get_fde_list_eh( dbg, & cie_data, & cie_count, & fde_data, & fde_count, & error ); if( status != DW_DLV_OK ) { fprintf( stderr, "failed to dwarf_get_fde_list_eh().\n" ); return 3; } return 0; } /* end main() */
static int bpf_object__elf_init(struct bpf_object *obj) { int err = 0; GElf_Ehdr *ep; if (obj_elf_valid(obj)) { pr_warning("elf init: internal error\n"); return -LIBBPF_ERRNO__LIBELF; } if (obj->efile.obj_buf_sz > 0) { /* * obj_buf should have been validated by * bpf_object__open_buffer(). */ obj->efile.elf = elf_memory(obj->efile.obj_buf, obj->efile.obj_buf_sz); } else { obj->efile.fd = open(obj->path, O_RDONLY); if (obj->efile.fd < 0) { pr_warning("failed to open %s: %s\n", obj->path, strerror(errno)); return -errno; } obj->efile.elf = elf_begin(obj->efile.fd, LIBBPF_ELF_C_READ_MMAP, NULL); } if (!obj->efile.elf) { pr_warning("failed to open %s as ELF file\n", obj->path); err = -LIBBPF_ERRNO__LIBELF; goto errout; } if (!gelf_getehdr(obj->efile.elf, &obj->efile.ehdr)) { pr_warning("failed to get EHDR from %s\n", obj->path); err = -LIBBPF_ERRNO__FORMAT; goto errout; } ep = &obj->efile.ehdr; if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) { pr_warning("%s is not an eBPF object file\n", obj->path); err = -LIBBPF_ERRNO__FORMAT; goto errout; } return 0; errout: bpf_object__elf_finish(obj); return err; }
static void set_flag(char *ifile, ulong_t flval) { Elf *elf; Elf_Scn *scn; Elf_Data *data; GElf_Shdr shdr; GElf_Dyn dyn; int fd, secidx, nent, i; (void) elf_version(EV_CURRENT); if ((fd = open(ifile, O_RDWR)) < 0) die("Can't open %s", ifile); if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) elfdie("Can't start ELF for %s", ifile); if ((secidx = findelfsecidx(elf, ".dynamic")) == -1) die("Can't find .dynamic section in %s\n", ifile); if ((scn = elf_getscn(elf, secidx)) == NULL) elfdie("elf_getscn (%d)", secidx); if (gelf_getshdr(scn, &shdr) == NULL) elfdie("gelf_shdr"); if ((data = elf_getdata(scn, NULL)) == NULL) elfdie("elf_getdata"); nent = shdr.sh_size / shdr.sh_entsize; for (i = 0; i < nent; i++) { if (gelf_getdyn(data, i, &dyn) == NULL) elfdie("gelf_getdyn"); if (dyn.d_tag == DT_FLAGS_1) { dyn.d_un.d_val |= (Elf64_Xword)flval; if (gelf_update_dyn(data, i, &dyn) == 0) elfdie("gelf_update_dyn"); break; } } if (i == nent) { die("%s's .dynamic section doesn't have a DT_FLAGS_1 " "field\n", ifile); } if (elf_update(elf, ELF_C_WRITE) == -1) elfdie("Couldn't update %s with changes", ifile); (void) elf_end(elf); (void) close(fd); }
Elf *xelf_begin(int fd, Elf_Cmd cmd, Elf *ref) { Elf *e = elf_begin(fd, cmd, ref); if (e == NULL) { eprintf("elf_begin() failed: %s", elf_errmsg(-1)); exit(EXIT_FAILURE); } return e; }
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); }
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; }
/** * 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; }
int ctf_elffdwrite(ctf_file_t *fp, int ifd, int ofd, int flags) { int ret; Elf *ielf, *oelf; (void) elf_version(EV_CURRENT); if ((ielf = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) return (ctf_set_errno(fp, ECTF_ELF)); if ((oelf = elf_begin(ofd, ELF_C_WRITE, NULL)) == NULL) return (ctf_set_errno(fp, ECTF_ELF)); ret = ctf_write_elf(fp, ielf, oelf, flags); (void) elf_end(ielf); (void) elf_end(oelf); return (ret); }
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); }