C Libelf将条目添加到现有elf的字符串表中

C Libelf将条目添加到现有elf的字符串表中,c,elf,C,Elf,我试图使用libelf在现有ELF二进制文件中向(symbol)字符串表添加一个条目。现在,我正在使用elf_getdata获取数据描述符,分配一个新的更大的d_buf并更改其d_大小,将字符串复制到缓冲区的末尾,更改适用shdr的sh_大小,使用gelf_update_shdr然后elf_update写入。这不会出错,并且成功地增加了字符串表的大小,但它实际上无法写入新数据:readelf报告如果我尝试分配一个四个字符的字符串,则新字符串是.sym,即它只是从字符串表后面的任何字符串中读取值

我试图使用
libelf
在现有ELF二进制文件中向(symbol)字符串表添加一个条目。现在,我正在使用
elf_getdata
获取数据描述符,分配一个新的更大的
d_buf
并更改其
d_大小
,将字符串复制到缓冲区的末尾,更改适用shdr的
sh_大小
,使用
gelf_update_shdr
然后
elf_update
写入。这不会出错,并且成功地增加了字符串表的大小,但它实际上无法写入新数据:
readelf
报告如果我尝试分配一个四个字符的字符串,则新字符串是
.sym
,即它只是从字符串表后面的任何字符串中读取值

下面是一些可以复制此功能的代码—它读入ELF数据,然后尝试将值添加到STRAB:

#包括
#包括
#包括
#包括
#包括
#包括
#包括
大小\u t strtab\u put(Elf\u Scn**scns,GElf\u Shdr*shdrs,int which,char*string){//将值放入strtab
对于(;*scns;scns++){
如果(shdrs->sh_type==SHT_STRTAB){
如果(哪个){
其中--;//只需通过数字索引引用strtabs
}否则{
打破
}
}
shdrs++;
}
如果(!*scns)返回-1;
Elf_数据*strtab;
strtab=elf_getdata(*scns,NULL);
对于(int i=0;id_size;i++){
如果(!strcmp((char*)strtab->d_buf+i,string)){//如果已经存在,则不分配新的
返回i;
}
}   
strtab->d_buf=(char*)realloc((char*)strtab->d_buf,strtab->d_size+strlen(string)+1);//realloc为新字符串提供足够的空间
strcpy((char*)strtab->d_buf+strtab->d_大小,字符串);
size\u t oldsize=strtab->d\u size;//还包括缓冲区中的偏移量
strtab->d_size+=strlen(字符串)+1;//更新数据和shdr大小
shdrs->sh_size+=strlen(字符串)+1;
gelf_更新_shdr(*SCN、shdr);
返回旧尺寸;
}
int main(){
elf_版本(EV_电流);
int fd=打开(“elftest”,O_RDWR,0);
Elf*Elf=Elf_begin(fd,Elf_C_RDWR,NULL);//从文件加载到Elf中
elf_-flagelf(elf、elf_-C_集、elf_-F_布局);
GElf_Ehdr Ehdr;
gelf_getehdr(elf和ehdr);
尺寸(单位:mm);
elf_getphdrnum(elf和numphdrs);
GElf_Phdr phdrs[numphdrs];//读入phdrs
对于(int i=0;i

这是正确的方法吗?我是否忘记了一些我必须更新的属性,一些
gelf\u update\u foo
调用,等等。?我是否必须更新之后每个部分的
sh_offset
值?

您可能需要添加代码来显示哪些部分不起作用。您是否正在尝试更改
ET_REL
ET_EXEC
/
ET_DYN
?前者应该有效,后者很可能无效。我认为它是
ET_DYN
,但即使将其更改为
ET_EXEC
(即使用
-无饼
重新编译),它仍然以同样的方式失败。