Example #1
0
Elf_Scn *
elf_newscn(Elf *e)
{
        int ec;
        void *ehdr;
        Elf_Scn *scn;

        if (e == NULL || e->e_kind != ELF_K_ELF) {
                LIBELF_SET_ERROR(ARGUMENT, 0);
                return (NULL);
        }

        if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) {
                LIBELF_SET_ERROR(CLASS, 0);
                return (NULL);
        }

        if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
                return (NULL);

        /*
         * The application may be asking for a new section descriptor
         * on an ELF object opened with ELF_C_RDWR or ELF_C_READ.  We
         * need to bring in the existing section information before
         * appending a new one to the list.
         *
         * Per the ELF(3) API, an application is allowed to open a
         * file using ELF_C_READ, mess with its internal structure and
         * use elf_update(...,ELF_C_NULL) to compute its new layout.
         */
        if (e->e_cmd != ELF_C_WRITE &&
            (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
            _libelf_load_scn(e, ehdr) == 0)
                return (NULL);

        if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) {
                assert(e->e_u.e_elf.e_nscn == 0);
                if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) ==
                    NULL)
                        return (NULL);
                e->e_u.e_elf.e_nscn++;
        }

        assert(e->e_u.e_elf.e_nscn > 0);

        if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL)
                return (NULL);

        e->e_u.e_elf.e_nscn++;

        (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY);

        return (scn);
}
Example #2
0
int
gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s)
{
	int ec;
	Elf *e;
	Elf32_Shdr *sh32;


	if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL ||
	    e->e_kind != ELF_K_ELF ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (e->e_cmd == ELF_C_READ) {
		LIBELF_SET_ERROR(MODE, 0);
		return (0);
	}

	(void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY);

	if (ec == ELFCLASS64) {
		scn->s_shdr.s_shdr64 = *s;
		return (1);
	}

	sh32 = &scn->s_shdr.s_shdr32;

	sh32->sh_name	 =  s->sh_name;
	sh32->sh_type	 =  s->sh_type;
	LIBELF_COPY_U32(sh32, s, sh_flags);
	LIBELF_COPY_U32(sh32, s, sh_addr);
	LIBELF_COPY_U32(sh32, s, sh_offset);
	LIBELF_COPY_U32(sh32, s, sh_size);
	sh32->sh_link	 =  s->sh_link;
	sh32->sh_info	 =  s->sh_info;
	LIBELF_COPY_U32(sh32, s, sh_addralign);
	LIBELF_COPY_U32(sh32, s, sh_entsize);

	return (1);
}
Example #3
0
Elf_Data *
elf_newdata(Elf_Scn *s)
{
	Elf *e;
	Elf_Data *d;

	if (s == NULL || (e = s->s_elf) == NULL ||
	    e->e_kind != ELF_K_ELF) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	/*
	 * elf_newdata() has to append a data descriptor, so
	 * bring in existing section data if not already present.
	 */
	if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data))
		if (elf_getdata(s, NULL) == NULL)
			return (NULL);

	if ((d = malloc(sizeof(Elf_Data))) == NULL) {
		LIBELF_SET_ERROR(RESOURCE, errno);
		return (NULL);
	}

	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
	d->d_flags = 0;
	d->d_scn = s;

	d->d_align = 1;
	d->d_buf = NULL;
	d->d_off = (uint64_t) ~0;
	d->d_size = 0;
	d->d_type = ELF_T_BYTE;
	d->d_version = LIBELF_PRIVATE(version);

	(void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY);

	return (d);
}
Elf_Data *
elf_newdata(Elf_Scn *s)
{
	Elf *e;
	struct _Libelf_Data *d;

	if (s == NULL || (e = s->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	assert(e->e_kind == ELF_K_ELF);

	/*
	 * elf_newdata() has to append a data descriptor, so
	 * bring in existing section data if not already present.
	 */
	if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data))
		if (elf_getdata(s, NULL) == NULL)
			return (NULL);

	if ((d = _libelf_allocate_data(s)) == NULL)
		return (NULL);

	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);

	d->d_data.d_align = 1;
	d->d_data.d_buf = NULL;
	d->d_data.d_off = (uint64_t) ~0;
	d->d_data.d_size = 0;
	d->d_data.d_type = ELF_T_BYTE;
	d->d_data.d_version = LIBELF_PRIVATE(version);

	(void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY);

	return (&d->d_data);
}
Example #5
0
int
set_dynamic (DSO *dso, GElf_Word tag, GElf_Addr value, int fatal)
{
  Elf_Data *data;
  Elf_Scn *scn;
  GElf_Dyn dyn;
  int ndx, maxndx;
  uint64_t mask = dso->info_set_mask;

  assert (dso->shdr[dso->dynamic].sh_type == SHT_DYNAMIC);

  scn = dso->scn[dso->dynamic];

  data = elf_getdata (scn, NULL);
  assert (elf_getdata (scn, data) == NULL);

  switch (tag)
    {
    case DT_CHECKSUM:
      mask |= (1ULL << DT_CHECKSUM_BIT); break;
    case DT_GNU_PRELINKED:
      mask |= (1ULL << DT_GNU_PRELINKED_BIT); break;
    case DT_VERDEF:
      mask |= (1ULL << DT_VERDEF_BIT); break;
    case DT_VERNEED:
      mask |= (1ULL << DT_VERNEED_BIT); break;
    case DT_VERSYM:
      mask |= (1ULL << DT_VERSYM_BIT); break;
    default:
      if (tag < DT_NUM && tag < 50)
	mask |= (1ULL << tag);
      break;
    }

  maxndx = data->d_size / dso->shdr[dso->dynamic].sh_entsize;
  for (ndx = 0; ndx < maxndx; ndx++)
    {
      gelfx_getdyn (dso->elf, data, ndx, &dyn);
      if (dyn.d_tag == DT_NULL)
	break;
      else if (dyn.d_tag == tag)
	{
	  if (dyn.d_un.d_ptr != value)
	    {
	      dyn.d_un.d_ptr = value;
	      gelfx_update_dyn (dso->elf, data, ndx, &dyn);
	      elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY);
	    }

	  return 0;
	}
    }
  assert (ndx < maxndx);

  if (ndx + 1 < maxndx)
    {
      /* DT_NULL is not the last dynamic entry.  */
      gelfx_update_dyn (dso->elf, data, ndx + 1, &dyn);
      dyn.d_tag = tag;
      dyn.d_un.d_ptr = value;
      gelfx_update_dyn (dso->elf, data, ndx, &dyn);
      dso->info_set_mask = mask;
      elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY);
      return 0;
    }

  if (fatal)
    error (0, 0, "%s: Not enough room to add .dynamic entry",
	   dso->filename);
  return 1;
}
Example #6
0
unsigned int
elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
{
	return (elf_flagscn(s, c, flags));
}
Example #7
0
bool saveSharedLibrary::readNewLib(){
	Elf32_Shdr *newsh, *shdr;
	Elf_Scn *scn, *newScn;
	Elf32_Ehdr *ehdr;
	Elf32_Phdr *oldPhdr;
	Elf_Data  *strdata, *newdata, *olddata;

	if ((ehdr = elf32_getehdr(newElf)) == NULL){ 
		fprintf(stderr," FAILED obtaining ehdr readNewLib\n");
		return false;
	}


	if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){
	    	if((strdata = elf_getdata(scn, NULL)) == NULL){
		 	fprintf(stderr," Failed obtaining .shstrtab data buffer \n");
			return false;
		}
	}else{
		fprintf(stderr," FAILED obtaining .shstrtab scn\n");
	}

	unsigned int newScnName =0;
	scn = NULL;
	Elf_Data shstrtabData;
#if  defined(i386_unknown_linux2_0) \
 || defined(x86_64_unknown_linux2_4) 
	/* save the PHDR from the library */
     oldPhdr = elf32_getphdr(newElf);
	Elf32_Phdr phdrBuffer[ehdr->e_phnum];
	/* 	copy it over to a buffer because, on linux, we will close newElf and reopen it.
		This closing of newElf should dealloc the data pointed to by oldPhdr
	*/
	memcpy(phdrBuffer, oldPhdr, ehdr->e_phnum * ehdr->e_phentsize);
#endif

	for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) {
		 //copy sections from newElf to newElf.

		 shdr = elf32_getshdr(scn);
		 olddata = elf_getdata(scn,NULL);


		 if(!strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){
			    textAddr = shdr->sh_addr;
				textData = olddata;
				textSize = shdr->sh_size;
		 }

		 if(!strcmp( (char*) strdata->d_buf + shdr->sh_name, ".shstrtab")){
			    const char *secname =".dyninst_mutated\0";
			    shstrtabData.d_size = olddata->d_size+strlen(secname)+1;
				newShstrtabData_d_buf = new  char[shstrtabData.d_size];
			    shstrtabData.d_buf = newShstrtabData_d_buf;
			    memcpy( shstrtabData.d_buf,  olddata->d_buf, olddata->d_size);
			    memcpy(&(((char*) shstrtabData.d_buf)[olddata->d_size]), secname,
					  strlen(secname)+1);

			    newScnName = olddata->d_size;
			    olddata->d_buf = shstrtabData.d_buf;
			    olddata->d_size = shstrtabData.d_size;

			    shdr->sh_size +=strlen(secname)+1;

				/* 	if the section header table is past this section in the
					ELF file, calculate the new offset*/
				if(ehdr ->e_shoff > shdr->sh_offset){
					ehdr->e_shoff += strlen(secname)+1;
				}
				elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);

		 }

	}



	ehdr-> e_shnum++;
	newScn = elf_newscn(newElf);

	newsh = elf32_getshdr(newScn);

	newsh->sh_name = newScnName;
	newsh->sh_type = SHT_NOBITS; // SHT_NOTE;
	newsh->sh_flags=0;
	newsh->sh_addr = 0x0;
	newsh->sh_offset = shdr->sh_offset;
	newsh->sh_size=0;
	newsh->sh_link=0;
	newsh->sh_info=0;
	newsh->sh_addralign = 0x1; //Values 0 and 1 mean the section has no alignment constraints.
	newsh->sh_entsize = 0;


	newdata = elf_newdata(newScn);
	newdata->d_size =0;
	newdata->d_buf=0;

	elf_update(newElf, ELF_C_NULL);

	/* 	elfutils on linux does not write data back to an ELF file you
		have opened correctly. Specifically, if you add a section the
		section's section header has space allocated for it in the file
		but no data is written to it. lovely, eh?

		to combat this, we reopen the file we just closed, and find the
		empty section header and fill it with data.
	*/

#if  defined(i386_unknown_linux2_0) \
 || defined(x86_64_unknown_linux2_4) 

	elf_update(newElf, ELF_C_WRITE);
  	elf_end(newElf);
	P_close(newfd);

	if((newfd = (open(newpathname, O_RDWR)))==-1){
		fprintf(stderr,"%s[%d]: cannot open new SO : %s\n",FILE__, __LINE__, newpathname);
		perror(" FAIL ");
		return false;;
	}
	if((newElf = elf_begin(newfd, ELF_C_RDWR, NULL)) ==NULL){
		fprintf(stderr,"cannot open ELF %s \n", newpathname);
		return false;;
	}
	if ((ehdr = elf32_getehdr(newElf)) == NULL){ 
		fprintf(stderr," FAILED obtaining ehdr readNewLib\n");
		return false;
	}


	if((scn = elf_getscn(newElf, ehdr->e_shstrndx)) != NULL){
	    	if((strdata = elf_getdata(scn, NULL)) == NULL){
		 	fprintf(stderr," Failed obtaining .shstrtab data buffer \n");
			return false;
		}
	}else{
		fprintf(stderr," FAILED obtaining .shstrtab scn\n");
	}

	scn = NULL;
	bool foundText=false; 
	for (int cnt = 1; (scn = elf_nextscn(newElf, scn)); cnt++) {
		 //copy sections from newElf to newElf.

		 shdr = elf32_getshdr(scn);
		 olddata = elf_getdata(scn,NULL);


		if(!foundText && !strcmp( (char *)strdata->d_buf + shdr->sh_name, ".text")){
			textAddr = shdr->sh_addr;
			textData = olddata;
			textSize = shdr->sh_size;
			elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);
			foundText = true;
		}	

	}

		/**UPDATE THE LAST SHDR **/
	memset(shdr,'\0', sizeof(Elf32_Shdr));	
	shdr->sh_name = newScnName;
	shdr->sh_addr = 0x0;
	shdr->sh_type = 7;

	/* 	update the PHDR, well just make sure it is reset to 
		what was in the original library */
     Elf32_Phdr *newPhdr = elf32_getphdr(newElf);
	memcpy(newPhdr,phdrBuffer, ehdr->e_phnum * ehdr->e_phentsize);

	/* be extra sure, set the DIRTY flag */
	elf_flagphdr(newElf, ELF_C_SET,ELF_F_DIRTY);
	elf_flagscn(scn,ELF_C_SET,ELF_F_DIRTY);
	elf_update(newElf, ELF_C_NULL);
#endif
	return true;

}
static int replaceAMDILSection(Elf* e, int nStream, MWCALtargetEnum target)
{
    Elf_Scn* scn = NULL;
    size_t shstrndx = 0;
    static const int verbose = 0;
    static const int verboseDebug = 0;

    /* Get section index of section containing the string table of section names */
    if (elf_getshdrstrndx(e, &shstrndx) != 0)
    {
        mw_printf("elf_getshdrstrndx failed: %s\n", elf_errmsg(-1));
        return 1;
    }

    /* Iterate through all the sections */
    while ((scn = elf_nextscn(e, scn)))
    {
        Elf32_Shdr* shdr;
        const char* name;

        /* Get the header for this section */
        shdr = elf32_getshdr(scn);
        if (!shdr)
        {
            mw_printf("elf32_getshdr() failed: %s\n", elf_errmsg(-1));
            return 1;
        }

        /* Look up the name of the section in the string table */
        name = elf_strptr(e, shstrndx, shdr->sh_name);
        if (!name)
        {
            mw_printf("elf_strptr() failed: %s\n", elf_errmsg(-1));
            return 1;
        }

        /*
        if (strstr(name, ".rodata") != NULL)
        {
            Elf_Data* data = elf_getdata(scn, NULL);


            FILE* f = fopen("rodata_section.bin", "wb");
            if (f)
            {
                fwrite(data->d_buf, 1, data->d_size, f);
                fclose(f);
            }
            else
            {
                perror("Failed to open file");
            }

            size_t roSize;
            char* r770RO = mwReadFileWithSize("rodata_section_RV770.bin", &roSize);
            assert(r770RO);

            data->d_buf = r770RO;
            data->d_size = roSize;


            if (!elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY))
            {
                mw_printf("elf_flagdata() failed: %s\n", elf_errmsg(-1));
                return 1;
            }

            if (!elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY))
            {
                mw_printf("elf_flagscn() failed: %s\n", elf_errmsg(-1));
                return 1;
            }

            if (elf_update(e, ELF_C_NULL) < 0)
            {
                mw_printf("elf_update(NULL) failed: %s\n", elf_errmsg(-1));
                return 1;
            }
        }
        */

        if (strstr(name, ".amdil") != NULL)
        {
            int uavId;
            const char* uavComment;
            Elf_Data* data;

            data = elf_getdata(scn, NULL);
            if (!data)
            {
                mw_printf("Failed to get data for .amdil section: %s\n", elf_errmsg(-1));
                return 1;
            }

            if (verbose)
            {
                mw_printf("Replacing section data of type %d, off %d align "ZU"\n",
                          data->d_type,
                          (int) data->d_off,
                          data->d_align);
            }


            /* Before we overwrite it, there is information we would like to extract */
            uavComment = strstr((const char*) data->d_buf, ";uavid:");
            if (!uavComment || (sscanf(uavComment, ";uavid:%d\n", &uavId) != 1))
            {
                mw_printf("Error reading uavid from IL comment\n");
                uavId = -1;
            }

            ilSrc = getILSrc(nStream, target, uavId, &ilSrcLen);
            if (!ilSrc || (ilSrcLen == 0))
            {
                mw_printf("Failed to get IL source\n");
                return 1;
            }

            data->d_buf = (void*) ilSrc;
            data->d_size = ilSrcLen;

            if (!elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY))
            {
                mw_printf("elf_flagdata() failed: %s\n", elf_errmsg(-1));
                return 1;
            }

            if (!elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY))
            {
                mw_printf("elf_flagscn() failed: %s\n", elf_errmsg(-1));
                return 1;
            }

            /* Don't let libelf rearrange the sections when writing.

               clBuildProgram() crashes on Windows if you don't do
               this with some(?) Catalyst versions
             */
            if (!elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT))
            {
                mw_printf("elf_flagelf() failed: %s\n", elf_errmsg(-1));
                return 1;
            }

            if (elf_update(e, ELF_C_NULL) < 0)
            {
                mw_printf("elf_update(NULL) failed: %s\n", elf_errmsg(-1));
                return 1;
            }
        }

        if (verboseDebug)
        {
            printf("Section %u %s\n", (unsigned int) elf_ndxscn(scn), name);
        }
    }

    if (elf_update(e, ELF_C_WRITE) < 0)
    {
        mw_printf("elf_update(ELF_C_WRITE) failed: %s\n", elf_errmsg(-1));
        return 1;
    }

    return 0;
}