Пример #1
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;
}
Пример #2
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 "";
}
Пример #3
0
Elf_Scn *elf_utils_new_scn_with_name(Elf *e, const char *scn_name)
{
	Elf_Scn *scn;
	GElf_Shdr shdr;
	size_t shstrndx, index, namelen;
	Elf_Data *shstrdata;
	void *ptr;

	ELF_ASSERT(elf_getshdrstrndx(e, &shstrndx) == 0);

	ELF_ASSERT(scn = elf_getscn(e, shstrndx));
	ELF_ASSERT(shstrdata = elf_getdata(scn, NULL));

	namelen = strlen(scn_name) + 1;
	ELF_ASSERT(gelf_getshdr(scn, &shdr));
	if (!elf_utils_shift_contents(e, shdr.sh_offset + shdr.sh_size, namelen))
		goto failure;
	ASSERT(ptr = realloc(shstrdata->d_buf, shstrdata->d_size + namelen));
	index = shstrdata->d_size;
	strcpy(ptr+index, scn_name);
	shstrdata->d_buf = ptr;
	shstrdata->d_size += namelen;
	shdr.sh_size += namelen;
	ELF_ASSERT(gelf_update_shdr(scn, &shdr));

	ELF_ASSERT(scn = elf_newscn(e));
	ELF_ASSERT(gelf_getshdr(scn, &shdr));
	shdr.sh_name = index;
	ELF_ASSERT(gelf_update_shdr(scn, &shdr));
	
	return scn;
failure:
	return NULL;
}
Пример #4
0
static int init_scns()
{
	Elf* e = g.e;
	size_t shstrndx = g.shstrndx;
	size_t shdrnum = g.shdrnum;

	int i = 0;
	GElf_Shdr shdr;
	Elf_Scn** buf   = (Elf_Scn**)malloc(shdrnum * sizeof(Elf_Scn*));
	GElf_Shdr* buf2 = (GElf_Shdr*)malloc(shdrnum * sizeof(GElf_Shdr));

	if (buf == NULL) {
		errx (EXIT_FAILURE , "malloc failed");
		return -1;
	}
	Elf_Scn *scn = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL && i < shdrnum) {
		if (gelf_getshdr (scn , & shdr ) != & shdr) {
			errx ( EXIT_FAILURE , " getshdr ()  failed : %s.",
			       elf_errmsg ( -1));
			free(buf);
			return -1;
		}
		buf[i]  = scn;
		buf2[i] = shdr;
		i++;
	}

	if (i < shdrnum) {
	  /* the .shstrtab section*/
	  /* size_t shstrndx; */
	  /* if (elf_getshdrstrndx (e, &shstrndx) != 0) */
	  /*   errx (EXIT_FAILURE, " getshdrstrndx ()  failed : %s.", */
	  /* 	  elf_errmsg (-1)); */
	  if ((scn = elf_getscn (e, shstrndx)) == NULL )
	    errx ( EXIT_FAILURE , " getscn ()  failed : %s.",
		   elf_errmsg ( -1));
	  if (gelf_getshdr(scn , &shdr) != & shdr )
	    errx ( EXIT_FAILURE , " getshdr ( shstrndx )  failed : %s.",
		   elf_errmsg ( -1));
	  buf[i] = scn;
	  buf2[i] = shdr;
	}

	// printf("[D] No. of sections:%d\n", i-1);
	
	g.scns  = buf;
	g.shdrs = buf2;
	
	return 0;
}
Пример #5
0
int ELF_build_symtbl(PROC_SYMTBL* symtbl){
    uint32_t sym_num;
    Elf32_Sym * sym;
    int strtab_index = 0;
    scn = NULL;
    data = NULL;
    while((scn = elf_nextscn(e, scn)) != NULL){
        if(gelf_getshdr(scn, &shdr) != &shdr){
            fprintf(stderr, "getshdr() failed.\n");
            exit(1);
        }
        strtab_index ++;
        char* name = elf_strptr(e, ehdr.e_shstrndx, shdr.sh_name);
        if(strcmp(name, ".strtab")==0)
            break;
    }

    scn = NULL;
    while((scn = elf_nextscn(e, scn)) != NULL){
        if(gelf_getshdr(scn, &shdr) != &shdr){
            fprintf(stderr, "getshdr() failed.\n");
            exit(1);
        }
        char* name = elf_strptr(e, ehdr.e_shstrndx, shdr.sh_name);
        if(strcmp(name, ".symtab")==0){
            data = elf_getdata(scn, data);
            sym_num = data->d_size/sizeof(Elf32_Sym);
            symtbl->sym_num = sym_num;
            // initial symtbl->name
            symtbl->name = malloc(sizeof(char*) * sym_num);
            int i;
            for(i=0; i<sym_num; i++)
                (symtbl->name)[i] = malloc(sizeof(char) * 100);
            // initial symtbl addr
            symtbl->addr = malloc(sizeof(uint32_t) * sym_num);
            // initial symtbl st_info
            symtbl->st_info = malloc(sizeof(unsigned char) * sym_num);
            sym = (Elf32_Sym*)data->d_buf;
            for(i=0; i<sym_num; i++){
                name = elf_strptr(e, strtab_index, sym[i].st_name);
                strcpy(symtbl->name[i], name);
                symtbl->addr[i] = sym[i].st_value;
                symtbl->st_info[i] = sym[i].st_info;
            }
        }
    }
    return 1;
}
Пример #6
0
static void handle_dynamic_section(elf_info_s *elf, Elf_Scn *scn, GElf_Shdr shdr)
{
    Elf_Data *data;
    GElf_Addr replt_addr;
    size_t replt_count;

    /* get data of .dynamic */
    data = elf_getdata(scn, NULL);

    /* iterate through .dynamic */
    for (size_t i = 0; i < shdr.sh_size / shdr.sh_entsize; ++i) {
        GElf_Dyn dyn;

        // get entries i
        gelf_getdyn(data, i, &dyn);
        // if replt
        if (dyn.d_tag == DT_JMPREL)
            replt_addr = dyn.d_un.d_ptr;
        // if replt_size
        if (dyn.d_tag == DT_PLTRELSZ)
            replt_count = dyn.d_un.d_val;
    }
    LOG(INFO, "Section relplt at 0x%lx (%zu)", replt_addr, replt_count);
    for (size_t i = 1; i < elf->hdr.e_shnum; ++i) {
        Elf_Scn *scn;
        GElf_Shdr shdr;
        scn = elf_getscn(elf->elf, i);
        gelf_getshdr(scn, &shdr);
        if (shdr.sh_addr == replt_addr && shdr.sh_size == replt_count) {
            elf->replt = elf_getdata(scn, NULL);
            elf->replt_count = shdr.sh_size / shdr.sh_entsize;
            break;
        }
    }
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
0
/* Check if Symbol 
Table 
exists */
static _Bool check_symbol_table(void)
{
	Elf_Scn *section = 0;
	int number = 0;
	while ((section = elf_nextscn(elf, section)) != 0) {
		char *name = 0;
		if (gelf_getshdr (section, &symtab_shdr) != 0) {
			if (symtab_shdr.sh_type == SHT_SYMTAB) {
				/* Change SHT_SYMTAB to SHT_DYNSYM
				 * to access the dynamic symbol table
				 */
				printf("Found Symbol Table\n");
				symtab_section = section;
				/* You can use the function given below to pri nt
				 * out the symbol table
				 * print_symbols(elf, section, shdr);
				 */
				return TRUE;
			}
		}
	}
	/* no symtab */
	printf("No symbol table found.\n");
	return FALSE;
}
Пример #10
0
int
findelfsecidx(Elf *elf, const char *file, const char *tofind)
{
	Elf_Scn *scn = NULL;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		elfterminate(file, "Couldn't read ehdr");

	while ((scn = elf_nextscn(elf, scn)) != NULL) {
		char *name;

		if (gelf_getshdr(scn, &shdr) == NULL) {
			elfterminate(file,
			    "Couldn't read header for section %d",
			    elf_ndxscn(scn));
		}

		if ((name = elf_strptr(elf, ehdr.e_shstrndx,
		    (size_t)shdr.sh_name)) == NULL) {
			elfterminate(file,
			    "Couldn't get name for section %d",
			    elf_ndxscn(scn));
		}

		if (strcmp(name, tofind) == 0)
			return (elf_ndxscn(scn));
	}

	return (-1);
}
Пример #11
0
int
find_injected_secaddr(elf_data_t *elf, inject_data_t *inject)
{
  Elf_Scn *scn;
  GElf_Shdr shdr;
  uint64_t max_inject_addr = 0;
  char* s;
  size_t shstrndx;

  if(elf_getshdrstrndx(elf->e, &shstrndx) < 0) {
    return -1;
  }

  scn = NULL;
  while((scn = elf_nextscn(elf->e, scn))) {
    if(!gelf_getshdr(scn, &shdr)) {
      return -1;
    }
    s = elf_strptr(elf->e, shstrndx, shdr.sh_name);
    if(!s) {
      return -1;
    }

    if(!strcmp(s, DYNINST_NAME))
		fprintf(finfo,"dyninst end=%lx\n",shdr.sh_addr + shdr.sh_size);
	if (shdr.sh_addr + shdr.sh_offset > max_inject_addr)
		max_inject_addr = shdr.sh_addr + shdr.sh_size;
  }
  inject->secaddr = max_inject_addr + inject->len + 0x4000;
  return 0;
}
Пример #12
0
int
elf_getphnum(Elf *elf, size_t *phnum)
{
	GElf_Ehdr	ehdr;
	Elf_Scn		*scn;
	GElf_Shdr	shdr0;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		return (0);

	if (ehdr.e_phnum != PN_XNUM) {
		*phnum = ehdr.e_phnum;
		return (1);
	}

	if ((scn = elf_getscn(elf, 0)) == NULL ||
	    gelf_getshdr(scn, &shdr0) == NULL)
		return (0);

	if (shdr0.sh_info == 0)
		*phnum = ehdr.e_phnum;
	else
		*phnum = shdr0.sh_info;

	return (1);
}
Пример #13
0
Elf_Scn *elf_utils_new_scn_with_data(Elf *e, const char *scn_name, void *buf, int len)
{
	Elf_Scn *scn;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *data;
	int offset;

	scn = elf_utils_new_scn_with_name(e, scn_name);
	if (scn == NULL)
		goto failure;

	ELF_ASSERT(gelf_getehdr(e, &ehdr));
	offset = ehdr.e_shoff;
	if (!elf_utils_shift_contents(e, offset, len))
		goto failure;

	ELF_ASSERT(gelf_getshdr(scn, &shdr));
	shdr.sh_offset = offset;
	shdr.sh_size = len;
	shdr.sh_addralign = 1;
	ELF_ASSERT(gelf_update_shdr(scn, &shdr));

	ELF_ASSERT(data = elf_newdata(scn));
	data->d_buf = buf;
	data->d_type = ELF_T_BYTE;
	data->d_version = EV_CURRENT;
	data->d_size = len;
	data->d_off = 0;
	data->d_align = 1;

	return scn;
failure:
	return NULL;
}
Пример #14
0
/**
 * @brief Search a single, particular ELF symbol table for a named symbol
 *
 * @param elf The open ELF object
 * @param symtab The ELF symbol table section
 * @param name The symbol name to find
 *
 * @returns The address to which the symbol points, 0 otherwise.
 */
static GElf_Addr elf_scn_getsymaddr_byname(Elf *elf, Elf_Scn *symtab,
                                           const char * name) {
    GElf_Shdr shdr;
    Elf_Data *data;
    uint32_t syms, i;
    GElf_Sym sym;

    if (gelf_getshdr(symtab, &shdr) == NULL || shdr.sh_type != SHT_SYMTAB) {
        return 0;
    }

    data = elf_getdata(symtab, NULL);
    if (data == NULL) {
        return 0;
    }

    syms = shdr.sh_size / shdr.sh_entsize;

    for(i=0; i<syms; i++) {
        gelf_getsym(data, i, &sym);
        if (strcmp(elf_strptr(elf, shdr.sh_link, sym.st_name), name) == 0) {
            return sym.st_value;
        }
    }

    return 0;
}
Пример #15
0
/**
 * @brief Search an elf for a named section
 *
 * @param elf The open elf object
 * @param name The section name to find
 *
 * @returns A pointer to the section if successful, NULL otherwise.
 */
static Elf_Scn * elf_getscn_byname(Elf *elf, const char * name) {
    Elf_Scn *scn = NULL;
    size_t shstrndx;
    GElf_Shdr shdr;
    char *section_name;

    if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
        fprintf(stderr, "elf_getshdrstrndx() failed: %s\n", elf_errmsg(-1));
    } else {
        /**
         * Iterate over the sections in the ELF descriptor to get the indices
         * of the .text and .data descriptors
         */
        while ((scn = elf_nextscn(elf, scn)) != NULL) {
            if (gelf_getshdr(scn, &shdr) != &shdr) {
                fprintf(stderr, "getshdr() failed: %s\n",
                    elf_errmsg(-1));
            } else {
                section_name = elf_strptr(elf, shstrndx, shdr.sh_name);
                if (section_name == NULL) {
                    fprintf(stderr, "elf_strptr() failed: %s\n",
                        elf_errmsg(-1));
                } else if (strcmp(section_name, name) == 0) {
                    break;
                }
            }
        }
    }

    return scn;
}
Пример #16
0
static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
				    GElf_Shdr *shp, const char *name,
				    size_t *idx)
{
	Elf_Scn *sec = NULL;
	size_t cnt = 1;

	/* Elf is corrupted/truncated, avoid calling elf_strptr. */
	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
		return NULL;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		char *str;

		gelf_getshdr(sec, shp);
		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
		if (!strcmp(name, str)) {
			if (idx)
				*idx = cnt;
			break;
		}
		++cnt;
	}

	return sec;
}
Пример #17
0
int
rewrite_section_name(elf_data_t *elf, inject_data_t *inject, char **err)
{
  Elf_Scn *scn;
  GElf_Shdr shdr;
  char *s;
  size_t shstrndx, stroff, strbase;

  if(strlen(inject->secname) > strlen(ABITAG_NAME)) {
    (*err) = "section name too long";
    return -1;
  }

  if(elf_getshdrstrndx(elf->e, &shstrndx) < 0) {
    (*err) = "failed to get string table section index";
    return -1;
  }

  stroff = 0;
  strbase = 0;
  scn = NULL;
  while((scn = elf_nextscn(elf->e, scn))) {
    if(!gelf_getshdr(scn, &shdr)) {
      (*err) = "failed to get section header";
      return -1;
    }

    s = elf_strptr(elf->e, shstrndx, shdr.sh_name);
    if(!s) {
      (*err) = "failed to get section name";
      return -1;
    }

    if(!strcmp(s, ABITAG_NAME)) {
      stroff = shdr.sh_name;   /* offset into shstrtab */
    } else if(!strcmp(s, SHSTRTAB_NAME)) {
      strbase = shdr.sh_offset; /* offset to start of shstrtab */
    }
  }

  if(stroff == 0) {
    (*err) = "cannot find shstrtab entry for injected section";
    return -1;
  } else if(strbase == 0) {
    (*err) = "cannot find shstrtab";
    return -1;
  }

  inject->shstroff = strbase + stroff;

  verbose("renaming rewritten section to \"%s\"", inject->secname);
  verbose("writing section string table to file");

  if(write_secname(elf, inject, err) < 0) {
    return -1;
  }

  return 0;
}
Пример #18
0
/* Try to find a symbol table in FILE.
   Returns DWFL_E_NOERROR if a proper one is found.
   Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM.  */
static Dwfl_Error
load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
	     Elf_Scn **symscn, Elf_Scn **xndxscn,
	     size_t *syments, int *first_global, GElf_Word *strshndx)
{
  bool symtab = false;
  Elf_Scn *scn = NULL;
  while ((scn = elf_nextscn (file->elf, scn)) != NULL)
    {
      GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
      if (shdr != NULL)
	switch (shdr->sh_type)
	  {
	  case SHT_SYMTAB:
	    if (shdr->sh_entsize == 0)
	      break;
	    symtab = true;
	    *symscn = scn;
	    *symfile = file;
	    *strshndx = shdr->sh_link;
	    *syments = shdr->sh_size / shdr->sh_entsize;
	    *first_global = shdr->sh_info;
	    if (*xndxscn != NULL)
	      return DWFL_E_NOERROR;
	    break;

	  case SHT_DYNSYM:
	    if (symtab)
	      break;
	    /* Use this if need be, but keep looking for SHT_SYMTAB.  */
	    if (shdr->sh_entsize == 0)
	      break;
	    *symscn = scn;
	    *symfile = file;
	    *strshndx = shdr->sh_link;
	    *syments = shdr->sh_size / shdr->sh_entsize;
	    *first_global = shdr->sh_info;
	    break;

	  case SHT_SYMTAB_SHNDX:
	    *xndxscn = scn;
	    if (symtab)
	      return DWFL_E_NOERROR;
	    break;

	  default:
	    break;
	  }
    }

  if (symtab)
    /* We found one, though no SHT_SYMTAB_SHNDX to go with it.  */
    return DWFL_E_NOERROR;

  /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
     We might have found an SHT_DYNSYM and set *SYMSCN et al though.  */
  *xndxscn = NULL;
  return DWFL_E_NO_SYMTAB;
}
Пример #19
0
bool
addr_in_section (Elf *elf, GElf_Word shndx, GElf_Addr addr)
{
  GElf_Shdr shdr;
  Elf_Scn *scn = elf_getscn (elf, shndx);
  gelf_getshdr (scn, &shdr);
  return addr >= shdr.sh_addr && addr < shdr.sh_addr + shdr.sh_size;
}
Пример #20
0
Файл: elves.c Проект: abrt/satyr
/**
 * Finds a section by its name in an ELF file.
 * @param elf
 *   A libelf handle representing the file.
 * @param section_name
 *   Name of section to be found.
 * @param data_dest
 *   Save the resulting elf data pointer here.  Cannot be NULL.
 * @param shdr_dest
 *   Save the section header here. Cannot be NULL.
 * @param error_message
 *   Will be filled by an error message if the function fails (returns
 *   zero).  Caller is responsible for calling free() on the string
 *   pointer.  If function succeeds, the pointer is not touched by the
 *   function.
 * @returns
 *   Zero on error, index of the section on success.
 */
static unsigned
find_elf_section_by_name(Elf *elf,
                         const char *section_name,
                         Elf_Data **data_dest,
                         GElf_Shdr *shdr_dest,
                         char **error_message)
{
    /* Find the string table index */
    size_t shdr_string_index;
    if (0 != elf_getshdrstrndx(elf, &shdr_string_index))
    {
        *error_message = sr_asprintf("elf_getshdrstrndx failed");
        return 0;
    }

    unsigned section_index = 0;
    Elf_Scn *section = NULL;
    while ((section = elf_nextscn(elf, section)) != NULL)
    {
        /* Starting index is 1. */
        ++section_index;

        GElf_Shdr shdr;
        if (gelf_getshdr(section, &shdr) != &shdr)
        {
            *error_message = sr_asprintf("gelf_getshdr failed");
            return 0;
        }

        const char *current_section_name = elf_strptr(elf,
                                                      shdr_string_index,
                                                      shdr.sh_name);

        if (!current_section_name)
        {
            *error_message = sr_asprintf("elf_strptr failed");
            return 0;
        }

        if (0 == strcmp(current_section_name, section_name))
        {
            /* We found the right section!  Save the data. */
            *data_dest = elf_getdata(section, NULL);
            if (!*data_dest)
            {
                *error_message = sr_asprintf("elf_getdata failed");
                return 0;
            }

            /* Save the section header. */
            *shdr_dest = shdr;
            return section_index;
        }
    }

    *error_message = sr_asprintf("Section %s not found", section_name);
    return 0;
}
Пример #21
0
static void
find_section_base(const char *exe, Elf *e, const char *section)
{
	Dwarf_Addr off;
	Elf_Scn *scn;
	GElf_Ehdr eh;
	GElf_Shdr sh;
	size_t shstrndx;
	int elferr;
	const char *name;

	if (gelf_getehdr(e, &eh) != &eh) {
		warnx("gelf_getehdr failed: %s", elf_errmsg(-1));
		return;
	}

	if (!elf_getshstrndx(e, &shstrndx)) {
		warnx("elf_getshstrndx failed: %s", elf_errmsg(-1));
		return;
	}

	(void) elf_errno();
	off = 0;
	scn = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &sh) == NULL) {
			warnx("gelf_getshdr failed: %s", elf_errmsg(-1));
			continue;
		}
		if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL)
			goto next;
		if (!strcmp(section, name)) {
			if (eh.e_type == ET_EXEC || eh.e_type == ET_DYN) {
				/*
				 * For executables, section base is the virtual
				 * address of the specified section.
				 */
				section_base = sh.sh_addr;
			} else if (eh.e_type == ET_REL) {
				/*
				 * For relocatables, section base is the
				 * relative offset of the specified section
				 * to the start of the first section.
				 */
				section_base = off;
			} else
				warnx("unknown e_type %u", eh.e_type);
			return;
		}
	next:
		off += sh.sh_size;
	}
	elferr = elf_errno();
	if (elferr != 0)
		warnx("elf_nextscn failed: %s", elf_errmsg(elferr));

	errx(EXIT_FAILURE, "%s: cannot find section %s", exe, section);
}
Пример #22
0
const char *get_scn_name(vita_elf_t *ve, Elf_Scn *scn)
{
	size_t shstrndx;
	GElf_Shdr shdr;

	elf_getshdrstrndx(ve->elf, &shstrndx);
	gelf_getshdr(scn, &shdr);
	return elf_strptr(ve->elf, shstrndx, shdr.sh_name);
}
Пример #23
0
/*
 * @param e         elf handle
 * @param name      name of section to be found
 * @param filename  filename for logging messages
 * @param dest      save the resulting elf data pointer here (can be NULL)
 * @param shdr_dest save the section header here (can be NULL)
 * @returns zero on error, index of the section on success
 */
static unsigned xelf_section_by_name(Elf *e, const char *name, const char *filename, Elf_Data **dest, GElf_Shdr *shdr_dest)
{
    Elf_Scn *scn = NULL;
    GElf_Shdr shdr;
    unsigned section_index = 0;
    size_t shstrndx;

    /* Find the string table index */
    if (elf_getshdrstrndx(e, &shstrndx) != 0)
    {
        VERB1 log_elf_error("elf_getshdrstrndx", filename);
        return 0;
    }

    while ((scn = elf_nextscn(e, scn)) != NULL)
    {
        section_index++; /* starting index is 1 */

        if (gelf_getshdr(scn, &shdr) != &shdr)
        {
            VERB1 log_elf_error("gelf_getshdr", filename);
            continue;
        }

        const char *scnname = elf_strptr(e, shstrndx, shdr.sh_name);
        if (scnname == NULL)
        {
            VERB1 log_elf_error("elf_strptr", filename);
            continue;
        }

        if (strcmp(scnname, name) == 0)
        {
            /* Found, save data */
            if (dest)
            {
                *dest = elf_getdata(scn, NULL);
                if (*dest == NULL)
                {
                    VERB1 log_elf_error("elf_getdata", filename);
                    break;
                }
            }

            /* save shdr */
            if (shdr_dest)
            {
                *shdr_dest = shdr;
            }

            return section_index;
        }
    }

    VERB1 log("Section %s not found in %s\n", name, filename);
    return 0;
}
Пример #24
0
static void
check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
{
  GElf_Shdr shdr_mem;
  GElf_Shdr *shdr;

  /* Get the section header data.  */
  shdr = gelf_getshdr (scn, &shdr_mem);
  if (shdr == NULL)
    /* This should never happen.  If it does something is
       wrong in the libelf library.  */
    abort ();


  /* Make sure the section is part of a section group only iff we
     really need it.  If we are looking for the global (= non-section
     group debug info) we have to ignore all the info in section
     groups.  If we are looking into a section group we cannot look at
     a section which isn't part of the section group.  */
  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
    /* Ignore the section.  */
    return;


  /* We recognize the DWARF section by their names.  This is not very
     safe and stable but the best we can do.  */
  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
				    shdr->sh_name);
  if (scnname == NULL)
    {
      /* The section name must be valid.  Otherwise is the ELF file
	 invalid.  */
      __libdw_seterrno (DWARF_E_INVALID_ELF);
      free (result);
      return;
    }


  /* Recognize the various sections.  Most names start with .debug_.  */
  size_t cnt;
  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
    if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
      {
	/* Found it.  Remember where the data is.  */
	if (unlikely (result->sectiondata[cnt] != NULL))
	  /* A section appears twice.  That's bad.  We ignore the section.  */
	  break;

	/* Get the section data.  */
	Elf_Data *data = elf_getdata (scn, NULL);
	if (data != NULL && data->d_size != 0)
	  /* Yep, there is actually data available.  */
	  result->sectiondata[cnt] = data;

	break;
      }
}
Пример #25
0
static void update_dyn_cache(ElfCreator *ctor)
{
	ctor->dynscn = get_scn_by_type(ctor, SHT_DYNAMIC);
	if (ctor->dynscn == NULL)
		return;

	ctor->dynshdr = gelf_getshdr(ctor->dynscn, &ctor->dynshdr_mem);
	ctor->dyndata = elf_getdata(ctor->dynscn, NULL);
}
Пример #26
0
int
internal_function
__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
{
  size_t shstrndx = SHN_UNDEF;
  int result = 0;

  Elf_Scn *scn = elf_nextscn (elf, NULL);

  if (scn == NULL)
    {
      /* No sections, have to look for phdrs.  */
      GElf_Ehdr ehdr_mem;
      GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
      size_t phnum;
      if (unlikely (ehdr == NULL)
	  || unlikely (elf_getphdrnum (elf, &phnum) != 0))
	{
	  __libdwfl_seterrno (DWFL_E_LIBELF);
	  return -1;
	}
      for (size_t i = 0; result == 0 && i < phnum; ++i)
	{
	  GElf_Phdr phdr_mem;
	  GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
	  if (likely (phdr != NULL) && phdr->p_type == PT_NOTE)
	    result = check_notes (mod, set,
				  elf_getdata_rawchunk (elf,
							phdr->p_offset,
							phdr->p_filesz,
							ELF_T_NHDR),
				  phdr->p_vaddr + mod->main.bias);
	}
    }
  else
    do
      {
	GElf_Shdr shdr_mem;
	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
	if (likely (shdr != NULL) && shdr->sh_type == SHT_NOTE)
	  {
	    /* Determine the right sh_addr in this module.  */
	    GElf_Addr vaddr = 0;
	    if (!(shdr->sh_flags & SHF_ALLOC))
	      vaddr = NO_VADDR;
	    else if (mod->e_type != ET_REL)
	      vaddr = shdr->sh_addr + mod->main.bias;
	    else if (__libdwfl_relocate_value (mod, elf, &shstrndx,
					       elf_ndxscn (scn), &vaddr))
	      vaddr = NO_VADDR;
	    result = check_notes (mod, set, elf_getdata (scn, NULL), vaddr);
	  }
      }
    while (result == 0 && (scn = elf_nextscn (elf, scn)) != NULL);

  return result;
}
Пример #27
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);
}
Пример #28
0
uint8_t *dump_section_data(Elf *elf_object, int *size)
{
	uint8_t *buffer = NULL;
	Elf_Data *data = NULL;
	size_t shdr_num;
	size_t max_saddr = 0;
	GElf_Shdr shdr;
	size_t shstrndx;
	char *name = NULL;

	*size = 0;

	int ret = elf_getshdrnum(elf_object, &shdr_num);
	if (ret) {
		printf("Problem during ELF parsing\n");
		return NULL;
	}

	if (shdr_num == 0)
		return NULL;

	Elf_Scn *cur_section = NULL;
	ret = elf_getshdrstrndx(elf_object, &shstrndx);
	if (ret)
		printf("No string table found\n");

	while ((cur_section = elf_nextscn(elf_object, cur_section)) != NULL ) {
		if (gelf_getshdr(cur_section, &shdr) != &shdr) {
			printf("Problem during ELF parsing\n");
			return NULL;
		}

		if ((shdr.sh_type == SHT_PROGBITS) && (shdr.sh_flags & SHF_ALLOC) && shdr.sh_size != 0) {

			name = elf_strptr(elf_object, shstrndx , shdr.sh_name);
			printf("Loading section %s, size 0x%08X lma 0x%08X\n",
				name ? name : "??", (unsigned int)shdr.sh_size, (unsigned int)shdr.sh_addr);

			if (shdr.sh_addr + shdr.sh_size >= max_saddr) {
				max_saddr = shdr.sh_addr + shdr.sh_size;
				buffer = realloc(buffer, max_saddr);
			}

			data = elf_getdata(cur_section, data);
			if (data != NULL)
				memcpy(buffer + shdr.sh_addr, data->d_buf, data->d_size);
			else {
				printf("Couldn't load section data chunk\n");
				return NULL;
			}
		}
	}

	*size = max_saddr;
	return buffer;
}
Пример #29
0
static const char *
elf_section_name (Elf *elf, GElf_Word shndx)
{
  GElf_Ehdr ehdr;
  GElf_Shdr shdr;
  Elf_Scn *scn = elf_getscn (elf, shndx);
  gelf_getshdr (scn, &shdr);
  gelf_getehdr (elf, &ehdr);
  return elf_strptr (elf, ehdr.e_shstrndx, shdr.sh_name);
}
Пример #30
0
/*
 * Print the symbol table.  This function does not print the contents
 * of the symbol table but sets up the parameters and then calls
 * print_symtab to print the symbols.  This function does not assume
 * that there is only one section of type SYMTAB.  Input is an opened
 * ELF file, a pointer to the ELF header, and the filename.
 */
static void
get_symtab(Elf *elf_file, char *filename)
{
	Elf_Scn	*scn, *scnfd;
	Elf_Data *data;
	GElf_Word symtabtype;
	size_t shstrndx;

	if (elf_getshdrstrndx(elf_file, &shstrndx) == -1) {
		(void) fprintf(stderr, gettext(
		    "%s: %s: cannot get e_shstrndx\n"),
		    prog_name, filename);
		return;
	}

	/* get section header string table */
	scnfd = get_scnfd(elf_file, shstrndx, SHT_STRTAB);
	if (scnfd == NULL) {
		(void) fprintf(stderr, gettext(
		    "%s: %s: cannot get string table\n"),
		    prog_name, filename);
		return;
	}

	data = elf_getdata(scnfd, NULL);
	if (data->d_size == 0) {
		(void) fprintf(stderr, gettext(
		    "%s: %s: no data in string table\n"),
		    prog_name, filename);
		return;
	}

	if (D_flag)
		symtabtype = SHT_DYNSYM;
	else if (L_flag)
		symtabtype = SHT_SUNW_LDYNSYM;
	else
		symtabtype = SHT_SYMTAB;

	scn = 0;
	while ((scn = elf_nextscn(elf_file, scn)) != 0)	{
		GElf_Shdr shdr;

		if (gelf_getshdr(scn, &shdr) == NULL) {
			(void) fprintf(stderr, "%s: %s: %s:\n",
			    prog_name, filename, elf_errmsg(-1));
			return;
		}

		if (shdr.sh_type == symtabtype)	{
			print_symtab(elf_file, shstrndx, scn,
			    &shdr, filename);
		}
	} /* end while */
}