c - Libelf 将条目添加到现有精灵的字符串表
问题描述
我正在尝试使用libelf
. 现在,我正在使用elf_getdata
获取数据描述符,分配一个新的更大的d_buf
并更改它的d_size
,将字符串复制到缓冲区的末尾,更改sh_size
适用的 shdr,然后使用gelf_update_shdr
然后elf_update
写入它。这不会出错,并且成功地增加了字符串表的大小,但它无法实际写入新数据:readelf
报告新字符串是.sym
如果我尝试分配一个四字符的字符串 - 即它只是从值中读取在字符串表之后的任何内容中。
这是一些可以复制的代码 - 它读取 ELF 数据,然后尝试将值添加到 strtab:
#include <libelf.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <gelf.h>
#include <string.h>
size_t strtab_put(Elf_Scn** scns, GElf_Shdr* shdrs, int which, char *string) { // put value into strtab
for (; *scns; scns++) {
if (shdrs->sh_type == SHT_STRTAB) {
if (which) {
which--; // just refer to strtabs by numeric index
} else {
break;
}
}
shdrs++;
}
if (!*scns) return -1;
Elf_Data *strtab;
strtab = elf_getdata(*scns, NULL);
for (int i = 0; i < strtab->d_size; i++) {
if (!strcmp((char*)strtab->d_buf + i, string)) { // if it's already there don't allocate a new one
return i;
}
}
strtab->d_buf = (char*)realloc((char*)strtab->d_buf, strtab->d_size + strlen(string) + 1); // realloc enough space for the new string
strcpy((char*)strtab->d_buf + strtab->d_size, string);
size_t oldsize = strtab->d_size; // also the offset into the buffer
strtab->d_size += strlen(string) + 1; // update data and shdr size
shdrs->sh_size += strlen(string) + 1;
gelf_update_shdr(*scns, shdrs);
return oldsize;
}
int main() {
elf_version(EV_CURRENT);
int fd = open("elftest", O_RDWR, 0);
Elf *elf = elf_begin(fd, ELF_C_RDWR, NULL); // load in elf from file
elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT);
GElf_Ehdr ehdr;
gelf_getehdr(elf, &ehdr);
size_t numphdrs;
elf_getphdrnum(elf, &numphdrs);
GElf_Phdr phdrs[numphdrs]; // read in phdrs
for (int i = 0; i < numphdrs; i++) {
gelf_getphdr(elf, i, &phdrs[i]);
}
Elf_Scn* scns[32];
GElf_Shdr shdrs[32]; // read in shdrs
size_t numshdrs;
Elf_Scn* curscn = NULL;
while ((curscn = elf_nextscn(elf, curscn)) != NULL) {
scns[numshdrs] = curscn;
gelf_getshdr(curscn, &shdrs[numshdrs]);
numshdrs++;
}
scns[numshdrs] = NULL;
printf("Offset of test: %lx\n", strtab_put(scns, shdrs, 1, "test"));
elf_update(elf, ELF_C_WRITE);
elf_end(elf);
close(fd);
}
这甚至是正确的方法吗?我是否忘记了一些我必须更新的属性、一些gelf_update_foo
调用等?我必须sh_offset
在它之后更新每个部分的值吗?
解决方案
推荐阅读
- jquery - 在使用 laravel 时将变量传递给 javascript 中的路由
- sql - 跨 2 个表查找部分字符串匹配的 SQL 查询
- swift - 如何使 UIView 像 UITablevViewCell 中的 Ticket
- paypal - 如何使用 paypal payout api 返回网址?
- javascript - CSS元素的点击事件
- c++ - 父类私有函数导致同名同参数子类公有函数调用不明确
- jupyter-notebook - Altair 条形图根据数据框列分配特定颜色
- xamarin - 如何以 xamarinforms mvvm 样式实现从我的数据库中删除项目的命令
- json - 从 Swift 中的 API 响应访问 JSON 数组
- java - 读取 xml 值时进行日期转换