ELF文件C语言解析

推荐y博士视频:ELF文件和链接
推荐博客:C语言的ELF文件格式学习

程序举例:

#include <stdio.h>
#include <stdlib.h>

int data[100] ={0};
int bss[100];

int main()
{
   int i=0;
   for(i=0; i<100; i++)
      bss[i] = i;
   printf("the bss[3]= %d\n", bss[3]);
   return 0;

}

利用命令 readelf -h 读取生成的可执行文件
在这里插入图片描述
对应的我们可以打开man elf 查看
在这里插入图片描述
上述两图是相互对应的。
在这里插入图片描述
上述图片是elf文件格式的排布,我们能够看到程序头表以及Section头表,利用如下命令得到elf文件:

readelf -a 可执行文件 | vim -

我们这里不讨论程序头表,讨论section头表,section头表的初始位置以及每个表元素的大小以及个数在ELF_enhd结构体中都存在,可以解析出来。
在这里插入图片描述
例如我们此时解析出 symtab 以及 strtab中的初始地址以及大小,首先我们继续看文档,section header包含哪些信息:
在这里插入图片描述
首先sh_name为section序号
sh_type为section的总类:包括:SHT_NULL、SHT_PROGBITS、SHT_STRTAB、SHT_SYMTAB等,我们发现我们可以通过这个遍历这个参数得到我们要的表头,

sh_offeset: 该成员的值保存了从文件开始到section中第一个字节的字节偏移量。
sh_size:该成员以字节为单位保存了section的大小。

sh_entsize:有些section保存一个固定大小的表,比如符号表。对于这样的section,该成员给出每个条目的字节大小。如果section中没有固定大小的表,则该成员为0条目。

上述三个参数能够让我们对SYMTAB以及STRTAB两个表进行定位。

随后我们找到SYMTAB中带有TYPE为FUNC的符号头,通过相同的方法,遍历SYM,sym的头结构体如下所示:
在这里插入图片描述
要遍历的symtab如图所示:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了解析ELF文件并获取链接脚本,您可以使用类似libelf的库。Libelf是一种开放源代码库,可用于访问ELF文件的内容。以下是一个简短的C程序示例,该程序使用libelf解析ELF文件并获取链接脚本: ``` #include <fcntl.h> #include <libelf.h> #include <stdio.h> int main() { //打开ELF文件 int fd = open("path/to/elf", O_RDONLY, 0); if (fd < 0) { perror("open failed"); return 1; } //加载ELF文件 Elf *e = elf_begin(fd, ELF_C_READ, NULL); if (e == NULL) { perror("elf_begin failed"); return 1; } //获取链接脚本的字符串节 size_t shstrndx; if (elf_getshdrstrndx(e, &shstrndx) != 0) { perror("elf_getshdrstrndx failed"); return 1; } Elf_Scn *scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { //获取节 GElf_Shdr shdr; if (gelf_getshdr(scn, &shdr) != &shdr) { perror("gelf_getshdr failed"); return 1; } //获取节名 char *sec_name = elf_strptr(e, shstrndx, shdr.sh_name); if (sec_name == NULL) { perror("elf_strptr failed"); return 1; } //如果是链接脚本节 if (shdr.sh_type == SHT_PROGBITS && strcmp(sec_name, ".linker_script") == 0) { //获取数据 char *data = (char*)malloc(shdr.sh_size); if (data == NULL) { perror("malloc failed"); return 1; } if (gelf_getdata(scn, data, shdr.sh_size, shdr.sh_offset) == NULL) { perror("gelf_getdata failed"); return 1; } //打印链接脚本数据 printf("%s\n", data); free(data); } } //释放ELF 文件 elf_end(e); close(fd); return 0; } ``` 请注意,这只是一个简单的示例程序。实际上,解析ELF文件可能会更复杂,取决于所需的信息类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值