- 论坛徽章:
- 0
|
ELF文件头(ELF header ),顾名思义,就是指一个ELF文件字节流的最开头的一部分。
它是多大呢?请看下面的小程序:
/*打印Elf32_Ehdr和Elf64_Ehdr结构的大小*/
#include
#include
int main()
{
printf("Elf32_Ehdr:%d\n",sizeof(Elf32_Ehdr));
printf("Elf64_Ehdr:%d\n",sizeof(Elf64_Ehdr));
return 0;
}
编译命令:
$ gcc -o test test.c
$ ./test
Elf32_Ehdr:52
Elf64_Ehdr:64
$
程序中包含了elf.h头文件,它位于/usr/include目录下。
elf.h文件中定义了Elf32_Ehdr和Elf64_Ehdr结构,程序用于打印这两个结构类型的大小。
这样,我们就知道,对于32位系统的ELF文件来说,它的前52个字节就是ELF header了。同理,64位系统的ELF文件的前64个字节是它的ELF header。
下面给出elf.h中这两个结构类型的定义:
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 entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
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; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size in 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;
在此系列的文章中,我只关注于32位系统的ELF文件格式,其实64位与32位大同小异,只是某些数据项的位数不同。
这是elf.h中给出的在Elf32_Ehdr的定义中用到的类型的由来:
typedef uint16_t Elf32_Half; 2字节
typedef uint32_t Elf32_Word; 4字节
typedef int32_t Elf32_Sword; 4字节
typedef uint32_t Elf32_Addr; 4字节
typedef uint32_t Elf32_Off; 4字节
可以看出来,Elf32_Ehdr的数据项都是基础类型。
嗨,如果你闲地没事,不妨将Elf32_Ehdr的各个项的位数相加,看是不是等于52呢?废话,当然等于!
我这里写了一个小程序,我们可以用它来显示ELF文件头的相关信息。
程序原理是这样的:
在main函数中,我先定义了两个重要变量。一个是FILE类型的指针fp,通过它我可以打开指定的文件,另一个是一个Elf32_Ehdr类型的变量elf_hdr。我用只读方式打开一个ELF文件,然后读取它的前52(sizeof(Elf32_Ehdr))个字节的数据给变量elf_hdr,好了,这样,我就可以这个对elf_hdr的各个字段进行分析来慢慢揭开ELF header的面纱。
附上程序原代码:
#include
#include
void func32(Elf32_Ehdr*);
int main(int argc,char *argv[])
{
char **p=argv;
FILE *fp;
Elf32_Ehdr elf_hdr;
int i=1,j;
printf("******************readelf*******************\n");
/*循环读命令行中给出的文件*/
while(ie_type==1)
printf("可从定位文件\n");
else if(p->e_type==2)
printf("可执行文件\n");
else if(p->e_type==3)
printf("动态连接文件\n");
if(p->e_machine==3)
printf("i386\n");
else if(p->e_machine==62)
printf("amd64\n");
printf("version:%d\n",p->e_version);
printf("entry:%x\n",p->e_entry);
printf("progrem header table:%x size:%x num:%x\nsection header table:%x size:%x num:%x\n",p->e_phoff,p->e_phentsize,p->e_phnum,p->e_shoff,p->e_shentsize,p->e_shnum);
printf("elf size:%x\n",p->e_ehsize);
printf("str dx:%x\n",p->e_shstrndx);
return;
}
编译方法:gcc -o readelfheader readelfheader.c
一个运行实例:
[leafteg@localhost elf]$ ./readelfheader hello
******************readelf*******************
this is file "hello"!
32位
可执行文件
i386
version:1
entry:8048380
progrem header table:34 size:20 num:7
section header table:c10 size:28 num:1c
elf size:34
str dx:19
the end!
[horok@localhost elf]$
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/104443/showart_2062832.html |
|