编程读取ELF文件头
来源:互联网 发布:win10内存优化软件 编辑:程序博客网 时间:2024/06/05 01:54
一个C语言源程序(.c文件)经过汇编以后生成目标文件(.o文件),目标文件再经过链接生成可执行文件。在linux系统中,目标文件和可执行文件都是ELF格式的,了解ELF文件的结构对于理解程序的编译、链接和装载运行至关重要。ELF文件的格式如下图所示,以文件头(ELF Header)开始,后面跟着代码段(.text)、数据段(.data)等。
ELF Header
.text
.data
.bss
.rodata
…
Other sections
Section header table
String Tables
Symbol Tables
…
文件头中保存着文件的基本属性,要解析整个ELF文件,必须从文件头开始。下面自己编写一个小程序来读取ELF文件头,它的功能等价于Linux提供的命令readelf -h xxx.o。自己写代码实现这些命令能加深对ELF文件结构的理解。
ELF文件头的结构定义在/usr/include/elf.h文件中,分32位和64位两种:
32位:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size*/
Elf32_Half e_phnum; /* Program header table entrycount */
Elf32_Half e_shentsize; /* Section header table entry size*/
Elf32_Half e_shnum; /* Section header table entrycount */
Elf32_Half e_shstrndx; /* Section header string tableindex */
} Elf32_Ehdr;
64位:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /*Object file type */
Elf64_Half e_machine; /*Architecture */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Programheader table file offset */
Elf64_Off e_shoff; /* Sectionheader table file offset */
Elf64_Word e_flags; /*Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header sizein bytes */
Elf64_Half e_phentsize; /* Program header table entry size */
Elf64_Half e_phnum; /* Program header table entry count */
Elf64_Half e_shentsize; /* Section header table entry size */
Elf64_Half e_shnum; /* Section header table entry count */
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;
因为我的ubuntulinux是64位的操作系统,所以下面的程序中,我用的是Elf64_Ehdr类型的结构体elfheader来存储文件头。其中,Elf64_Half是unsigned short int类型(2字节),Elf64_Word是unsigned int类型(4字节),Elf64_Addr是unsigned long int类型(8字节),Elf64_Off是unsigned long int类型(8字节)。程序以只读方式(r或者rb模式)打开目标文件elftest2.o,然后用fread函数从文件中读出一块大小为sizeof(Elf64_Ehdr)(64字节)的内容到elfheader中,最后把文件头中每一部分打印输出。
//read_ELFheader.c (ubuntu)
#include "stdio.h"
#include "/usr/include/elf.h"
int main()
{
FILE * fp;
int i;
Elf64_Ehdr elfheader;
fp= fopen("elftest2.o","r");
fread(&elfheader,sizeof(Elf64_Ehdr),1,fp);
for(i=0;i<16; i++)
printf("%x",elfheader.e_ident[i]);
printf("\n");
printf("%hx\n", elfheader.e_type);
printf("%hx\n", elfheader.e_machine);
printf("%x\n", elfheader.e_version);
printf("%lx\n", elfheader.e_entry);
printf("%lx\n", elfheader.e_phoff);
printf("%lx\n", elfheader.e_shoff);
printf("%x\n", elfheader.e_flags);
printf("%hx\n", elfheader.e_ehsize);
printf("%hx\n", elfheader.e_phentsize);
printf("%hx\n", elfheader.e_phnum);
printf("%hx\n", elfheader.e_shentsize);
printf("%hx\n", elfheader.e_shnum);
printf("%hx\n", elfheader.e_shstrndx);
return 0;
}
读取了文件头以后,就可以利用elfheader.e_shoff (段表的偏移)来进一步读取段表,从而对各个段进行解析。
- 编程读取ELF文件头
- ELF文件头读取修改
- ELF头文件学习
- ELF文件头分析
- ELF文件头结构
- ELF文件格式(一)--ELF文件头
- Bfd对elf文件头的处理
- ELF文件-段和程序头
- ELF文件头更详细结构
- ELF(二)ELF头
- 读取wav文件头
- 一个简单的elf文件头查看工具
- 简单SO加密及ELF头文件修复
- 如何读取MP3头文件
- 读取bmp文件头出错
- python 读取DICOM头文件
- ELF文件解析之 ELF头 程序头表 节头表-补充之前文章代码 只支持32位 出版
- ELF程序头分析
- stm32f10x学习一 存储器和总线构架
- 动态规划1011
- 多线程(二) 同步 锁对象和条件对象
- osg创建简单图元(2)
- 将接收的二进制流转换成图片保存
- 编程读取ELF文件头
- 常规功能和模块自定义系统 (cfcmms)—048模块导航功能的重构(6)以后的设想
- 另眼观宝岛之一
- JamesMusic浅读--------5,文件选择系统的数据库绑定
- DP 1014
- 客户端架构
- go语言的模板,text/template包
- 到底买不买,找零钱,字符统计,输出PATest
- Android 基础总结:(五)Service详解(上)