`
blue_halo
  • 浏览: 86615 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

ELF格式分析

F# 
阅读更多

一、在linux平台下,目标文件的格式是ELF,下面举例说明ELF文件的组成。

 

二、如下的程序被编译成附件的object文件,格式是ELF。

 

int printf(const char* format,...);  
  
int global_init_var=84;  
int global_uninit_var;  
  
void func1(int i)  
{  
    printf("%d\n",i);  
}  
  
int main(void)  
{  
    static int static_var=85;  
    static int static_var2;  
    int a=1;  
    int b;  
      
    func1(static_var+static_var2+a+b);  
    return a;  
} 

 

三、分析程序如下

 

//elf.h
typedef struct
{
	unsigned char e_ident[16];//0-3:魔数,4:1-小端模式,5:1-32位,6:版本号,7-15:保留
	unsigned short e_type;//1-object文件,2-可执行文件,3-动态链接文件
	unsigned short e_machine;//3-80386
	unsigned int e_version;	//版本号为1
	unsigned int e_entry;//可执行文件的入口虚拟地址,object文件为0
	unsigned int e_phoff;
	unsigned int e_shoff;//段表偏移,这个很重要,根据此值获得段表的首地址
	unsigned int e_flags;//一些标志位
	unsigned short e_ehsize;//此结构体的大小
	unsigned short e_phentsize;
	unsigned short e_phnum;
	unsigned short e_shentsize;
	unsigned short e_shnum;
	unsigned short e_shstrndx;
}Elf32_Ehdr;

typedef struct
{
	unsigned int sh_name;//段名在段名字符串表中的偏移
	unsigned int sh_type;
	//0-无效段,1-代码段、数据段,2-符号表,3-字符串表,4-重定位表,5-符号表的哈希表
	//6-动态链接信息,7-提示性信息,8-不占文件空间如bss段,9-重定位信息
	//10-保留,11-动态链接符号表
	unsigned int sh_flags;//1-表示该段在可写,2-表示该段需要分配空间,3-代码段,是位或的关系
	unsigned int sh_addr;//段虚拟地址
	unsigned int sh_offset;//段在文件中的偏移
	unsigned int sh_size;//段的长度
	unsigned int sh_link;//重定位表或者重定位信息的符号表描述符在段表中的下标
	unsigned int sh_info;//重定位表或者重定位信息所作用的段描述符在段表中的下标
	unsigned int sh_addralign;//段的对齐,2的指数
	unsigned int sh_entsize;//若段包含固定大小的项,此值为项的大小,否则为0
}Elf32_Shdr;

typedef struct
{
	unsigned int st_name;//符号名
	unsigned int st_value;//符号地址在段内偏移
	unsigned int st_size;//符号大小
	unsigned char st_info;//符号绑定信息,0-文件内部变量 1-全局符号 2-弱引用
	                      //符号类型,0-未知类型符号 1-数据对象 2-可执行代码 3-一个段 4-文件名  
	unsigned char st_other;//保留
	unsigned short st_shndx;//符号所在段 0xfff1-文件名常量 0xfff2-common块 0-表示未定义
}Elf32_Sym;

 

//readelf.c
#include <stdio.h>
#include <stdlib.h>
#include "elf.h"

FILE *elf;

Elf32_Ehdr elf_header;
Elf32_Shdr *sec_des;

char str_data[100]={0};//字符串表

void read_header()
{
	elf=fopen("d:/share/simple.o","rb");
	if(elf==NULL)
	{
		printf("fail to open the object file!\n");
	}
	else
	{
		fread(&elf_header,sizeof(elf_header),1,elf);
		printf("elf header information:\n");
		for(int i=0;i<16;i++)
		{
			printf("%x,",elf_header.e_ident[i]);
		}
		printf("\n");
/*
		printf("elf file type: %d\n",elf_header.e_type);
		printf("elf support machine: %d\n",elf_header.e_machine);
		printf("elf file entry: %d\n",elf_header.e_entry);
		printf("address of program headers: %d\n",elf_header.e_phoff);
		printf("address of section table: %d\n",elf_header.e_shoff);//段描述符表在elf文件中的偏移
		printf("elf file flags: %d\n",elf_header.e_flags);
		printf("size of elf header: %d\n",elf_header.e_ehsize);//Elf32_Ehdr的大小
		printf("size of program headers: %d\n",elf_header.e_phentsize);
		printf("number of programe headers: %d\n",elf_header.e_phnum);
		printf("size of section description: %d\n",elf_header.e_shentsize);//段描述符大小
		printf("number of section description: %d\n",elf_header.e_shnum);//段描述符数量即段的数量
		printf("section table string index: %d\n",elf_header.e_shstrndx);//段名字符串表在段表中的偏移
*/
	}
	//首先读文件头,根据段表偏移获取段表,然后根据段描述符的大小和数量获取每一个段的信息。
}

void read_data_sec(void);

void read_section(void)
{
	unsigned int des_sec_off=elf_header.e_shoff;
	unsigned int des_size=elf_header.e_shentsize;
	unsigned int des_num=elf_header.e_shnum;
	unsigned int sec_namestr_idx=elf_header.e_shstrndx;

	sec_des =(Elf32_Shdr*)malloc(des_size*des_num);
	fseek(elf,des_sec_off,SEEK_SET);
	fread(sec_des,des_size*des_num,1,elf);

	unsigned int sec_namestr_off=sec_des[sec_namestr_idx].sh_offset;
	unsigned int sec_namestr_size=sec_des[sec_namestr_idx].sh_size;
	unsigned char *sec_namestr;
	sec_namestr=(unsigned char*)malloc(sec_namestr_size);
	fseek(elf,sec_namestr_off,SEEK_SET);
	fread(sec_namestr,sec_namestr_size,1,elf);

	printf("This file has %d sections!\n",des_num);

/*
	for(unsigned int i=0;i<des_num;i++)
	{
		printf("Information of section %d:\n",i+1);
		printf("\tname: %s\n\ttype:%d\n\t",sec_namestr+sec_des[i].sh_name,sec_des[i].sh_type);
		printf("flags:%d\n\tvirtual address:0x%x\n\t",sec_des[i].sh_flags,sec_des[i].sh_addr);
		printf("file offset:%d\n\tsection size:%d\n",sec_des[i].sh_offset,sec_des[i].sh_size);
	}
*/
	read_data_sec();

	free(sec_des);
}

void read_rdata_sec(void);

void read_data_sec(void)
{
	int global_init[2]={};//对应全局初始化变量和静态初始化变量
	fseek(elf,132,SEEK_SET);
	fread(global_init,8,1,elf);
	printf("global_init var:%d,%d\n",global_init[0],global_init[1]);
	read_rdata_sec();
}

void read_comment_sec(void);

void read_rdata_sec(void)
{
	char rdata[10]={0};//const变量及字符串常量
	fseek(elf,140,SEEK_SET);
	fread(&rdata,4,1,elf);
	printf("rdata :%s\n",rdata);
	read_comment_sec();
}

void read_str_sec(void);

void read_comment_sec(void)
{
	char comm_data[30]={0};//编译器及操作系统版本号
	fseek(elf,144,SEEK_SET);
	fread(&comm_data,29,1,elf);
	printf("comment data :%s\n",comm_data+1);
	read_str_sec();
}

void read_symbol_sec(void);

void read_str_sec(void)
{
	fseek(elf,936,SEEK_SET);
	fread(&str_data,95,1,elf);
	printf("all string is here!\n");
	for(int i=0;i<95;i++)
	{
		if(str_data[i]==0)
		{
			printf("%s\n",&str_data[i]+1);
		}
	}

	read_symbol_sec();
}

Elf32_Sym sym[15]={0};

void read_symbol_sec(void)
{
	fseek(elf,696,SEEK_SET);
	fread(sym,240,1,elf);
	printf("symbol information:\n");
	for(int i=0;i<15;i++)
	{
		printf("symbol %d :\n",i+1);
		printf("\tname: %s\tvalue is %d\tsize is %d\n\t",str_data+sym[i].st_name,sym[i].st_value,sym[i].st_size);
		printf("type is %d\tsection is %d\n",sym[i].st_info,sym[i].st_shndx);
	}
}

int main(void)
{
	read_header();
	read_section();
	system("pause");
	return 0;
}

 

四、得到的结果如下:

 

elf header information:
7f,45,4c,46,1,1,1,0,0,0,0,0,0,0,0,0,
This file has 11 sections!
Information of section 1:
	name: 
	type:0
	flags:0
	virtual address:0x0
	file offset:0
	section size:0
Information of section 2:
	name: .text
	type:1
	flags:6
	virtual address:0x0
	file offset:52
	section size:80
Information of section 3:
	name: .rel.text
	type:9
	flags:0
	virtual address:0x0
	file offset:1032
	section size:40
Information of section 4:
	name: .data
	type:1
	flags:3
	virtual address:0x0
	file offset:132
	section size:8
Information of section 5:
	name: .bss
	type:8
	flags:3
	virtual address:0x0
	file offset:140
	section size:4
Information of section 6:
	name: .rodata
	type:1
	flags:2
	virtual address:0x0
	file offset:140
	section size:4
Information of section 7:
	name: .comment
	type:1
	flags:48
	virtual address:0x0
	file offset:144
	section size:29
Information of section 8:
	name: .note.GNU-stack
	type:1
	flags:0
	virtual address:0x0
	file offset:173
	section size:0
Information of section 9:
	name: .shstrtab
	type:3
	flags:0
	virtual address:0x0
	file offset:173
	section size:81
Information of section 10:
	name: .symtab
	type:2
	flags:0
	virtual address:0x0
	file offset:696
	section size:240
Information of section 11:
	name: .strtab
	type:3
	flags:0
	virtual address:0x0
	file offset:936
	section size:95
 
elf header information:
7f,45,4c,46,1,1,1,0,0,0,0,0,0,0,0,0,
This file has 11 sections!
global_init var:84,85
rdata :%d

comment data :GCC: (Debian 4.4.5-8) 4.4.5
all string is here!
simple.c
static_var.1255
static_var2.1256
global_init_var
global_uninit_var
func1
printf
main

symbol information:
symbol 1 :
	name: 		value is 0	size is 0
	type is 0	section is 0
symbol 2 :
	name: simple.c	value is 0	size is 0
	type is 4	section is 65521
symbol 3 :
	name: 		value is 0	size is 0 //type 是3的name就是段名
	type is 3	section is 1
symbol 4 :
	name: 		value is 0	size is 0
	type is 3	section is 3
symbol 5 :
	name: 		value is 0	size is 0
	type is 3	section is 4
symbol 6 :
	name: 		value is 0	size is 0
	type is 3	section is 5
symbol 7 :
	name: static_var.1255	value is 4	size is 4
	type is 1	section is 3
symbol 8 :
	name: static_var2.1256	value is 0	size is 4
	type is 1	section is 4
symbol 9 :
	name: 		value is 0	size is 0
	type is 3	section is 7
symbol 10 :
	name: 		value is 0	size is 0
	type is 3	section is 6
symbol 11 :
	name: global_init_var	value is 0	size is 4
	type is 17	section is 3
symbol 12 :
	name: global_uninit_var	value is 4	size is 4
	type is 17	section is 65522
symbol 13 :
	name: func1	value is 0	size is 27
	type is 18	section is 1
symbol 14 :
	name: printf	value is 0	size is 0
	type is 16	section is 0
symbol 15 :
	name: main	value is 27	size is 53
	type is 18	section is 1
1
1
分享到:
评论

相关推荐

    ELF解析工具 v1.7(elf格式解析工具)

    支持全部ELF类型解析。支持32位/64位elf文件自适应解析、可解析elf文件头、程序头、节头、字符表、符号表、...可以解析linux及大部分嵌入式的编译输出文件,如gcc、keil mdk、iar、ccs等编译器的输出文件格式均为ELF。

    ELF 文件格式分析(北京大学实验室出的标准版)

    通过学习这份文档,读者可以掌握如何读取和解析ELF文件,理解动态链接机制,以及如何利用ELF格式进行程序调试和分析。 总之,对ELF文件格式有深入的理解对于系统级编程、逆向工程、软件调试以及优化都是至关重要的...

    elf格式解析工具

    用来解析elf格式文件,如DSP/ccs的编译输出.out文件 或ARM/MDK编译的axf文件,使用mfc设计,使用虚拟列表完美提升工具性能

    ELF文件格式规范1.2

    - **跨平台兼容性**:ELF格式支持多种不同的处理器架构,例如x86、ARM等,这使得基于ELF的应用程序可以在不同的平台上运行。 - **可扩展性**:ELF文件格式具有良好的扩展性,可以轻松添加新的特性而不影响现有系统的...

    ELF文件格式分析

    ### ELF文件格式分析 #### 一、概述 ELF(Executable and Linkable Format)文件格式是一种广泛应用于UNIX类操作系统中的目标文件格式,旨在提供一种跨平台的二进制接口,以便于软件的编译、链接及执行。ELF格式...

    《ELF文件格式分析.pdf》与elf解析代码

    通过深入学习`ELF文件格式分析.pdf`文档,并结合`readelf.c`源码,开发者可以更全面地理解ELF格式,这对于编写和调试涉及二进制文件处理的工具或程序大有裨益。同时,掌握ELF知识对于系统级编程和底层软件开发也是必...

    ReadELF, ELF格式分析程序源码

    ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码

    elf格式解析工具V1.0免安装版.rar

    elf格式解析工具用来解析elf格式文件,解析后可以得到ELF文件头信息,显示标识符、程序头表偏移、ELF头大小、节头大小、节头表偏移、程序头表大小、程序头表总数、硬件环境及特定处理器标志、入口函数及版本等信息。...

    ELF文件格式详细分析

    ELF格式被设计成高度可移植的,并且能够跨不同的操作系统和硬件平台使用。这种格式不仅用于存储可执行文件,也用于存储共享库和对象文件。通过使用ELF格式,开发者能够在不同的环境下重用代码,同时保持良好的性能和...

    ELF文件格式详解,包括详细的分析

    ### ELF文件格式详解 #### 一、概述 ELF (Executable and Linkable Format) 文件格式是一种广泛应用于Unix和类Unix操作系统中的二进制文件格式,主要用于可执行文件、目标文件和共享库等类型的文件。本篇文章将...

    ELF文件格式分析.pdf

    ELF文件格式分析文档,北京大学信息科学技术学院操作系统实验室教学材料,滕启明编写

    ELF文件格式详解

    ELF(Executable and Linkable Format)文件格式是Unix和Unix-like系统(包括Linux)中常用的二进制文件格式,用于存储程序的代码和数据。ELF文件既可以用作可执行文件,也可以用作可重定位的目标文件(生成库文件)...

    ELF文件格式详解(中文)

    ELF格式的主要优势在于其良好的跨平台兼容性和强大的扩展能力,这使得它能够在多种不同的硬件平台上运行。 #### 二、ELF文件结构概览 ##### 1. 文件格式概述 ELF文件主要由以下几个部分组成: - **文件标识**:...

    ELF 文件解析工具1.7

    在计算机科学中,是一种用于二进制文件、可执行文件格式 ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中...

Global site tag (gtag.js) - Google Analytics