Beispiel #1
0
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;
  }
}
Beispiel #2
0
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,&ltab);

   if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
       (void)elf_end(elf);
   } else {
	ltab->xc_did_elf_begin = 1;
	*ret_tab_ptr = ltab;
   }

   return retstatus;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
/*
 * 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);
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
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);
}
Beispiel #10
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;
}
Beispiel #11
0
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];
}
Beispiel #12
0
/* 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;
}
Beispiel #14
0
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;
}
Beispiel #15
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 "";
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #21
0
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() */
Beispiel #23
0
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;
}
Beispiel #24
0
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);
}
Beispiel #25
0
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;
}
Beispiel #26
0
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);

}
Beispiel #27
0
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, &lte->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;
}
Beispiel #28
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;
}
Beispiel #29
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);
}
Beispiel #30
0
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);
}