#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <elf.h>
void help();
void fileheader(const char *pbuff); //读取文件header函数
void sectionheader(const char *pbuff); //读取section头
void tableheader(const char *pbuff); //读取符号表信息
void outputsyminfo(const Elf64_Sym *psym, const char *pbuffstr, int ncount);
void programheader(const char *pbuff); //读取程序头函数
void relocheader(const char *pbuff); //重定位函数
int main(int argc, char * argv[])
{
/*在C中,argc是指参数个数,这个值是包含执行程序名在内的个数值,即:argv[0]是执行程序名,argv[1]...是程序的参数*/
if(argc != 3) //linux 命令行全部都是参数 设置好第一个参数是指令,第二个是解析文件
{
printf("输入参数不对 ./elf -指令 文件位置!\n");
help();
return 0;
}
//打开指定文件
int fd = open(argv[2], O_RDONLY, 0);
if(-1 == fd)
{
perror("文件打开失败!\n");
return 0;
}
//分配文件大小
long int end = lseek(fd, 0, SEEK_END);
long int begin = lseek(fd, 0, SEEK_SET);
char* pbuff = malloc(end);
if(!pbuff)
{
printf("文件分配内存失败\n");
return 0;
}
//初始化0
memset(pbuff, 0, end);
if(-1 == read(fd, pbuff, end))
{
perror("文件读取失败");
return 0;
}
//指令分类
if(!strcmp(argv[1], "-h"))
{
fileheader(pbuff); //读取文件header
}
else if(!strcmp(argv[1], "-S"))
{
sectionheader(pbuff); //读取节区表函数
}
else if(!strcmp(argv[1], "-s"))
{
tableheader(pbuff); //打印符号表信息
}
else if(!strcmp(argv[1], "-l"))
{
programheader(pbuff); //读取程序头函数
}
else if(!strcmp(argv[1], "-r"))
{
relocheader(pbuff); //重定位函数
}
return 0;
}
void help()
{
printf("这是zzzyyyy的解析器demo\n");
printf("-h :头部信息\n");
printf("-S :节区表信息\n");
printf("-s :符号表信息\n");
printf("-l :程序头信息\n");
printf("-r :重定位表信息\n");
}
//重定位函数
void relocheader(const char *pbuff)
{
Elf64_Ehdr* pfilehead = (Elf64_Ehdr*)pbuff;
Elf64_Shdr* psecheader = (Elf64_Shdr*)(pbuff + pfilehead->e_shoff);
Elf64_Shdr* pshstr = (Elf64_Shdr*)(psecheader + pfilehead->e_shstrndx);
char* pstrbuff = (char*)(pbuff + pshstr->sh_offset);
for(int i = 0;i<pfilehead->e_shnum;++i)
{
if(!strncmp(psecheader[i].sh_name + pstrbuff, ".rel", 4))
{
int ncount = psecheader[i].sh_size / psecheader[i].sh_entsize;
printf("\r\n重定位节'%s' 位于偏移量 %0lX 含有 %d 条目:\r\n", psecheader[i].sh_name + pstrbuff, psecheader[i].sh_offset,
ncount);
Elf64_Rela* preltable = (Elf64_Rela*)(pbuff + psecheader[i].sh_offset);
printf("%-16s %-16s %-16s %-16s %-16s\r\n", "偏移量", "信息", "类型 ", "符号值", "符号名称 + 加数");
int symnum = psecheader[i].sh_link;
int strnum = psecheader[symnum].sh_link;
//开始位置
char* prelstrbuf = (char*)(psecheader[strnum].sh_offset + pbuff);
//symbol
Elf64_Sym* psym = (Elf64_Sym*)(pbuff + psecheader[symnum].sh_offset);
for(int n = 0;n<ncount;++n)
{
printf("%016lX %016lX ", preltable[n].r_offset, preltable[n].r_info);
switch(ELF64_R_TYPE(preltable[n].r_info))
{
case R_386_NONE:
printf("%-16s", "R_386_NONE");break;
case R_386_32:
printf("%-16s", "R_386_32");break;
case R_386_PC32:
printf("%-16s", "R_386_PC32");break;
case R_386_GOT32:
printf("%-16s", "R_386_GOT32");break;
case R_386_PLT32:
printf("%-16s", "R_386_PLT32");break;
case R_386_COPY:
printf("%-16s", "R_386_COPY");break;
case R_386_GLOB_DAT:
printf("%-16s", "R_386_GLOB_DAT");break;
case R_386_JMP_SLOT:
printf("%-16s", "R_386_JMP_SLOT");break;
case R_386_RELATIVE:
printf("%-16s", "R_386_RELATIVE");break;
case R_386_GOTOFF:
printf("%-16s", "R_386_GOTOFF");break;
case R_386_GOTPC:
printf("%-16s", "R_386_GOTPC");break;
default:
break;
}
printf(" %016lX ", (psym + ELF64_R_SYM(preltable[n].r_info))->st_value);
printf("%s + %lu\r\n", (char*)(prelstrbuf + (psym + ELF64_R_SYM(preltable[n].r_info))->st_name), preltable[n].r_addend);
}
}
}
}
//读取程序头函数
void programheader(const char *pbuff)
{
Elf64_Ehdr* pfilehead = (Elf64_Ehdr*)pbuff;
Elf64_Phdr* pproheader = (Elf64_Phdr*)(pbuff + pfilehead->e_phoff);
Elf64_Shdr* psecheader = (Elf64_Shdr*)(pbuff + pfilehead->e_shoff);
Elf64_Shdr* pshstr = (Elf64_Shdr*)(psecheader + pfilehead->e_shstrndx);
char* pstrbuff = (char*)(pbuff + pshstr->sh_offset);
printf("Elf 文件类型为");
switch(pfilehead->e_type)
{
case 0:
printf(" No file type\r\n");
break;
case 1:
printf(" Relocatable file(可重定向文件)\r\n");
break;
case 2:
printf(" Executable file(可执行文件)\r\n");
break;
case 3:
printf(" Shared object file(共享目标文件)\r\n");
break;
case 4:
printf(" Core file(核心文件)\r\n");
break;
default:
printf(" ERROR\r\n");
break;
}
printf("入口点 0X%0lX\r\n", pfilehead->e_entry);
printf("共有 %d 程序头, 开始于偏移量 %lu\r\n\r\n", pfilehead->e_phnum, pfilehead->e_phoff);
printf("Program Headers:\r\n");
printf(" %-14s %-16s %-16s %-16s\r\n", "Type", "Offset", "VirtAddr", "PhysAddr");
printf(" %-14s %-16s %-16s %-6s %-6s\r\n", "", "FileSiz", "MemSiz", "Flags", "Align");
for(int i=0;i<pfilehead->e_phnum;++i)
{
//type
switch(pproheader[i].p_type)
{
case PT_NULL:
printf(" %-14s %016lX %016lX %016lX\r\n %-14s %016lX %016lX ", "", pproheader[i].p_offset, pproheader[i].p_vaddr,
pproheader[i].p_paddr, "", pproheader[i].p_filesz, pproheader[i].p_memsz);break;
case PT_LOAD:
printf(" %-14s %016lX %016lX %016lX\r\n %-14s %016lX %016lX ", "LOAD", pproheader[i].p_offset, pproheader[i].p_vaddr,
pproheader[i].p_paddr, "", pproheader[i].p_filesz, pproheader[i].p_memsz);break;
case PT_DYNAMIC:
printf(" %-14s %016lX %016lX %016lX\r\n %-14s %016lX %016lX ", "DYNAMIC", pproheader[i].p_offset, pproheader[i].p_vaddr,
pproheader[i].p_paddr, "", pproheader[i].p_filesz, pproheader[i].p_memsz);break;
case PT_INTERP:
printf(" %-14s %016lX %016lX %016lX\r\n %-14s %016lX %016lX ", "INTERP", pproheader[i].p_offset, pproheader[i].p_vaddr,
pproheader[i].p_paddr, "", pproheader[i].p_filesz, pproheader[i].p_memsz);break;
case PT_NOTE:
printf(" %-14s %016lX %016lX %016lX\r\n %-14s %016lX %016lX ", "NOTE", pproheader[i].p_offset, pproheader[i].p_vaddr,
pproheader[i
linux,elf文件内容解析器,实现readelf的功能
5星 · 超过95%的资源 需积分: 30 13 浏览量
2022-07-16
09:06:46
上传
评论 1
收藏 48KB RAR 举报
Believer_YU
- 粉丝: 28
- 资源: 3
最新资源
- 电力场景设备漏油检测数据集VOC+YOLO格式338张1类别.7z
- 基于yolov8+pyqt5实现精美界面支持图片视频和摄像检测源码.zip
- 用C语言为母亲节献上一份特别的祝福.zip
- LCD1602液晶显示屏的深入探索与实用指南.zip
- 基于Matlab人脸肤色定理的教师人数统计+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab霍夫曼变换的表盘读数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab火灾烟雾检测源码带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的恶劣天气交通标志识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的霍夫曼变换的表盘示数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的车道线识别系统 +源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论5