- 浏览: 86163 次
- 性别:
- 来自: 天津
最新评论
一、在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
- simple.7z (533 Bytes)
- 下载次数: 1
发表评论
-
lisp之函数基础
2011-09-08 13:38 782一、lisp函数的基本定义是如下这样的 span { fo ... -
lisp之函数基础
2011-09-08 13:37 967一、lisp函数的基本定义 ... -
c语言之可变参数
2011-04-22 14:29 2//arg.h #define ALIGN(n) ( ( ... -
ELF格式分析
2011-04-21 16:07 5一、概括 在linux系统下,c程序被编译成elf格式的目标 ... -
C语言解析
2011-04-18 11:33 7链接:巴克斯范式 理解extern ... -
ARM组成原理及编程模型
2011-04-15 16:42 3ARM组成原理及编程模型 -
windows系统基本原理总结
2011-04-14 16:43 2windows系统基本原理总结 -
嵌入式操作系统uItron全解析
2011-04-14 16:42 5嵌入式操作系统uItron全解析 -
80386保护模式编程模型
2011-04-14 15:25 2一、概述 所谓的保护模式就是在此模式下,CPU利用对虚拟 ... -
80386实模式编程模型
2011-04-14 09:42 5概括:当80386上电复位后,进入实模式状态,本文就介绍803 ... -
操作系统基本原理
2011-04-12 11:13 11操作系统基本原理 -
8086编程模型
2011-04-12 11:08 7概括:Intel的芯片具有良好的兼容性,8086和80386是 ... -
80x86组成原理总结
2011-04-12 11:00 6链接:补码的由来 概 ... -
总体框架
2011-04-12 10:59 3概括: 尽量没有废话,总结自己所学的知识。 知识框架 ... -
C++之函数的泛型编程
2011-04-06 09:36 76概括: 1、c++是一种多范式的编程语言,就和c语言兼容的面 ... -
linux0.11
2011-03-29 21:05 811linux0.11 -
补码的由来
2011-03-21 17:14 32很多教科书上只说补码是原码取反加1而没有进行详细的说明,只有从 ... -
计算机图形学
2011-03-20 14:08 1570计算机图形学 -
程序员的自我修养
2011-03-17 20:14 1270程序员的自我修养。 -
virtualbox安装文件
2011-03-13 12:37 844virtualbox
相关推荐
支持全部ELF类型解析。支持32位/64位elf文件自适应解析、可解析elf文件头、程序头、节头、字符表、符号表、...可以解析linux及大部分嵌入式的编译输出文件,如gcc、keil mdk、iar、ccs等编译器的输出文件格式均为ELF。
通过学习这份文档,读者可以掌握如何读取和解析ELF文件,理解动态链接机制,以及如何利用ELF格式进行程序调试和分析。 总之,对ELF文件格式有深入的理解对于系统级编程、逆向工程、软件调试以及优化都是至关重要的...
用来解析elf格式文件,如DSP/ccs的编译输出.out文件 或ARM/MDK编译的axf文件,使用mfc设计,使用虚拟列表完美提升工具性能
- **跨平台兼容性**:ELF格式支持多种不同的处理器架构,例如x86、ARM等,这使得基于ELF的应用程序可以在不同的平台上运行。 - **可扩展性**:ELF文件格式具有良好的扩展性,可以轻松添加新的特性而不影响现有系统的...
### ELF文件格式分析 #### 一、概述 ELF(Executable and Linkable Format)文件格式是一种广泛应用于UNIX类操作系统中的目标文件格式,旨在提供一种跨平台的二进制接口,以便于软件的编译、链接及执行。ELF格式...
通过深入学习`ELF文件格式分析.pdf`文档,并结合`readelf.c`源码,开发者可以更全面地理解ELF格式,这对于编写和调试涉及二进制文件处理的工具或程序大有裨益。同时,掌握ELF知识对于系统级编程和底层软件开发也是必...
ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码 ReadELF, ELF格式分析程序源码
elf格式解析工具用来解析elf格式文件,解析后可以得到ELF文件头信息,显示标识符、程序头表偏移、ELF头大小、节头大小、节头表偏移、程序头表大小、程序头表总数、硬件环境及特定处理器标志、入口函数及版本等信息。...
ELF格式被设计成高度可移植的,并且能够跨不同的操作系统和硬件平台使用。这种格式不仅用于存储可执行文件,也用于存储共享库和对象文件。通过使用ELF格式,开发者能够在不同的环境下重用代码,同时保持良好的性能和...
### ELF文件格式详解 #### 一、概述 ELF (Executable and Linkable Format) 文件格式是一种广泛应用于Unix和类Unix操作系统中的二进制文件格式,主要用于可执行文件、目标文件和共享库等类型的文件。本篇文章将...
ELF文件格式分析文档,北京大学信息科学技术学院操作系统实验室教学材料,滕启明编写
ELF(Executable and Linkable Format)文件格式是Unix和Unix-like系统(包括Linux)中常用的二进制文件格式,用于存储程序的代码和数据。ELF文件既可以用作可执行文件,也可以用作可重定位的目标文件(生成库文件)...
ELF格式的主要优势在于其良好的跨平台兼容性和强大的扩展能力,这使得它能够在多种不同的硬件平台上运行。 #### 二、ELF文件结构概览 ##### 1. 文件格式概述 ELF文件主要由以下几个部分组成: - **文件标识**:...
在计算机科学中,是一种用于二进制文件、可执行文件格式 ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中...