免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1508 | 回复: 0
打印 上一主题 下一主题

ELF文件头(ELF header )分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-30 02:15 |只看该作者 |倒序浏览

                                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
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP