Пример #1
0
int main(int argc,char *argv[])
{
	if(argc<2) {
		printf("Usage: %s [elf path]\n",argv[0]);
		return 0;
	}

	int fd = open(argv[1],OFLAGS);
	if(fd<0) {
		fprintf(stderr,"Unable to open elf file: %s\n",argv[1]);
		return 1;
	}

	elf_version(EV_CURRENT);
	
	Elf *elf = elf_begin(fd,ELF_C_READ,NULL);
	if(!elf) {
		fprintf(stderr,"libelf could not read elf file: %s\n",elf_errmsg(elf_errno()));
		return 1;
	}

	Elf_Scn *prx = getSection(elf,".sys_proc_prx_param");
	if(!prx || memcmp(elf_getdata(prx,NULL)->d_buf,prx_magic,sizeof(prx_magic))) {
		fprintf(stderr,"elf does not have a prx parameter section.\n");
		return 1;
	}

	Elf_Scn *stubsection = getSection(elf,".lib.stub");
	Elf_Data *stubdata = elf_getdata(stubsection,NULL);
	Elf64_Shdr *stubshdr = elf64_getshdr(stubsection);
	Stub *stubbase = (Stub*)stubdata->d_buf;
	size_t stubcount = stubdata->d_size/sizeof(Stub);
	Elf_Scn *fnidsection = getSection(elf,".rodata.sceFNID");
	Elf64_Shdr *fnidshdr = elf64_getshdr(fnidsection);
	for(Stub *stub = stubbase;stub<stubbase + stubcount;stub++) {
		uint32_t fnid = BE32(stub->fnid);
		uint32_t end = fnidshdr->sh_addr + fnidshdr->sh_size;
		for(Stub *substub = stubbase;substub<(stubbase + stubcount);substub++) {
			if(stub==substub) continue;

			uint32_t newfnid = BE32(substub->fnid);
			if(newfnid>=fnid && newfnid<end) end = newfnid;
		}

		uint16_t fnidcount = (end - fnid)/4;
		if(BE16(stub->imports)!=fnidcount) {
			lseek(fd,stubshdr->sh_offset + (stub - stubbase)*sizeof(Stub)+offsetof(Stub,imports),SEEK_SET);
			fnidcount = BE16(fnidcount);
			if(write(fd,&fnidcount,sizeof(fnidcount))!=sizeof(fnidcount)) {
				printf("Error occurred during write in %s:%d\n",__FILE__,__LINE__);
			}
		}
	}

	Elf_Scn *opdsection = getSection(elf,".opd");
	Elf_Data *opddata = elf_getdata(opdsection,NULL);
	Elf64_Shdr *opdshdr = elf64_getshdr(opdsection);

	Opd64 *opdbase = (Opd64*)opddata->d_buf;
	size_t opdcount = opddata->d_size/sizeof(Opd64);
	for(Opd64 *opd = opdbase;opd<(opdbase + opdcount);opd++) {
		opd->data = BE64(((BE64(opd->func)<<32ULL) | (BE64(opd->rtoc)&0xffffffffULL)));
		lseek(fd,opdshdr->sh_offset + (opd - opdbase)*sizeof(Opd64),SEEK_SET);
		if(write(fd,opd,sizeof(Opd64))!=sizeof(Opd64)) {
			printf("Error occurred during write in %s:%d\n",__FILE__,__LINE__);
		}
	}

	elf_end(elf);
	close(fd);

	return 0;
}
Пример #2
0
int main(int argc, const char *argv[])
{
	int i, fd;
	Elf *pelf = NULL;
	char *id, bytes[5];
	size_t n = 0;
	Elf32_Phdr *phdr32 = NULL; 
	GElf_Phdr gphdr = { 0 };	

	if (argc != 2)	
		errx(EXIT_FAILURE, "usage: %s file-name", argv[0]);

	if (elf_version(EV_CURRENT) == EV_NONE)
		errx(EXIT_FAILURE, "ELF library initialization "
				"failed: %s", elf_errmsg(-1));

	if ((fd = open(argv[1], O_RDONLY, 0)) < 0)
		errx(EXIT_FAILURE, "open \"%s\" failed", argv[1]);

	if ((pelf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
		errx(EXIT_FAILURE, "elf_begin() failed: %s",
				elf_errmsg(-1));

	if (elf_kind(pelf) != ELF_K_ELF)
		errx(EXIT_FAILURE, "\"%s\" is not an ELF object.",
				argv[1]);

	// get the num of program header table
	if (elf_getphdrnum(pelf, &n) != 0)
		errx(EXIT_FAILURE, "elf_getphdrnum() failed: %s.",
				elf_errmsg(-1));
	
#if 0
	// 32bit
	if ((phdr32 = elf32_getphdr(pelf)) == NULL)
		errx(EXIT_FAILURE, "elf32_getphdr() failed: %s.",
				elf_errmsg(-1));
	for (i = 0; i < n; i++) {
		Elf32_Phdr phdr = phdr32[i];
		printf("PHDR %d:\n", i);
#define PRINT_FMT	"    %-20s 0x%jx"
#define PRINT_FIELD(N)	do { printf(PRINT_FMT, #N, (uintmax_t)phdr.N); } while (0);
#define NL() do { printf("\n"); } while (0);

		PRINT_FIELD(p_type);
		print_ptype(phdr.p_type); 				NL();
		PRINT_FIELD(p_offset);					NL();
		PRINT_FIELD(p_vaddr);					NL();
		PRINT_FIELD(p_paddr); 					NL();
		PRINT_FIELD(p_filesz);					NL();
		PRINT_FIELD(p_memsz);					NL();
		PRINT_FIELD(p_flags);					
		printf(" [");
		if (phdr.p_flags & PF_X)
			printf(" execute");
		if (phdr.p_flags & PF_R)
			printf(" read");
		if (phdr.p_flags & PF_W)
			printf(" write");
		printf(" ]");			NL();
		PRINT_FIELD(p_align);	NL();
	}
#endif

#if 1
	for (i = 0; i < n; i++) {
		// get every entry fist 
		if (gelf_getphdr(pelf, i, &gphdr) != &gphdr)	
			errx(EXIT_FAILURE, "gelf_getphdr() failed: %s.",
													elf_errmsg(-1));
		// now print every entry
		printf("PHDR %d:\n", i);
#define PRINT_FMT	"    %-20s 0x%jx"
#define PRINT_FIELD(N)	do { printf(PRINT_FMT, #N, (uintmax_t)gphdr.N); } while (0);
#define NL() do { printf("\n"); } while (0);

		PRINT_FIELD(p_type);
		print_ptype(gphdr.p_type); 				NL();
		PRINT_FIELD(p_offset);					NL();
		PRINT_FIELD(p_vaddr);					NL();
		PRINT_FIELD(p_paddr); 					NL();
		PRINT_FIELD(p_filesz);					NL();
		PRINT_FIELD(p_memsz);					NL();
		PRINT_FIELD(p_flags);					;
		printf(" [");
		if (gphdr.p_flags & PF_X)
			printf(" execute");
		if (gphdr.p_flags & PF_R)
			printf(" read");
		if (gphdr.p_flags & PF_W)
			printf(" write");
		printf(" ]");			NL();
		PRINT_FIELD(p_align);	NL();
	}
#endif

	elf_end(pelf);
	close(fd);

	exit(EXIT_SUCCESS);
}
Пример #3
0
int
main (void)
{
  AsmCtx_t *ctx;
  AsmScn_t *scn1;
  AsmScn_t *scn2;
  int fd;
  Elf *elf;
  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr;
  int result = 0;
  size_t cnt;

  elf_version (EV_CURRENT);

  ctx = asm_begin (fname, false, EM_386, ELFCLASS32, ELFDATA2LSB);
  if (ctx == NULL)
    {
      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
      return 1;
    }

  /* Create two sections.  */
  scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
  scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
  if (scn1 == NULL || scn2 == NULL)
    {
      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Special alignment for the .text section.  */
  if (asm_align (scn1, 32) != 0)
    {
      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
      result = 1;
    }

  /* Create the output file.  */
  if (asm_end (ctx) != 0)
    {
      printf ("cannot create output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Check the file.  */
  fd = open (fname, O_RDONLY);
  if (fd == -1)
    {
      printf ("cannot open generated file: %m\n");
      result = 1;
      goto out;
    }

  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close;
    }
  if (elf_kind (elf) != ELF_K_ELF)
    {
      puts ("not a valid ELF file");
      result = 1;
      goto out_close2;
    }

  ehdr = gelf_getehdr (elf, &ehdr_mem);
  if (ehdr == NULL)
    {
      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close2;
    }

  if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
    {
      puts ("ELF header does not match");
      result = 1;
      goto out_close2;
    }

  for (cnt = 1; cnt < 4; ++cnt)
    {
      Elf_Scn *scn;
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr;

      scn = elf_getscn (elf, cnt);
      if (scn == NULL)
	{
	  printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
	{
	  printf ("cannot get section header for section %Zd: %s\n",
		  cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]) != 0)
	{
	  printf ("section %Zd's name differs: %s vs %s\n", cnt,
		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]);
	  result = 1;
	}

      if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS))
	{
	  printf ("section %Zd's type differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR))
	  || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
	  || (cnt == 3 && shdr->sh_flags != 0))
	{
	  printf ("section %Zd's flags differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_addr != 0)
	{
	  printf ("section %Zd's address differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31))
	{
	  printf ("section %Zd's offset differs\n", cnt);
	  result = 1;
	}

      if ((cnt != 3 && shdr->sh_size != 0)
	  || (cnt == 3 && shdr->sh_size != 23))
	{
	  printf ("section %Zd's size differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_link != 0)
	{
	  printf ("section %Zd's link differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_info != 0)
	{
	  printf ("section %Zd's info differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_addralign != 32)
	  || (cnt != 1 && shdr->sh_addralign != 1))
	{
	  printf ("section %Zd's addralign differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_entsize != 0)
	{
	  printf ("section %Zd's entsize differs\n", cnt);
	  result = 1;
	}
    }

 out_close2:
  elf_end (elf);
 out_close:
  close (fd);
 out:
  /* We don't need the file anymore.  */
  unlink (fname);

  return result;
}
int analyze_elf_binary(int file_descriptor, unsigned char *file_data)
{
	Elf *elf_handle;
	GElf_Ehdr elf_executable_header;
	Elf_Scn *section;
	GElf_Shdr section_header;
	char *section_name;
	int replacements;

	if (elf_version(EV_CURRENT) == EV_NONE)
		PRINT_ELF_ERRNO();
	if ((elf_handle = elf_begin(file_descriptor, ELF_C_READ, NULL)) == NULL)
		PRINT_ELF_ERRNO();
	if (gelf_getehdr(elf_handle, &elf_executable_header) == NULL)
		PRINT_ELF_ERRNO();

	switch(elf_kind(elf_handle)) {
		case ELF_K_NUM:
		case ELF_K_NONE:
			PRINT_ERROR_MESSAGE("file type unknown", false);
			break;
		case ELF_K_COFF:
			PRINT_ERROR_MESSAGE("COFF binaries not supported", false);
			break;
		case ELF_K_AR:
			PRINT_ERROR_MESSAGE("AR archives not supported", false);
			break;
		case ELF_K_ELF:
			if (options.verbose) {
				if (gelf_getclass(elf_handle) == ELFCLASS32)
					printf("Reading 32-bit ELF binary");
				else
					printf("Reading 64-bit ELF binary");

				if (options.read_only)
					printf(" in read-only mode\n");
				else
					printf("\n");
			}
			break;
	}

	replacements = 0;
	section = NULL;
	while ((section = elf_nextscn(elf_handle, section)) != NULL) {
		if (gelf_getshdr(section, &section_header) != &section_header)
			PRINT_ELF_ERRNO();

		if ((section_name = elf_strptr(elf_handle, elf_executable_header.e_shstrndx,
						section_header.sh_name)) == NULL)
			PRINT_ELF_ERRNO();

		if (options.verbose && !(section_header.sh_flags & SHF_EXECINSTR))
			printf("* Section %s\n", section_name);
		else if (options.verbose)
			printf("* Section %s is executable\n", section_name);

		if (section_header.sh_flags & SHF_EXECINSTR || options.patch_all_sections) {
			/* Avoid the `.bss' section, it doesn't exist in the binary file. */
			if (strcmp(section_name, ".bss")) {
				replacements += replace_vendor_string(file_data + section_header.sh_offset,
						section_header.sh_size,
						(unsigned char *) section_header.sh_addr);
			}
		}
	}
	PRINT_ELF_ERRNO(); /* If there isn't elf_errno set, nothing will happend. */

	elf_end(elf_handle);

	return replacements;
}
Пример #5
0
static int
chk4ubin(char *root, char *binary)
{
	int  		fd;
	Elf		*elf;
	Elf_Scn		*symscn;
	Elf_Scn		*strscn;
	GElf_Shdr	symhdr;
	GElf_Shdr	strhdr;
	int64_t		symtab_size;
	int64_t		strtab_size;
	int64_t		total;
	int		found_symtab = 0;
	int		found_strtab = 0;
	uint_t		off;
	int		rv = 1;
	char		path[MAXPATHLEN];

	if (root == NULL) {
		(void) snprintf(path, sizeof (path), "%s", binary);
	} else {
		(void) snprintf(path, sizeof (path), "%s/%s", root, binary);
	}

	if ((fd = open(path, O_RDONLY)) == -1) {
		(void) printf("%s: cannot open %s - %s\n",
		    whoami, path, strerror(errno));
		return (1);
	}

	elf_version(EV_CURRENT);
	elf = elf_begin(fd, ELF_C_READ, NULL);

	symscn = NULL;
	while ((symscn = elf_nextscn(elf, symscn)) != NULL) {
		gelf_getshdr(symscn, &symhdr);
		switch (symhdr.sh_type) {
		case SHT_SYMTAB:
			found_symtab = 1;
			symtab_size = symhdr.sh_size;
			strscn = elf_getscn(elf, symhdr.sh_link);
			if (strscn != NULL) {
				gelf_getshdr(strscn, &strhdr);
				strtab_size = strhdr.sh_size;
				found_strtab = 1;
			}
			break;
		}
		if (found_symtab && found_strtab)
			break;
	}

	elf_end(elf);
	(void) close(fd);

	if (found_symtab && found_strtab) {
		int err;
		total = symtab_size + strtab_size;
		off = total & pagemask;
		err = (off >= toxic_start && off <= toxic_end);
		if (inject_err || err) {
			(void) printf("%s: ERROR: %s\n", whoami, binary);
			(void) printf("ERROR: symbol table size 0x%llx is "
			    "in toxic range (0x%x - 0x%x)!\n",
			    total, toxic_start, toxic_end);
			(void) printf("%s", detailed_error_msg);
		} else {
			rv = 0;
			(void) printf("%s: %s ok\n", whoami, binary);
			if (verbose) {
				(void) printf("symbol table size 0x%llx "
				    "not in toxic range (0x%x - 0x%x)\n",
				    total, toxic_start, toxic_end);
			}
		}
		if (verbose) {
			(void) printf(".symtab size: 0x%llx\n",
			    symtab_size);
			(void) printf(".strtab size: 0x%llx\n",
			    strtab_size);
			(void) printf("total:        0x%llx "
			    "(0x%llx, 0x%llx)\n", total, (total & ~pagemask),
			    (total & pagemask));
		}
		if (verbose || err || inject_err)
			(void) printf("\n");
	} else {
		if (!found_symtab && !found_strtab) {
			(void) fprintf(stderr,
			    "%s: %s - no symtab or strtab section found\n",
			    whoami, binary);
		} else if (!found_symtab) {
			(void) fprintf(stderr,
			    "%s: %s - no symtab section found\n",
			    whoami, binary);
		} else if (!found_strtab) {
			(void) fprintf(stderr,
			    "%s: %s - no strtab section found\n",
			    whoami, binary);
		}
	}

	return (rv);
}
Пример #6
0
int
main(int argc, char **argv)
{
	Elf *e;
	Dwarf_Debug dbg;
	Dwarf_Error de;
	const char *exe, *section;
	char line[1024];
	int fd, i, opt;

	exe = NULL;
	section = NULL;
	while ((opt = getopt_long(argc, argv, "b:Ce:fj:sHV", longopts, NULL)) !=
	    -1) {
		switch (opt) {
		case 'b':
			/* ignored */
			break;
		case 'C':
			demangle = 1;
			break;
		case 'e':
			exe = optarg;
			break;
		case 'f':
			func = 1;
			break;
		case 'j':
			section = optarg;
			break;
		case 's':
			base = 1;
			break;
		case 'H':
			usage();
		case 'V':
			version();
		default:
			usage();
		}
	}

	argv += optind;
	argc -= optind;

	if (exe == NULL)
		exe = "a.out";

	if ((fd = open(exe, O_RDONLY)) < 0)
		err(EXIT_FAILURE, "%s", exe);

	if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de))
		errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(de));

	if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK)
		errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de));

	if (section)
		find_section_base(exe, e, section);
	else
		section_base = 0;

	if (argc > 0)
		for (i = 0; i < argc; i++)
			translate(dbg, argv[i]);
	else
		while (fgets(line, sizeof(line), stdin) != NULL) {
			translate(dbg, line);
			fflush(stdout);
		}

	dwarf_finish(dbg, &de);

	(void) elf_end(e);

	exit(0);
}
Пример #7
0
void dynLibImplLinux::CloseDynamicLibrary( Elf* elf )
{
  elf_end(elf);
  close(elf->e_fd);
}
Пример #8
0
int main( int argc, char *argv[])
{
	int fd, cmd;
	size_t i, n;
	char *p; 

	Elf *arf, *elf;
	GElf_Ehdr ehdr;
	Elf_Scn *scn;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn dyn;

	if(elf_version(EV_CURRENT) == EV_NONE)
		error(EXIT_FAILURE, 0, "Library out of date.");

	if(argc != 2)
		error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]);

	if((fd = open(argv[1], O_RDONLY)) == -1)
		error(EXIT_FAILURE, 0, "Failed open file.");


	cmd = ELF_C_READ;

	if((arf = elf_begin(fd, cmd, (Elf *)0)) == NULL)
		error(EXIT_FAILURE, 0, "Failed open elf: %s", elf_errmsg ( -1));
		

	while((elf = elf_begin(fd, cmd, arf)) != NULL)
	{
		if(gelf_getehdr(elf,&ehdr) != NULL)
		{
			scn = NULL;
			while((scn = elf_nextscn(elf, scn)) != NULL)
			{
				gelf_getshdr(scn, &shdr);

				if(shdr.sh_type != SHT_DYNAMIC)
					continue;

				printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));

				data = NULL;
				while((data = elf_getdata(scn, data)) != NULL)
				{
					if(data != NULL)
						for( i=0; gelf_getdyn(data, i, &dyn) != NULL; i++)
						{
							if(dyn.d_tag == DT_RPATH)
								printf("DT_RPATH found\n");
							if(dyn.d_tag == DT_RUNPATH)
								printf("DT_RUNPATH found\n");
						}
				}
			}
		}

		cmd = elf_next(elf);
		elf_end(elf);

	}

	elf_end(arf);

	close(fd);
}
Пример #9
0
static int
analyse_elf(struct pkg *pkg, const char *fpath)
{
	Elf *e = NULL;
	GElf_Ehdr elfhdr;
	Elf_Scn *scn = NULL;
	Elf_Scn *note = NULL;
	Elf_Scn *dynamic = NULL;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn *dyn, dyn_mem;
	struct stat sb;
	int ret = EPKG_OK;

	size_t numdyn = 0;
	size_t sh_link = 0;
	size_t dynidx;
	const char *myarch;
	const char *shlib;
	char *rpath = NULL;

	bool is_shlib = false;

	myarch = pkg_object_string(pkg_config_get("ABI"));

	int fd;

	pkg_debug(1, "analysing elf %s", fpath);
	if (lstat(fpath, &sb) != 0)
		pkg_emit_errno("fstat() failed for", fpath);
	/* ignore empty files and non regular files */
	if (sb.st_size == 0 || !S_ISREG(sb.st_mode))
		return (EPKG_END); /* Empty file or sym-link: no results */

	if ((fd = open(fpath, O_RDONLY, 0)) < 0) {
		return (EPKG_FATAL);
	}

	if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		ret = EPKG_FATAL;
		pkg_emit_error("elf_begin() for %s failed: %s", fpath,
		    elf_errmsg(-1));
		goto cleanup;
	}

	if (elf_kind(e) != ELF_K_ELF) {
		/* Not an elf file: no results */
		ret = EPKG_END;
		pkg_debug(1, "not an elf");
		goto cleanup;
	}

	if (ctx.developer_mode)
		pkg->flags |= PKG_CONTAINS_ELF_OBJECTS;

	if (gelf_getehdr(e, &elfhdr) == NULL) {
		ret = EPKG_FATAL;
		pkg_emit_error("getehdr() failed: %s.", elf_errmsg(-1));
		goto cleanup;
	}

	if (elfhdr.e_type != ET_DYN && elfhdr.e_type != ET_EXEC &&
	    elfhdr.e_type != ET_REL) {
		pkg_debug(1, "not an elf");
		ret = EPKG_END;
		goto cleanup;
	}

	/* Elf file has sections header */
	while ((scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr) {
			ret = EPKG_FATAL;
			pkg_emit_error("getshdr() for %s failed: %s", fpath,
					elf_errmsg(-1));
			goto cleanup;
		}
		switch (shdr.sh_type) {
		case SHT_NOTE:
			if ((data = elf_getdata(scn, NULL)) == NULL) {
				ret = EPKG_END; /* Some error occurred, ignore this file */
				goto cleanup;
			}
			else if (data->d_buf != NULL) {
				Elf_Note *en = (Elf_Note *)data->d_buf;
				if (en->n_type == NT_ABI_TAG)
					note = scn;
			}
			break;
		case SHT_DYNAMIC:
			dynamic = scn;
			sh_link = shdr.sh_link;
			if (shdr.sh_entsize == 0) {
				ret = EPKG_END;
				goto cleanup;
			}
			numdyn = shdr.sh_size / shdr.sh_entsize;
			break;
		}

		if (note != NULL && dynamic != NULL)
			break;
	}

	/*
	 * note == NULL usually means a shared object for use with dlopen(3)
	 * dynamic == NULL means not a dynamically linked elf
	 */
	if (dynamic == NULL) {
		ret = EPKG_END;
		goto cleanup; /* not a dynamically linked elf: no results */
	}

	if (!shlib_valid_abi(fpath, &elfhdr, myarch)) {
		ret = EPKG_END;
		goto cleanup; /* Invalid ABI */
	}

#ifdef __FreeBSD__
	if (elfhdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD &&
	    !is_old_freebsd_armheader(&elfhdr)) {
		ret = EPKG_END;
		goto cleanup;
	}
#endif

	if ((data = elf_getdata(dynamic, NULL)) == NULL) {
		ret = EPKG_END; /* Some error occurred, ignore this file */
		goto cleanup;
	}

	/* First, scan through the data from the .dynamic section to
	   find any RPATH or RUNPATH settings.  These are colon
	   separated paths to prepend to the ld.so search paths from
	   the ELF hints file.  These always seem to come right after
	   the NEEDED shared library entries.

	   NEEDED entries should resolve to a filename for installed
	   executables, but need not resolve for installed shared
	   libraries -- additional info from the apps that link
	   against them would be required.  Shared libraries are
	   distinguished by a DT_SONAME tag */

	rpath_list_init();
	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) {
			ret = EPKG_FATAL;
			pkg_emit_error("getdyn() failed for %s: %s", fpath,
			    elf_errmsg(-1));
			goto cleanup;
		}

		if (dyn->d_tag == DT_SONAME) {
			is_shlib = true;

			/* The file being scanned is a shared library
			   *provided* by the package. Record this if
			   appropriate */
			shlib = elf_strptr(e, sh_link, dyn->d_un.d_val);
			if (shlib != NULL && *shlib != '\0')
				pkg_addshlib_provided(pkg, shlib);
		}

		if ((dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) &&
		    rpath == NULL)
			rpath = elf_strptr(e, sh_link, dyn->d_un.d_val);
	}
	if (rpath != NULL)
		shlib_list_from_rpath(rpath, bsd_dirname(fpath));

	/* Now find all of the NEEDED shared libraries. */

	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) {
			ret = EPKG_FATAL;
			pkg_emit_error("getdyn() failed for %s: %s", fpath,
			    elf_errmsg(-1));
			goto cleanup;
		}

		if (dyn->d_tag != DT_NEEDED)
			continue;

		shlib = elf_strptr(e, sh_link, dyn->d_un.d_val);

		add_shlibs_to_pkg(pkg, fpath, shlib, is_shlib);
	}

cleanup:
	rpath_list_free();

	if (e != NULL)
		elf_end(e);
	close(fd);

	return (ret);
}
Пример #10
0
static int
analyse_elf(struct pkg *pkg, const char *fpath,
	int (action)(void *, struct pkg *, const char *, const char *, bool),
	void *actdata)
{
	Elf *e = NULL;
	GElf_Ehdr elfhdr;
	Elf_Scn *scn = NULL;
	Elf_Scn *note = NULL;
	Elf_Scn *dynamic = NULL;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn *dyn, dyn_mem;
	struct stat sb;
	int ret = EPKG_OK;

	size_t numdyn = 0;
	size_t sh_link = 0;
	size_t dynidx;
	const char *osname;
	const char *shlib;

	bool shlibs = false;
	bool autodeps = false;
	bool developer = false;
	bool is_shlib = false;

	pkg_config_bool(PKG_CONFIG_AUTODEPS, &autodeps);
	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);
	pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);

	int fd;

	if ((fd = open(fpath, O_RDONLY, 0)) < 0) {
		return (EPKG_FATAL);
	}
	if (fstat(fd, &sb) != 0)
		pkg_emit_errno("fstat() failed for %s", fpath);
	/* ignore empty files and non regular files */
	if (sb.st_size == 0 || !S_ISREG(sb.st_mode)) {
		ret = EPKG_END; /* Empty file: no results */
		goto cleanup;
	}

	if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		ret = EPKG_FATAL;
		pkg_emit_error("elf_begin() for %s failed: %s", fpath,
		    elf_errmsg(-1));
		goto cleanup;
	}

	if (elf_kind(e) != ELF_K_ELF) {
		close(fd);
		return (EPKG_END); /* Not an elf file: no results */
	}

	if (developer)
		pkg->flags |= PKG_CONTAINS_ELF_OBJECTS;

	if (!autodeps && !shlibs) {
	   ret = EPKG_OK;
	   goto cleanup;
	}

	if (gelf_getehdr(e, &elfhdr) == NULL) {
		ret = EPKG_FATAL;
		pkg_emit_error("getehdr() failed: %s.", elf_errmsg(-1));
		goto cleanup;
	}

	while ((scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr) {
			ret = EPKG_FATAL;
			pkg_emit_error("getshdr() for %s failed: %s", fpath,
			    elf_errmsg(-1));
			goto cleanup;
		}
		switch (shdr.sh_type) {
		case SHT_NOTE:
			note = scn;
			break;
		case SHT_DYNAMIC:
			dynamic = scn;
			sh_link = shdr.sh_link;
			numdyn = shdr.sh_size / shdr.sh_entsize;
			break;
		}

		if (note != NULL && dynamic != NULL)
			break;
	}

	/*
	 * note == NULL usually means a shared object for use with dlopen(3)
	 * dynamic == NULL means not a dynamically linked elf
	 */
	if (dynamic == NULL) {
		ret = EPKG_END;
		goto cleanup; /* not a dynamically linked elf: no results */
	}

	if (note != NULL) {
		data = elf_getdata(note, NULL);
		osname = (const char *) data->d_buf + sizeof(Elf_Note);
		if (strncasecmp(osname, "freebsd", sizeof("freebsd")) != 0) {
			ret = EPKG_END;	/* Foreign (probably linux) ELF object */
			goto cleanup;
		}
	} else {
		if (elfhdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD) {
			ret = EPKG_END;
			goto cleanup;
		}
	}

	data = elf_getdata(dynamic, NULL);

	/* First, scan through the data from the .dynamic section to
	   find any RPATH or RUNPATH settings.  These are colon
	   separated paths to prepend to the ld.so search paths from
	   the ELF hints file.  These always seem to come right after
	   the NEEDED shared library entries.

	   NEEDED entries should resolve to a filename for installed
	   executables, but need not resolve for installed shared
	   libraries -- additional info from the apps that link
	   against them would be required.  Shared libraries are
	   distinguished by a DT_SONAME tag */

	rpath_list_init();
	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) {
			ret = EPKG_FATAL;
			pkg_emit_error("getdyn() failed for %s: %s", fpath,
			    elf_errmsg(-1));
			goto cleanup;
		}

		if (dyn->d_tag == DT_SONAME)
			is_shlib = true;

		if (dyn->d_tag != DT_RPATH && dyn->d_tag != DT_RUNPATH)
			continue;
		
		shlib_list_from_rpath(elf_strptr(e, sh_link, dyn->d_un.d_val), 
				      dirname(fpath));
		break;
	}

	/* Now find all of the NEEDED shared libraries. */

	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) {
			ret = EPKG_FATAL;
			pkg_emit_error("getdyn() failed for %s: %s", fpath,
			    elf_errmsg(-1));
			goto cleanup;
		}

		if (dyn->d_tag != DT_NEEDED)
			continue;

		shlib = elf_strptr(e, sh_link, dyn->d_un.d_val);

		/* When running in DEVELOPER_MODE check that shlib
		   names conform to the correct pattern.  Only issue a
		   warning on mismatch -- shlibs may belong to a
		   different package. */

		if (developer)
			warn_about_name_format(pkg, fpath, shlib);

		action(actdata, pkg, fpath, shlib, is_shlib);
	}

cleanup:
	rpath_list_free();

	if (e != NULL)
		elf_end(e);
	close(fd);

	return (ret);
}
Пример #11
0
/* Method to test if a file is non stripped binary. Uses libelf*/
bool rm_util_is_nonstripped(_U const char *path, _U RmStat *statp) {
    bool is_ns = false;

#if HAVE_LIBELF
    g_return_val_if_fail(path, false);

    if(statp && (statp->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) {
        return false;
    }

    /* inspired by "jschmier"'s answer at http://stackoverflow.com/a/5159890 */
    int fd;

    /* ELF handle */
    Elf *elf;

    /* section descriptor pointer */
    Elf_Scn *scn;

    /* section header */
    GElf_Shdr shdr;

    /* Open ELF file to obtain file descriptor */
    if((fd = rm_sys_open(path, O_RDONLY)) == -1) {
        rm_log_warning_line(_("cannot open file '%s' for nonstripped test: "), path);
        rm_log_perror("");
        return 0;
    }

    /* Protect program from using an older library */
    if(elf_version(EV_CURRENT) == EV_NONE) {
        rm_log_error_line(_("ELF Library is out of date!"));
        rm_sys_close(fd);
        return false;
    }

    /* Initialize elf pointer for examining contents of file */
    elf = elf_begin(fd, ELF_C_READ, NULL);

    /* Initialize section descriptor pointer so that elf_nextscn()
     * returns a pointer to the section descriptor at index 1.
     * */
    scn = NULL;

    /* Iterate through ELF sections */
    while((scn = elf_nextscn(elf, scn)) != NULL) {
        /* Retrieve section header */
        gelf_getshdr(scn, &shdr);

        /* If a section header holding a symbol table (.symtab)
         * is found, this ELF file has not been stripped. */
        if(shdr.sh_type == SHT_SYMTAB) {
            is_ns = true;
            break;
        }
    }
    elf_end(elf);
    rm_sys_close(fd);
#endif

    return is_ns;
}
Пример #12
0
int main( int argc, char *argv[])
{
	int fd, cmd;
	char *scn_name;

	Elf *elf;
	GElf_Ehdr ehdr;
	Elf_Scn *scn;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn dyn;

	if(argc != 3)
		error(EXIT_FAILURE, 0, "Usage: %s <elf> <ld.so>", argv[0]);

	if(elf_version(EV_CURRENT) == EV_NONE)
		error(EXIT_FAILURE, 0, "Library out of date.");

	if((fd = open(argv[1], O_RDWR)) == -1)
		error(EXIT_FAILURE, 0, "Failed open file.");

	if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, elf)) != NULL)
	{
		if(gelf_getehdr(elf,&ehdr) != NULL)
		{
			scn = NULL;
			while((scn = elf_nextscn(elf, scn)) != NULL)
			{
				gelf_getshdr(scn, &shdr);
				scn_name = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name);

				if(strcmp(scn_name, ".interp"))
					continue;

				printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));

				if((data = elf_getdata(scn, data)) != NULL)
				{
					printf("Old ld.so: %s\n", (char *)data->d_buf);
					printf("Data size: %zu\n", data->d_size);
					/*
					printf( "Data:\t\t%s\nType:\t\t%d\nSize:\t\t%lu\n"
						"Off:\t\t%lu\nAlign:\t\t%lu\nVersion:\t%u\n",
						(char *)data->d_buf,
						data->d_type,
						data->d_size,
						data->d_off,
						data->d_align,
						data->d_version
					);
					*/

					if(data->d_size >= strlen(argv[2]))
					{
						memset(data->d_buf, 0, data->d_size);
						strncpy(data->d_buf, argv[2], data->d_size);

						if(!gelf_update_shdr(scn, &shdr))
						{
							elf_end(elf);
							close(fd);
							error(EXIT_FAILURE, 0, "\tELF ERROR: gelf_update_shdr(): %s", elf_errmsg(elf_errno()));
						}
					}
					else
					{
						elf_end(elf);
						close(fd);
						error(EXIT_FAILURE, 0, "\tld.so path too long: max=%zu", data->d_size);
					}

					printf( "New ld.so: %s\n", (char *)data->d_buf);
					/*
					printf( "Data:\t\t%s\nType:\t\t%d\nSize:\t\t%lu\n"
						"Off:\t\t%lu\nAlign:\t\t%lu\nVersion:\t%u\n",
						(char *)data->d_buf,
						data->d_type,
						data->d_size,
						data->d_off,
						data->d_align,
						data->d_version
					);
					*/
				}
			}
		}
	}

	elf_end(elf);
	close(fd);
}
Пример #13
0
/* Load an ELF image into the simulated memory. Using libelf*/
int mips_load_elf_image (cpu_mips_t * cpu, char *filename,
    m_va_t * entry_point)
{
    m_va_t vaddr;
    m_uint32_t remain;
    void *haddr;
    Elf32_Ehdr *ehdr;
    Elf32_Shdr *shdr;
    Elf_Scn *scn;
    Elf *img_elf;
    size_t len, clen;
    int i, fd;
    FILE *bfd;

    if (! filename)
        return (-1);

#ifdef __CYGWIN__
    fd = open (filename, O_RDONLY | O_BINARY);
#else
    fd = open (filename, O_RDONLY);
#endif
    printf ("Loading ELF file '%s'...\n", filename);
    if (fd == -1) {
        perror ("load_elf_image: open");
        return (-1);
    }

    if (elf_version (EV_CURRENT) == EV_NONE) {
        fprintf (stderr, "load_elf_image: library out of date\n");
        return (-1);
    }

    if (!(img_elf = elf_begin (fd, ELF_C_READ, NULL))) {
        fprintf (stderr, "load_elf_image: elf_begin: %s\n",
            elf_errmsg (elf_errno ()));
        return (-1);
    }

    if (!(ehdr = elf32_getehdr (img_elf))) {
        fprintf (stderr, "load_elf_image: invalid ELF file\n");
        return (-1);
    }

    bfd = fdopen (fd, "rb");

    if (!bfd) {
        perror ("load_elf_image: fdopen");
        return (-1);
    }
// if (!skip_load) {
    for (i = 0; i < ehdr->e_shnum; i++) {
        scn = elf_getscn (img_elf, i);

        shdr = elf32_getshdr (scn);
        len = shdr->sh_size;

        if (!(shdr->sh_flags & SHF_ALLOC) || !len)
            continue;

        fseek (bfd, shdr->sh_offset, SEEK_SET);
        vaddr = sign_extend (shdr->sh_addr, 32);

        if (cpu->vm->debug_level > 0) {
            printf ("   * Adding section at virtual address 0x%8.8" LL "x "
                "(len=0x%8.8lx)\n", vaddr & 0xFFFFFFFF, (u_long) len);
        }

        while (len > 0) {
            haddr = cpu->mem_op_lookup (cpu, vaddr);

            if (!haddr) {
                fprintf (stderr,
                    "load_elf_image: invalid load address 0x%" LL "x\n",
                    vaddr);
                return (-1);
            }

            if (len > MIPS_MIN_PAGE_SIZE)
                clen = MIPS_MIN_PAGE_SIZE;
            else
                clen = len;

            remain = MIPS_MIN_PAGE_SIZE;
            remain -= (vaddr - (vaddr & MIPS_MIN_PAGE_SIZE));

            clen = m_min (clen, remain);

            if (fread ((u_char *) haddr, clen, 1, bfd) < 1)
                break;

            vaddr += clen;
            len -= clen;
        }
    }

    printf ("ELF entry point: 0x%x\n", ehdr->e_entry);

    if (entry_point)
        *entry_point = ehdr->e_entry;

    elf_end (img_elf);
    fclose (bfd);
    return (0);
}
Пример #14
0
int
main (void)
{
  AsmCtx_t *ctx;
  AsmScn_t *scn1;
  AsmScn_t *scn2;
  int result = 0;
  int fd;
  Elf *elf;
  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr;
  size_t cnt;

  elf_version (EV_CURRENT);

  Ebl *ebl = ebl_openbackend_machine (EM_386);
  if (ebl == NULL)
    {
      puts ("cannot open backend library");
      return 1;
    }

  ctx = asm_begin (fname, ebl, false);
  if (ctx == NULL)
    {
      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
      return 1;
    }

  /* Create two sections.  */
  scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
  scn2 = asm_newsubscn (scn1, 1);
  if (scn1 == NULL || scn2 == NULL)
    {
      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Special alignment for the .text section.  */
  if (asm_align (scn1, 16) != 0)
    {
      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
      result = 1;
    }

  /* Add a few strings.  */
  if (asm_addstrz (scn1, "one", 4) != 0)
    {
      printf ("cannot insert first string: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_addstrz (scn2, "three", 0) != 0)
    {
      printf ("cannot insert second string: %s\n", asm_errmsg (-1));
      result = 1;
    }
  if (asm_addstrz (scn1, "two", 4) != 0)
    {
      printf ("cannot insert third string: %s\n", asm_errmsg (-1));
      result = 1;
    }

  /* Create the output file.  */
  if (asm_end (ctx) != 0)
    {
      printf ("cannot create output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Check the file.  */
  fd = open (fname, O_RDONLY);
  if (fd == -1)
    {
      printf ("cannot open generated file: %m\n");
      result = 1;
      goto out;
    }

  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close;
    }
  if (elf_kind (elf) != ELF_K_ELF)
    {
      puts ("not a valid ELF file");
      result = 1;
      goto out_close2;
    }

  ehdr = gelf_getehdr (elf, &ehdr_mem);
  if (ehdr == NULL)
    {
      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close2;
    }

  if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
    {
      puts ("ELF header does not match");
      result = 1;
      goto out_close2;
    }

  for (cnt = 1; cnt < 3; ++cnt)
    {
      Elf_Scn *scn;
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr;

      scn = elf_getscn (elf, cnt);
      if (scn == NULL)
	{
	  printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
	{
	  printf ("cannot get section header for section %Zd: %s\n",
		  cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]) != 0)
	{
	  printf ("section %Zd's name differs: %s vs %s\n", cnt,
		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
		  scnnames[cnt]);
	  result = 1;
	}

      if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS))
	{
	  printf ("section %Zd's type differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
	  || (cnt == 2 && shdr->sh_flags != 0))
	{
	  printf ("section %Zd's flags differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_addr != 0)
	{
	  printf ("section %Zd's address differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15))
	  || (cnt == 2
	      && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15)
				     + strlen ("one") + 1
				     + strlen ("two") + 1
				     + strlen ("three") + 1)))
	{
	  printf ("section %Zd's offset differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1
					 + strlen ("two") + 1
					 + strlen ("three") + 1))
	  || (cnt == 2 && shdr->sh_size != 17))
	{
	  printf ("section %Zd's size differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_link != 0)
	{
	  printf ("section %Zd's link differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_info != 0)
	{
	  printf ("section %Zd's info differs\n", cnt);
	  result = 1;
	}

      if ((cnt == 1 && shdr->sh_addralign != 16)
	  || (cnt != 1 && shdr->sh_addralign != 1))
	{
	  printf ("section %Zd's addralign differs\n", cnt);
	  result = 1;
	}

      if (shdr->sh_entsize != 0)
	{
	  printf ("section %Zd's entsize differs\n", cnt);
	  result = 1;
	}
    }

 out_close2:
  elf_end (elf);
 out_close:
  close (fd);
 out:
  /* We don't need the file anymore.  */
  unlink (fname);

  ebl_closebackend (ebl);

  return result;
}
Пример #15
0
char elf_section_boundary_get(char* path, size_t* offset, size_t* size) {
  char retval = 0;

  int fd = open(path, O_RDONLY);
  if (!fd) {
    retval = 8;
    goto end_0;
  }

  if (elf_version(EV_CURRENT) == EV_NONE) {
    retval = 2;
    goto end_0;
  }

  Elf* e = elf_begin(fd, ELF_C_READ, NULL);
  if (!e) {
    retval = 3;
    goto end_0;
  }

  if (elf_kind(e) != ELF_K_ELF) {
    retval = 4;
    goto end_1;
  }

  size_t shstrndx;
  // Todo: Check the return value!
  //  if(elf_getshdrstrndx(e, &shstrndx) != 0) {
  //    retval = 5;
  //    goto end_1;
  //  }
  elf_getshdrstrndx(e, &shstrndx);

  Elf_Scn* scn = NULL;

  char found = 0;
  while ((scn = elf_nextscn(e, scn)) != NULL) {
    GElf_Shdr shdr;
    if (gelf_getshdr(scn, &shdr) != &shdr) {
      retval = 6;
      goto end_1;
    }

    char* name = elf_strptr(e, shstrndx, shdr.sh_name);
    if (!name) {
      retval = 7;
      goto end_1;
    }
    if (!strcmp(name, ".text")) {
      *offset = shdr.sh_offset;
      *size = shdr.sh_size;
      found = 1;
      break;
    }
  }

  if (!found) retval = 1;

end_1:
  elf_end(e);

end_0:
  close(fd);

  return retval;
}
Пример #16
0
int
_elf_nlist(int fd, struct nlist * list)
{
	Elf	   *elfdes;	/* ELF descriptor */
	GElf_Ehdr  ehdr;	/* ELF Ehdr */
	GElf_Shdr  s_buf;	/* buffer storing section header */
	Elf_Data   *symdata;	/* buffer points to symbol table */
	Elf_Scn    *secidx = 0;	/* index of the section header table */
	GElf_Sym   sym;		/* buffer storing one symbol information */
	unsigned   strtab;	/* index of symbol name in string table */
	long	   count;	/* number of symbols */
	long	   ii;		/* loop control */

	if (elf_version(EV_CURRENT) == EV_NONE) {
		(void) close(fd);
		return (-1);
	}
	elfdes = elf_begin(fd, ELF_C_READ, (Elf *)0);
	if (gelf_getehdr(elfdes, &ehdr) == 0)
		return (end_elf_job(fd, elfdes));

	while ((secidx = elf_nextscn(elfdes, secidx)) != 0) {
		if ((gelf_getshdr(secidx, &s_buf)) == 0)
			return (end_elf_job(fd, elfdes));
		if (s_buf.sh_type != SHT_SYMTAB) /* not symbol table */
			continue;
		symdata = elf_getdata(secidx, (Elf_Data *)0);
		if (symdata == 0)
			return (end_elf_job(fd, elfdes));
		if (symdata->d_size == 0)
			break;
		strtab = s_buf.sh_link;
		count = symdata->d_size / s_buf.sh_entsize;
		for (ii = 1; ii < count; ++ii) {
			struct nlist *p;
			register char *name;
			/* LINTED */
			(void) gelf_getsym(symdata, (int)ii, &sym);
			name = elf_strptr(elfdes, strtab, (size_t)sym.st_name);
			if (name == 0)
				continue;
			for (p = list; p->n_name && p->n_name[0]; ++p) {
				if (strcmp(p->n_name, name))
					continue;
				p->n_value = (long)sym.st_value;
				p->n_type = GELF_ST_TYPE(sym.st_info);
				p->n_scnum = sym.st_shndx;
				break;
			}
		}
		break;
		/*
		 * Currently there is only one symbol table section
		 * in an object file, but this restriction may be
		 * relaxed in the future.
		 */
	}
	(void) elf_end(elfdes);
	(void) close(fd);
	return (0);
}
Пример #17
0
int ELF_close(){
    (void) elf_end(e);
    (void) close(fd);
    return 1;
}
Пример #18
0
static int
pkg_get_myabi(char *dest, size_t sz)
{
	Elf *elf;
	Elf_Data *data;
	Elf_Note note;
	Elf_Scn *scn;
	char *src, *osname;
	const char *abi;
	GElf_Ehdr elfhdr;
	GElf_Shdr shdr;
	int fd, i, ret;
	uint32_t version;

	version = 0;
	ret = -1;
	scn = NULL;
	abi = NULL;

	if (elf_version(EV_CURRENT) == EV_NONE) {
		warnx("ELF library initialization failed: %s",
		    elf_errmsg(-1));
		return (-1);
	}

	if ((fd = open("/bin/sh", O_RDONLY)) < 0) {
		warn("open()");
		return (-1);
	}

	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		ret = -1;
		warnx("elf_begin() failed: %s.", elf_errmsg(-1));
		goto cleanup;
	}

	if (gelf_getehdr(elf, &elfhdr) == NULL) {
		ret = -1;
		warn("getehdr() failed: %s.", elf_errmsg(-1));
		goto cleanup;
	}

	while ((scn = elf_nextscn(elf, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr) {
			ret = -1;
			warn("getshdr() failed: %s.", elf_errmsg(-1));
			goto cleanup;
		}

		if (shdr.sh_type == SHT_NOTE)
			break;
	}

	if (scn == NULL) {
		ret = -1;
		warn("failed to get the note section");
		goto cleanup;
	}

	data = elf_getdata(scn, NULL);
	src = data->d_buf;
	for (;;) {
		memcpy(&note, src, sizeof(Elf_Note));
		src += sizeof(Elf_Note);
		if (note.n_type == NT_VERSION)
			break;
		src += note.n_namesz + note.n_descsz;
	}
	osname = src;
	src += note.n_namesz;
	if (elfhdr.e_ident[EI_DATA] == ELFDATA2MSB)
		version = be32dec(src);
	else
		version = le32dec(src);

	for (i = 0; osname[i] != '\0'; i++)
		osname[i] = (char)tolower(osname[i]);

	snprintf(dest, sz, "%s:%d:%s:%s",
	    osname, version / 100000,
	    elf_corres_to_string(mach_corres, (int)elfhdr.e_machine),
	    elf_corres_to_string(wordsize_corres,
	    (int)elfhdr.e_ident[EI_CLASS]));

	ret = 0;

	switch (elfhdr.e_machine) {
	case EM_ARM:
		snprintf(dest + strlen(dest), sz - strlen(dest),
		    ":%s:%s:%s", elf_corres_to_string(endian_corres,
		    (int)elfhdr.e_ident[EI_DATA]),
		    (elfhdr.e_flags & EF_ARM_NEW_ABI) > 0 ?
		    "eabi" : "oabi",
		    (elfhdr.e_flags & EF_ARM_VFP_FLOAT) > 0 ?
		    "softfp" : "vfp");
		break;
	case EM_MIPS:
		/*
		 * this is taken from binutils sources:
		 * include/elf/mips.h
		 * mapping is figured out from binutils:
		 * gas/config/tc-mips.c
		 */
		switch (elfhdr.e_flags & EF_MIPS_ABI) {
		case E_MIPS_ABI_O32:
			abi = "o32";
			break;
		case E_MIPS_ABI_N32:
			abi = "n32";
			break;
		default:
			if (elfhdr.e_ident[EI_DATA] ==
			    ELFCLASS32)
				abi = "o32";
			else if (elfhdr.e_ident[EI_DATA] ==
			    ELFCLASS64)
				abi = "n64";
			break;
		}
		snprintf(dest + strlen(dest), sz - strlen(dest),
		    ":%s:%s", elf_corres_to_string(endian_corres,
		    (int)elfhdr.e_ident[EI_DATA]), abi);
		break;
	}

cleanup:
	if (elf != NULL)
		elf_end(elf);

	close(fd);
	return (ret);
}
Пример #19
0
int
main (void)
{
  int result = 0;
  size_t cnt;
  AsmCtx_t *ctx;
  Elf *elf;
  int fd;

  elf_version (EV_CURRENT);

  Ebl *ebl = ebl_openbackend_machine (EM_386);
  if (ebl == NULL)
    {
      puts ("cannot open backend library");
      return 1;
    }

  ctx = asm_begin (fname, ebl, false);
  if (ctx == NULL)
    {
      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
      return 1;
    }

  if (asm_newabssym (ctx, "tst8-out.s", 4, 0xfeedbeef, STT_FILE, STB_LOCAL)
      == NULL)
    {
      printf ("cannot create absolute symbol: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Create the output file.  */
  if (asm_end (ctx) != 0)
    {
      printf ("cannot create output file: %s\n", asm_errmsg (-1));
      asm_abort (ctx);
      return 1;
    }

  /* Check the file.  */
  fd = open (fname, O_RDONLY);
  if (fd == -1)
    {
      printf ("cannot open generated file: %m\n");
      result = 1;
      goto out;
    }

  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
      result = 1;
      goto out_close;
    }
  if (elf_kind (elf) != ELF_K_ELF)
    {
      puts ("not a valid ELF file");
      result = 1;
      goto out_close2;
    }

  for (cnt = 1; 1; ++cnt)
    {
      Elf_Scn *scn;
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr;

      scn = elf_getscn (elf, cnt);
      if (scn == NULL)
	{
	  printf ("cannot get section %Zd: %s\n", cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}

      shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr == NULL)
	{
	  printf ("cannot get section header for section %Zd: %s\n",
		  cnt, elf_errmsg (-1));
	  result = 1;
	  continue;
	}
      /* We are looking for the symbol table.  */
      if (shdr->sh_type != SHT_SYMTAB)
	continue;

      for (cnt = 1; cnt< (shdr->sh_size
			  / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
	   ++cnt)
	{
	  GElf_Sym sym_mem;
	  GElf_Sym *sym;

	  if (cnt > 1)
	    {
	      puts ("too many symbol");
	      result = 1;
	      break;
	    }

	  sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem);
	  if (sym == NULL)
	    {
	      printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1));
	      result = 1;
	    }
	  else
	    {
	      if (sym->st_shndx != SHN_ABS)
		{
		  printf ("expected common symbol, got section %u\n",
			  (unsigned int) sym->st_shndx);
		  result = 1;
		}

	      if (sym->st_value != 0xfeedbeef)
		{
		  printf ("requested value 0xfeedbeef, is %#" PRIxMAX "\n",
			  (uintmax_t) sym->st_value);
		  result = 1;
		}

	      if (sym->st_size != 4)
		{
		  printf ("requested size 4, is %" PRIuMAX "\n",
			  (uintmax_t) sym->st_value);
		  result = 1;
		}

	      if (GELF_ST_TYPE (sym->st_info) != STT_FILE)
		{
		  printf ("requested type FILE, is %u\n",
			  (unsigned int) GELF_ST_TYPE (sym->st_info));
		  result = 1;
		}
	    }
	}

      break;
    }

 out_close2:
  elf_end (elf);
 out_close:
  close (fd);
 out:
  /* We don't need the file anymore.  */
  unlink (fname);

  ebl_closebackend (ebl);

  return result;
}