当前位置:文档之家› elf详解

elf详解

elf详解
elf详解

ARM-ELF文件格式与GNU ARM Linker机制

作者:admin 日期:2008-10-13

字体大小: 小中大

里面除了二进制的机器代码,还有一些可用于进行重定位的信息。它主要是作为LINKER(ld)的输入,LINKER将跟据这些信息,将需要重定位的符号重定位,进而产生可执行的OBJECT 文件。ELF格式的可重定位OBJECT文件由header与section 组成。

Header 包括ELF header 与 section header. ELF header 位于文件的头部,用于存储目标机器的架构,大小端配置,ELF header 大小,object文件类型,section header 在文件中的偏移,section header 的大小,section header 中的项目数等信息。Section header 则定义了文件中每个section 的类型,位置,大小等信息。Linker就是通过查找ELF header,找到

section header 的入口,再在section header 中找到相应的section 入口,进而定位到目标section 的。

Section 包括

.text :经过编译的机器代码。

.rodata :只读的数据,例如printf(“hello!”)中的字符串hello。.data :已初始化的全局变量,局部变量将在运行时被存放在堆栈中,不会在.data或 .bss段中出现。

.bss :未初始化的全局变量,在这里只是一个占位符,在object 文件中并没有实际的存储空间。

.symtab :符号表,用于存放程序中被定义的或被引用到的全局变量和函数的信息。

.rel.text :一个保存着一系列在.text中的位置的列表。这些位置将在linker把这个文件与其它object文件合并时被修改,一般来说,这些位置都是保存着一些引用到全局变量或者外部函数的指令。引用局部变量或者本地函数的指令是不需要被修改的,因为局部变量和本地函数的地址一般都是使用PC相对偏移地址的。需要注意的是,这个section 和下面的.rel.data在运行时并不需要,生成可执行的ELF object文件时会去掉这个section。.rel.data :保存全局变量的重定位信息。一般来说,如果一个全局变量它的初始化值是另一个全局变量的地址,或者是外部函数的地址,那么它就需要被重定位。

.debug :保存debug信息。

.strtab :一个字符串表,保存着.symtab和.debug ,和各个section的名字。.symtab,.debug 和section table里面,凡是保存name的域,其实都是保存了一个偏移值,通过这个偏移值在这个字符串表里面可以找到相应得字符串。

下面仔细讨论一下.symtab:

每一个可重定位的object文件,都会有一个.symtab。这个符号表保存了在这个object文件中所有被定义的和被引用的符号。当源程序是C 语言程序时,.symtab 中的符号直接来源于C编译器(cc1)。这里所说的符号主要有三种:

1) 在这个object文件中被定义的可以被其他object文件全局符号。在C语言源程序中,主要就是那些非静态(没有static 修饰

的)的全局变量和非静态的函数。在ARM汇编语言中,就是那些被EXPORT 指令导出的变量。

2) 在这个object文件中引用到,但是在其他文件中定义的全局变量。在ARM汇编语言中就是通过IMPORT命令引入的变量3) 本地变量。本地变量只在本object文件内可见。这里的本地变量指的是连接器本地变量,应该和一般的程序本地变量作区别。这里所指的本地变量,包括用static 修饰的全局变量,object 文件中section名称,源代码文件名称。一般意义上的本地变量,是在运行时由系统的运行时环境管理的,linker并不关心。

每个符合上面条件的符号在.symtab文件中都会有一个数据项。这个数据项的数据结构是:

Typedef struct{

int name;//符号名称,其实就是.strtab的偏移值

int value;//在section中的位置,以相对section地址的偏移表示

int size;//大小

char type;//类型,一般是数据或函数

char binding;//是本地变量还是全局变量

char reserved;//保留的位

char section;//符号所属的section。可选有:.text(用数字1代表),.data(用数

//3代表),ABS(不应被重定位的符号),UND (在本object文件

//中未定义的符号,可能在别的文件中定义),COM(一般的未初//始化的变量符号)。

}ELF_sym

现在假设组成应用的各个模块都已经被汇编,构建出了可重定位的object文件。这些object的结构都是一样的,有各自

的.text, .data section, 有各自的.symtab. GCC下一步要做的就是使用linker (ld),把这些object文件,加上必要的库连接成具有绝对运行时地址的可执行文件,就是可执行的ELF格式的文件。 Linker 的连接动作可以分为两部分:

1) 符号解析。确定引用符号的指向。

2) 符号重定位。合并section, 分配运行时环境地址,引用符号重定位。

符号解析:

在一个object文件中,有指令定义了符号,也有指令引用了符号。可能存在这样一种情况,一个被引用到的符号,有多重的定义。符号解析的作用就是确定,在这个object文件中,一个符号引用真正引用的是哪个符号。

在编译的时候,除了在本文件中定义的全局变量会由编译器生成一个符号表项之外,当发现一个被引用到的符号在本文件中并

没有被定义,编译器也会自动产生一个符号表项,把确定这些引用的工作留给linker。汇编器在汇编时将读取这些符号表项,生成.symtab。在读取的过程中,如果发现有在无法确定的符号引用项,汇编器会为这些符号额外生成一个数据项,称作重定位数据项,存放于rel.text或rel.data section中,交由linker确定。下面是重定位数据项(relocation entry)的数据结构:

Typedef struct{

int offset;//指明需要被重定位的引用在object中的偏移,实际上就是需要被重定位的引用

//在object中的实际位置

int symbol;//这个被重定位的引用真实指向的符号

int type;//重定位类型:R_ARM_PC24:使用24bit的PC相对地址重定位引用

//R_ARM_ABS32:使用32bit绝对地址重定位引用

}Elf32_Rel

Linker 需要解析的,就是那些被生成了重定位数据项的引用。Linker将根据C语言定义的规则,对于每一个重定位数据项,在输入的各个object文件中查找适合的符号,把这个符号填入symbol项中。但是由于还不知道这个符号的真实地址,所以现在就算知道了引用的真实指向,但我们还是不能确定这个引用指

向的地址。

符号重定位:

符号重定位用来解决上面的问题。Linker首先进行section 的合并。Linker合并object文件的过程很简单,一般就是相同属性的section合并,例如不同object文件的.text section 将被合并成一个.text。同样,.symtab section也被合并成一个.symtab。这里面涉及到两个问题:

1) 各个object文件合并的顺序。这个问题涉及到最终指令和符号的运行地址。最为重要的是,究竟是哪个section排在最前头?在ARM RAW 系统得开发过程中,这个最为重要。ARM系统CPU上电后,系统会自动的从0x00000000地址取指令并执行,这个地址上映射着存储器。这个动作是不可编程的。所以排在最前面的section一定要包含有程序的入口点,否则系统无法正常运行。

2) 输入段与输出端之间的对应关系。理论上,任何section,都可以被随意的映射到一个输出段中。一个.data section是可以与一个.text section 组成输出一个.text的。当然这样的动作毫无意义。我们必须告诉linker使用那些section作为输入,产生一个输出section.

以上这两个问题,都是通过一个称为连接脚本的文件控制的。Linker通过读取连接脚本,来决定section 从输入到输出的映射,设置程序的入口点,设置哪个section应该在整个可执行文件的

头部等问题。

连接脚本还有另外一个作用,那就是指定每个section的地址。在section 合并完成后,linker将跟据.symtab,对符号进行统一的编址,分配一个绝对的运行时地址。这个地址是以section地址作为基地址的。假设.text section的地址是0x00000000,那么.text里面的符号将以0x00000000这个地址作为基准地址。指定section地址的工作也是由连接脚本完成。在嵌入式开发中常见的在编译工程时需指定的text_base, data_base等参数,最后会被加入到连接脚本中,从而完成section的地址分配。

以上两步完成后,linker 执行引用符号重定位操作。Linker遍历.rel section (包括.rel text 和 .rel data),对于其中的每个数据项,根据symbol域到.symtab 中查出相应的引用的真实地址(经过上面的地址分配,现在.symtab里面的符号都具有绝对的运行地址),再根据offset域提供的偏移,将这个地址填入相应的位置上。

至此,符号重定位工作全部完成。Linker删除用于保存重定位信息的rel.text和rel.data section,加入一个segment header

和一个.init section。生成可执行的ELF格式的object文件。 Segment header保存了用于操作系统内存映射的信

息。.init section 包含了一个_init 的函数。程序加载时,操作系统的程序加载器通过读取segment header,将程序加载到用户内存空间,并根据segment header里面映射信息,分别将.text 段

和.data段映射到适当的地址上。然后再调用.init中的_init函数,完成初始化工作。

由于ELF文件具有通用性强的优点,现在流行的开发模式是,先通过编译工具生成ELF文件格式的可执行文件,在使用外部工具,抽离出ELF文件中的相应部分,生成BIN文件。例如著名的GNU bootloader U-Boot,就采用了这种做法,编译器工具集是GCC,BIN生成工具是elf2bin。ARM公司著名的开发环境ADS,虽然使用的是自家的armcc,和armcpp编译器,但他们的工作方式却是与GNU GCC如出一辙。

[本日志由admin 于2008-10-14 06:48 PM 编辑]

elf文件格式

第1章文件格式 1.1 Executable and Linking Format (ELF) 1.1.1整体结构 ELF对象格式用于目标文件(.o扩展名)和执行文件. 有些信息只出现在目标文件或执行文件中. ELF文件由下列部件构成. ELF header必须放在文件的开始;其他部件可以随便排放(ELF header给出了其他部件的偏移量). 1.1.2ELF头[ELF Header] ELF头包含目标文件的一般信息;具有如下结构(from elf.h): #define EI_NIDENT 16 typedef struct { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; }; ELF头域描述:

1.1.3程序头[Program Header] 程序头为一结构数组,每个元素描述执行文件的一个可载入段. 元素结构如下(from elf.h): typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr;

pe文件格式

PE文件格式详解(一)――基础知识 什么是PE文件格式: 我们知道所有文件都是一些连续(当然实际存储在磁盘上的时候不一定是连续的)的数据组织起来的,不同类型的文件肯定组织形式也各不相同;PE文件格式便是一种文件组织形式,它是32位Wind ow系统中的可执行文件EXE以及动态连接库文件DLL的组织形式。为什么我们双击一个EXE文件之后它就会被Window运行,而我们双击一个DOC文件就会被Word打开并显示其中的内容;这说明文件中肯定除了存在那些文件的主体内容(比如EXE文件中的代码,数据等,DOC文件中的文件内容等)之外还存在其他一些重要的信息。这些信息是给文件的使用者看的,比如说EXE文件的使用者就是Window,而DOC文件的使用者就是Word。Window可以根据这些信息知道把文件加载到地址空间的那个位置,知道从哪个地址开始执行;加载到内存后如何修正一些指令中的地址等等。那么PE文件中的这些重要信息都是由谁加入的呢?是由编译器和连接器完成的,针对不同的编译器和连接器通常会提供不同的选项让我们在编译和 联结生成PE文件的时候对其中的那些Window需要的信息进行设定;当然也可以按照默认的方式编译连接生成Window中默认的信息。例如:WindowNT默认的程序加载基址是0x40000;你可以在用VC连接生成EXE文件的时候使用选项更改这个地址值。在不同的操作系统中可执行文件的格式是不同的,比如在Linux上就有一种流行的ELF格式;当然它是由在Linux上的编译器和连接器生成的,

所以编译器、连接器是针对不同的CPU架构和不同的操作系统而涉及出来的。在嵌入式领域中我们经常提到交叉编译器一词,它的作用就是在一种平台下编译出能在另一个平台下运行的程序;例如,我们可以使用交叉编译器在跑Linux的X86机器上编译出能在Arm上运行的程序。 程序是如何运行起来的: 一个程序从编写出来到运行一共需要那些工具,他们都对程序作了些什么呢?里面都涉及哪些知识需要学习呢?先说工具:编辑器-》编译器-》连接器-》加载器;首先我们使用编辑器编辑源文件;然后使用编译器编译程目标文件OBJ,这里面涉及到编译原理的知识;连接器把OBJ文件和其他一些库文件和资源文件连接起来生成EXE文件,这里面涉及到不同的连接器的知识,连接器根据OS的需要生成EXE文件保存着磁盘上;当我们运行EXE文件的时候有W indow的加载器负责把EXE文件加载到线性地址空间,加载的时候便是根据上一节中说到的PE文件格式中的哪些重要信息。然后生成一个进程,如果进程中涉及到多个线程还要生成一个主线程;此后进程便开始运行;这里面涉及的东西很多,包括:PE文件格式的内容;内存管理(CPU内存管理的硬件环境以及在此基础上的OS内存管理方式);模块,进程,线程的知识;只有把这些都弄清楚之后才能比较清楚的了解这整个过程。下面就让我们先来学习PE文件格式吧。

ARM平台下ELF文件反汇编

ARM平台下的反汇编 目的 作为代码插桩过程的前提,首先需要对于所提供的二进制代码进行必要的分析,了解ELF文件的结构以及ARM平台的指令编码,将二进制01码翻译成为用户可读的汇编代码。通过对于汇编代码的分析,用户可以得到程序应用中各个函数起始地址以及程序各个模块的流程调用等重要信息,为代码插桩提供详细的数据。经过插桩的代码最后通过再一次汇编的过程输出到目标文件。因此,正确、快速地进行平台下的反汇编工作显得十分关键。 ARM平台介绍[1-2] ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,设计了大量高性能、廉价、耗能低的RISC(精简指令集计算机)处理器、相关技术及软件。技术具有性能高、成本低和能耗低等特点。经历过早期自己设计和制造芯片的不景气之后,公司自己开始不制造芯片,只将芯片的设计方案授权(licensing)给其他公司,由它们来生产,形成了较为独特的盈利模式。RISC结构优先选取使用频率最高的简单指令,避免复杂指令;将指令长度固定,指令格式和寻地方式种类减少;以控制逻辑为主,不用或少用微码控制等。ARM处理器在秉承RISC体系优点的基础上,进行了针对嵌入式系统的功能扩展,使得指令更加灵活,处理器性能在嵌入式平台上更加突出。 ARM微处理器的核心结构如下图所示: Figure 1.ARM处理器核心结构示意图[2] 数据指令通过数据总线进入到处理器核心,然后在指令被执行之前经由指令解码器翻译。和所有精简指令集处理器一样,ARM采用了load-store架构,load指令将数据从内存拷贝到寄存器,store指令将数据从寄存器转储到内存,所有的数据处理在寄存器中完成。 ARM处理器是32位的处理器,所有的指令默认将寄存器视为32位的值,因此Sign extend会在数据写入寄存器之前将所有8位或者12位的数值转换为32位的数值。ARM指令通常有两个源寄存器: Rn, Rm 以及一个目标寄存器,操作数都是从寄存器通过内部总线读取得到。 核心的ALU (arithmetic logic unit) or MAC (multiply-accumulate unit) 从内部总线A,B上取得操作数进行运算,然后将结果写入目标寄存器。 ARM处理器一个很大的特色是寄存器Rm可以选择性地在进入ALU运算之前在barrel shifter中进

ELF文件结构描述

ELF文件结构描述 3.4 ELF文件结构描述 我们已经通过SimpleSection.o的结构大致了解了ELF文件的轮廓,接着就来看看ELF 文件的结构格式。图3-4描述的是ELF目标文件的总体结构,我们省去了ELF一些繁琐的结构,把最重要的结构提取出来,形成了如图3-4所示的ELF文件基本结构图,随着我们讨论的展开,ELF文件结构会在这个基本结构之上慢慢变得复杂起来。 ELF目标文件格式的最前部是ELF文件头(ELF Header),它包含了描述整个文件的基本属性,比如ELF文件版本、目标机器型号、程序入口地址等。紧接着是ELF文件各个段。其中ELF文件中与段有关的重要结构就是段表(Section Header Table),该表描述了ELF文件包含的所有段的信息,比如每个段的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。接着将详细分析ELF文件头、段表等ELF关键的结构。另外还会介绍一些ELF中辅助的结构,比如字符串表、符号表等,这些结构我们在本节只是简单介绍一下,到相关章节中再详细展开。 3.4.1 文件头 我们可以用readelf命令来详细查看ELF文件,代码如清单3-2所示。

ELF文件头结构及相关常数被定义在“/usr/include/elf.h”里,因为ELF文件在各种平台下都通用,ELF文件有32位版本和64位版本。它的文件头结构也有这两种版本,分别叫做“Elf32_Ehdr”和“Elf64_Ehdr”。32位版本与64位版本的ELF文件的文件头内容是一样的,只不过有些成员的大小不一样。为了对每个成员的大小做出明确的规定以便于在不同的编译环境下都拥有相同的字段长度,“elf.h”使用typedef定义了一套自己的变量体系,如表3-3所示。 我们这里以32位版本的文件头结构“Elf32_Ehdr”作为例子来描述,它的定义如下:

elf详解

ARM-ELF文件格式与GNU ARM Linker机制 作者:admin 日期:2008-10-13 字体大小: 小中大

里面除了二进制的机器代码,还有一些可用于进行重定位的信息。它主要是作为LINKER(ld)的输入,LINKER将跟据这些信息,将需要重定位的符号重定位,进而产生可执行的OBJECT 文件。ELF格式的可重定位OBJECT文件由header与section 组成。 Header 包括ELF header 与 section header. ELF header 位于文件的头部,用于存储目标机器的架构,大小端配置,ELF header 大小,object文件类型,section header 在文件中的偏移,section header 的大小,section header 中的项目数等信息。Section header 则定义了文件中每个section 的类型,位置,大小等信息。Linker就是通过查找ELF header,找到 section header 的入口,再在section header 中找到相应的section 入口,进而定位到目标section 的。 Section 包括 .text :经过编译的机器代码。 .rodata :只读的数据,例如printf(“hello!”)中的字符串hello。.data :已初始化的全局变量,局部变量将在运行时被存放在堆栈中,不会在.data或 .bss段中出现。 .bss :未初始化的全局变量,在这里只是一个占位符,在object 文件中并没有实际的存储空间。 .symtab :符号表,用于存放程序中被定义的或被引用到的全局变量和函数的信息。

elf文件资料格式(中文版)

3. 页标题的容和文章的页脚已经在开始的时候被换掉了。 4. 文章的排版也已经修正过了。 5. 如果必要,不同的字体已经被忽略了。大部分地方,这片文档能让你 充分的理解。然而,很小的地方,原始的文档使用了斜体字来指出文 章中的字符变量。在那种情况下,本文使用<尖括号>。在原始的文档 中没有出现尖括号。 6. 原始的文档有三个错误,如果你是不经意读它的话,是不会明显 就能找出的。但是在这里,明确的被鉴别出来了。 我很冒昧的纠正了那些错误。在他们的位置用一个{*}做上了标记。 可能还有其他我没有看出来的的错误。 如果有如何其他的区别都是我的责任。这样的错误请 mailto:breadboxmuppetlabs.. Brian Raiter [Last edited Fri Jul 23 1999] ________________________________________________________________ EXECUTABLE AND LINKABLE FORMAT (ELF) Portable Formats Specification, Version 1.1 Tool Interface Standards (TIS) ________________________________________________________________ =========================== Contents 容=========================== 序言 1. OBJECT文件 导言 ELF头(ELF Header) Sections String表(String Table) Symbol表(Symbol Table) 重定位(Relocation) 2. 程序装载与动态连接 导言 Program头(Program Header)

关于ELF文件格式

现代Linux采用ELF(Executable and Linking Format)做为其可连接和可执行文件的格式,因此ELF格式也向我们透出了一点Linux核内的情景,就像戏台维幕留下的一条未拉严的缝。 PC世界32仍是主流,但64位的脚步却已如此的逼近。如果你对Windows比较熟悉,本文还将时时把你带回到PE中,在它们的相似之处稍做比较。ELF文件以“ELF 头”开始,后面可选择的跟随着程序头和节头。地理学用等高线与等温线分别展示同一地区的地势和气候,程序头和节头则分别从加载与连接角度来描述EFL文件的组织方式。 ELF头 ------------------------------------------------ ELF头也叫ELF文件头,它位于文件中最开始的地方。 /usr/src/linux/include/linux/elf.h typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; /* Entry point */ Elf32_Off e_phoff;

Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; #define EI_NIDENT 16 ELF头中每个字段的含意如下: Elf32_Ehdr->e_ident[] (Magic) 这个字段是ELF头结构中的第一个字段,在elf.h中EI_NIDENT被定义为16,因此它占用16个字节。e_ident的前四个字节顺次应该是0x7f、 0x45、 0x4c、 0x46,也就是"\177ELF"。这是ELF文件的标志,任何一个ELF文件这四个字节都完全相同。 16进制 8进制字母 0x7f 0177 0x45 E 0x4c L

嵌入式bin文件和elf文件重点

嵌入式bin文件和elf文件重点 文件格式 (1)BIN文件:binary文件,即二进制文件。 (2)HEX文件:hex的全称是Intel HEX,此类文件通常用于传输将被存于ROM或者EPROM 中的程序和数据。是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。大多数EPROM编程器或模拟器使用Intel HEX文件。HEX文件记录由对应机器语言码和/或常量数据的十六进制编码数字组成。 (3)ELF文件:是Linux的主要可执行文件格式。ELF文件除了机器码外,还包含其它额外的信息,如段的加载地址,运行地址,重定位表,符号表等。 (4)bin文件和elf文件重点摘要: 执行raw binary很简单,只需要将程序加载到其起始地址,就可以执行; 执行ELF程序则需要一个ELF Loader。现在知道了吧,uboot和Linux kernel启动的时候是没有ELF Loader 的,所以烧在flash上的文件只能是raw binary格式的,即镜像文件image。 a)通过gcc编译出来的是elf文件 b)通过objcpy可以把elf文件转换为bin文件 (5)LDS文件:它定义了整个程序编译之后的连接过程,决定了一个可执行程序的各个段的存储位置。指定连接文件的存储地址、运行地址,存储地址和运行地址可以相同也可以不同。转自:https://wenku.baidu/view/9a8beb125f0e7cd18425369al (6)map文件:map文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,是整个程序工程信息的静态文本,通常由linker生成。map文件保存整个工程的静态文本信息,里面有所有函数的入口地址。 通过查看map文件,我们可以找到代码段(.text),全局未初始化区(.bss),数据段(.data)。map文件的作用是,我们可以根据程序产生错误地址在map文件中找到相应的函数、变量地址。 (7)symbol文件:目标文件的值、类型、名字,例如:00000024 T cleanup_before_linux

目标文件格式分析工具-ar-nm等等

目标文件格式分析工具: ar,nm,objdump,objcopy,readelf 如果普通编程不需要了解这些东西,如果想精确控制你的目标文件的格式或者你想查看一下文件里的内容以便作出某种判断,那么你可以看一下下面的工具:ar,nm,objdump,objcopy。具体用法请参考man在线手册。 ar基本用法 ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。 下面是ar命令的格式: ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files... 例如我们可以用ar rv libtest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。选项前可以有‘-'字符,也可以没有。下面我们来看看命令的操作选项和任选项。现在我们把{dmpqrtx}部分称为操作选项,而[abcfilNoPsSuvV]部分称为任选项。 {dmpqrtx}中的操作选项在命令中只能并且必须使用其中一个,它们的含义如下: ?d:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v 则列出被删除的每个模块。 ?m:该操作是在一个库中移动成员。当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。如果没有指定任选项,任何指定的成员将移到库的最后。也可以使用'a','b',或'I'任选项移动到指定的位置。 ?p:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。 ?q:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。'a','b',或'I'任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。 这时,库的符号表没有更新,可以用'ar s'或ranlib来更新库的符号表索引。 ?r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。 如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。 ?t:显示库的模块表清单。一般只显示模块名。 ?x:从库中提取一个成员。如果不指定要提取的模块,则提取库中所有的模块。 下面在看看可与操作选项结合使用的任选项: ?a:在库的一个已经存在的成员后面增加一个新的文件。如果使用任选项a,则应该为命令行中membername参数指定一个已经存在的成员名。

计算机操作系统实验_解析ELF文件

西北工业大学操作系统实验实验报告 一、实验目的 熟悉可执行链接文件(ELF)的结构,了解GeekOS将ELF格式的可执行程序加载到内存,建立内核线程并运行的实现技术。 二、实验要求 1.修改Project1项目中的/GeekOS/elf.c文件:在函数Parse_ELF_Executable()中添加代码,分析ELF格式的可执行文件(包括分析得出ELF文件头、程序头),获取可执行文件长度、代码段、数据段等信息,并打印输出。并且,填充Exe_Format 数据结构中的值域。 2.掌握GeekOS在核心态运行可执行程序的原理,绘制出可执行程序在内核中加载、运行的流程图(需反映关键函数的调用关系)。 3.回答实验讲义P125页的思考题。 三、实验过程及结果 1、修改Project1项目中的/GeekOS/elf.c文件:在函数Parse_ELF_Executable()中添加代码,分析ELF格式的可执行文件(包括分析得出ELF文件头、程序头),获取可执行文件长度、代码段、数据段等信息,并打印输出。并且,填充Exe_Format 数据结构中的值域。 答:修改Project1项目中的/GeekOS/elf.c文件:在函数Parse_ELF_Executable()中添加代码,如下: ==============elf.c=================== int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat) { int i; elfHeader *head=(elfHeader*)exeFileData; programHeader *proHeader=(programHeader *)(exeFileData+head->phoff); KASSERT(exeFileData!=NULL); KASSERT(exeFileLength>head->ehsize+head->phentsize*head->phnum); KASSERT(head->entry%4==0); exeFormat->numSegments=head->phnum;

ELF文件的加载和动态链接过程

ELF 文件的加载和动态链接过程 本文的目的:大家对于Hello World 程序应该非常熟悉,随便使用哪一种语言,即使还不熟悉的语言,写出一个Hello World 程序应该毫不费力,但是如果让大家详细的说明这个程序加载和链接的过程,以及后续的符号动态解析过程,可能还会有点困难。本文就是以一个最基本的C 语言版本Hello World 程序为基础,了解Linux 下ELF 文件的格式,分析并验证ELF 文件和加载和动态链接的具有实现。 本文的实验平台: Ubuntu 7.04 Linux kernel 2.6.20 gcc 4.1.2 glibc 2.5 gdb 6.6 objdump/readelf 2.17.50 本文的组织: 第一部分大致描述ELF 文件的格式; 第二部分分析ELF 文件在内核空间的加载过程; 第三部分分析ELF 文件在运行过程中符号的动态解析过程; (以上各部分都是以Hello World 程序为例说明) 第四部分简要总结; 第五部分阐明需要深入了解的东西。 一、 ELF 文件格式 1. 概述 Executable and Linking Format(ELF)文件是x86 Linux 系统下的一种常用目标文件(object file)格式,有三种主要类型: 1) 适于连接的可重定位文件(relocatable file),可与其它目标文件一起创建可执行文件 和共享目标文件。 2) 适于执行的可执行文件(executable file),用于提供程序的进程映像,加载的内存执 行。 3) 共享目标文件(shared object file),连接器可将它与其它可重定位文件和共享目标文 件连接成其它的目标文件, 动态连接器又可将它与可执行文件和其它共享目标文件

ELF格式-中文

________________________________________________________________ EXECUTABLE AND LINKABLE FORMAT (ELF) Portable Formats Specification, Version 1.1 Tool Interface Standards (TIS) ________________________________________________________________ =========================== Contents 内容=========================== 序言 1. OBJECT文件 导言 ELF头(ELF Header) Sections String表(String Table) Symbol表(Symbol Table) 重定位(Relocation) 2. 程序装载与动态连接 导言 Program头(Program Header) Program装载(Program Loading) Dynamic连接(Dynamic Linking) 3. C LIBRARY C Library ________________________________________________________________ 导言 ________________________________________________________________ ELF: 可执行连接格式 可执行连接格式是UNIX系统实验室(USL)作为应用程序二进制接口 (Application Binary Interface(ABI)而开发和发布的。工具接口标准委 员会(TIS)选择了正在发展中的ELF标准作为工作在32位INTEL体系上不同操 作系统之间可移植的二进制文件格式。

Linux ELF 运行时内存详解 - 黑客防线官方站

Linux ELF 运行时内存详解 4/22/2012 前一段时间做ROP (return-oriented programming )的东西,想要系统的了解Linux 中程序的内存格式(memory layout ),网上有很多文章,却没有一个深入完整的介绍。所以花了些时间做深入的了解,不放过一个细节。由于最初写的是英文文档,所以文中的图都是用英文标识的,不过应该不影响阅读。 本文详细解释了Linux ELF 文件的虚拟地址空间。另外本文也大概介绍了ASLR (Address Space Layout Randomization)技术对ELF 虚拟地址空间的影响。作者的测试系统是Linux Ubuntu 2.6.32-24和Vmware Workstation 7。另外所有的分析都基于Intel x86架构。 虚拟地址空间 当代的操作系统中每个进程都有自己的独立虚拟地址空间。在32位系统上,该虚拟地址空间有4G 大小。为了将虚拟地址转换为物理地址,Linux 内核使用了一个两级(事实上是三级,但是中间一级没有任何实质操作)分页机制,即页目录表和页表。分页机制与MMU (Memory Management Unit )合作将虚拟地址转换为物理地址。当操作系统引入虚拟地址后,所有的用户操作系统和内核线程(事实上Linux 只有进程概念而没有线程概念,Linux 通过页表机制来模拟实现内核线程)都将运行于虚拟地址模式。 另外Linux (以及Windows )使用了CPU 提供的权限机制。内核代码将运行于ring 0而用户程序运行于ring 3。 因此为了适应该分级机制以及适应多任务机制,Linux 的虚拟地址空间被分为两部分,如图1所示: 0xffff ffff 0x0Linux Virtual Address Split 0xffff ffff 0x0 Windows Virtual Address Split 图1. Linux/Windows 虚拟地址空间的内核部分和用户部分。 Linux 中,内核空间为0xc0000000到0xffffffff 的地址,因此内核代码将被映射到区域。而在Windows 中,默认的分割方式为内核与用户各占2GB 。本文仅详细分析Linux 的地址空间而不再涉及Windows 。下面分两部分介绍Linux 地址空间,首先是内核地址空间然后再介绍用户地址空间。 1. 内核地址空间 黑 客防线 a c k e r .c o m .c n 明出处

Linux系统下的ELF文件分析

Linux系统下的ELF文件分析 摘要:随着linux系统的发展,elf成了十分重要的可执行文件格式。本文介绍了eIf文件的格式,并在此基础上分析出eIf文件的特性。关键词:elf文件:平台相关PIC 1.引言 ELF(Executable and Linkable Format)IN可执行连接文件格式.是LinuxSVR4和Solaris2,0默认的目标文件格式,目前标准接口委员会TIS已将ELF标准化为一种可移植的目标文件格式,运行于32一bitIntel体系微机上,可与多种操作系统兼容。分析elf文件有助于理解一些重要的系统概念,例如程序的编译和链接,程序的加载和运行等 2.ELF文件格式 2.1 ELF文件的类型ELF文件主要有三种类型 (1)可重定位文件包含了代码和数据.可与其它ELF文件建立一个可执行或共享的文件: (2)可执行文件时可直接执行的程序: (3)共享目标文件包括代码和数据,可以在两个地方链接。第一,连接器可以把它和其它可重定位文件和共享文件一起处理以建立另一个ELF文件;第二,动态链接器把它和一个可执行文件和其它共享文件结合在一起建立一个进程映像。 2.2 ELF文件的组织 ELF文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),编译器和链接器将其视为节头表(section headertable)描述的一些节(section)的集合,而加载器则将其视为程序头表(program header table)描述的段(segment)的集合,通常一个段可以包含多个节。可重定位文件都包含一个节头表.可执行文件都包含一个程序头表。共享文件两者都包含有。为此,ELF文件格式同时提供了两种看待文件内容的方式,反映了不同行为的不同要求。

Linux下ELF文件的代码签名验证机制

1 引言 随着Linux 的不断发展,已有越来越多的人开始推广和使用Linux,其安全性也受到越来越多的挑战。ELF(Executable and Linkable Format)[1]作为Linux 下最主要的可执行二进制文件格式,自然成了病毒及各种恶意代码的攻击目标。事实证明,有不少Linux下的病毒程序就是通过直接修改ELF文件的方法来实现入侵的[10]。传统的Unix系统(包括Linux)并不会对执行的代码进行完整性和合法性检测,因而让很多病毒程序以及木马程序有机可乘。 代码签名验证是一种能够有效的防止病毒以及其他恶意代码入侵的方法。对于Linux下的代码签名验证机制,早几年就已经有人研究。文[2]提出了在安装时进行签名验证的方法,并通过修改chmod系统调用控制文件的可执行属性,但这种方法无法检测程序安装后对代码的任何修改,有一定的局限性。文[3][4][5]描述的都是在执行时进行签名验证的方法,其中[4][5]采用了缓存已验证文件的策略,使效率较[3]有很大提高。但是,它们将所有ELF文件"一视同仁",没有主次轻重之分,缺少灵活性。 本文提出了一种改进的基于ELF文件格式的代码签名验证机制,通过提供更加灵活的分级验证方式,进一步提高验证效率,并且使系统在安全性与效率方面取得平衡。 2 签名验证原理 我们采用完全符合PKCS[8] 系列标准的签名验证算法,并兼容所有符合X509格式的证书,以RSA[6][7]非对称密钥体制为基础来完成对ELF文件代码的签名验证。 2.1签名 设被签名的数据为m,其数字摘要为h。 h = Hash(m) 其中,Hash是哈希单向散列算法,如MD5、SHA-1等。 设p,q,d为签名者的私有数据,他们都包含在签名者的私钥SK中;n,e为签名者的公开数据,并且都包含在签名者的公钥PK中。这些数据满足以下要求: n = pq 其中p ≠q,p q均为大素数;e,d∈RZn 并且e = d-1,ed ≡1mod(n);这里,(n) = (p-1)(q-1)。那么,使用签名者私钥对h进行加密即可得到签名值s: s = E(x) = hdmod n 2.2验证 设被验证数据为m′,其数字摘要为h′。 h′= Hash(m′) 假设我们已经取得签名者的真实公钥PK,然后我们使用PK中的公开数据e对s进行解密计算,得到还原的数字摘要h′′,这里h′′就相当于是○1式中的h。 h′′= D(s) = se mod n 现在,我们比较h′和h′′是否完全相同。如果相同则验证通过,否则验证失败。 3 设计与实现 为了便于描述,我们引入以下几个基本概念: 1. 完全摘要值--指对ELF文件的所有数据以及签名相关数据计算出来的摘要值; 2. 不完全摘要值--指对ELF文件的一部分重要数据(主要是ELF文件头)以及签名相关数

elf文件格式(中文版)

3. 页标题的内容和文章的页脚已经在开始的时候被换掉了。 4. 文章的排版也已经修正过了。 5. 如果必要,不同的字体已经被忽略了。大部分地方,这片文档能让你 充分的理解。然而,很小的地方,原始的文档使用了斜体字来指出文 章中的字符变量。在那种情况下,本文使用<尖括号>。在原始的文档 中没有出现尖括号。 6. 原始的文档有三个错误,如果你是不经意读它的话,是不会明显 就能找出的。但是在这里,明确的被鉴别出来了。 我很冒昧的纠正了那些错误。在他们的位置用一个{*}做上了标记。 可能还有其他我没有看出来的的错误。 如果有如何其他的区别都是我的责任。这样的错误请 mailto:breadbox@https://www.doczj.com/doc/2316179872.html,. Brian Raiter [Last edited Fri Jul 23 1999] ________________________________________________________________ EXECUTABLE AND LINKABLE FORMAT (ELF) Portable Formats Specification, Version 1.1 Tool Interface Standards (TIS) ________________________________________________________________ =========================== Contents 内容=========================== 序言 1. OBJECT文件 导言 ELF头(ELF Header) Sections String表(String Table) Symbol表(Symbol Table) 重定位(Relocation) 2. 程序装载与动态连接 导言 Program头(Program Header)

可执行文件(ELF)格式的理解=

可执行文件(ELF)格式的理解 ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。它自最早在System V 系统上出现后,被xNIX 世界所广泛接受,作为缺省的二进制文件格式来使用。可以说,ELF是构成众多xNIX系统的基础之一,所以作为嵌入式Linux系统乃至内核驱动程序开发人员,你最好熟悉并掌握它。 其实,关于ELF这个主题,网络上已经有相当多的文章存在,但是其介绍的内容比较分散,使得初学者不太容易从中得到一个系统性的认识。为了帮助大家学习,我这里打算写一系列连贯的文章来介绍ELF以及相关的应用。这是这个系列中的第一篇文章,主要是通过不同工具的使用来熟悉ELF文件的内部结构以及相关的基本概念。后面的文章,我们会介绍很多高级的概念和应用,比方动态链接和加载,动态库的开发,C语言Main函数是被谁以及如何被调用的,ELF格式在内核中的支持,Linux内核中对ELF section的扩展使用等等。 好的,开始我们的第一篇文章。在详细进入正题之前,先给大家介绍一点ELF文件格式的参考资料。在ELF 格式出来之后,TISC(Tool Interface Standard Committee)委员会定义了一套ELF标准。你可以从这里(https://www.doczj.com/doc/2316179872.html,/elf/)找到详细的标准文档。TISC委员会前后出了两个版本,v1.1和v1.2。两个版本内容上差不多,但就可读性上来讲,我还是推荐你读v1.2的。因为在v1.2版本中,TISC重新组织原本在v1.1版本中的内容,将它们分成为三个部分(books): a) Book I 介绍了通用的适用于所有32位架构处理器的ELF相关内容 b) Book II 介绍了处理器特定的ELF相关内容,这里是以Intel x86 架构处理器作为例子介绍 c) Book III 介绍了操作系统特定的ELF相关内容,这里是以运行在x86上面的UNIX System V.4 作为例子介绍 值得一说的是,虽然TISC是以x86为例子介绍ELF规范的,但是如果你是想知道非x86下面的ELF实现情况,那也可以在https://www.doczj.com/doc/2316179872.html,/elf/中找到特定处理器相关的Supplment文档。比方ARM相关的,或者MIPS相关的等等。另外,相比较UNIX系统的另外一个分支BSD Unix,Linux系统更靠近System V 系统。所以关于操作系统特定的ELF内容,你可以直接参考v1.2标准中的内容。 这里多说些废话:别忘了Linus 在实现Linux的第一个版本的时候,就是看了介绍Unix内部细节的书:《The of the Unix Operating System》,得到很多启发。这本书对应的操作系统是System V 的第二个Release。这本书介绍了操作系统的很多设计观念,并且行文简单易懂。所以虽然现在的Linux也吸取了其他很多Unix 变种的设计理念,但是如果你想研究学习Linux内核,那还是以看这本书作为开始为好。这本书也是我在接触Linux内核之前所看的第一本介绍操作系统的书,所以我极力向大家推荐。(在学校虽然学过操作系统原理,但学的也是很糟糕最后导致期末考试才四十来分,记忆仿佛还在昨天:)) 好了,还是回来开始我们第一篇ELF主题相关的文章吧。这篇文章主要是通过使用不同的工具来分析对象文

ELF格式data、bss、text段内容调查

详情参考<<程序员的自我修养>> 几个特殊的sections说明: 1. .bss,该section包含了在内存中的程序的未初始化的数据,当程序开始运行时,系统将用0来初始化该区域。该section不占用文件空间,该section type = SHT_NOBITS; 2. .comment,该section包含了版本控制信息; 3. .data和.data1,该section包含了在内存中的程序的初始化数据; 4. .debug,该section包含了符号调试信息,其中内容没有硬性规定; 5. .dynamic,该section包含了动态链接信息,该section属性将包含SHF_ALLOC比特位,而SHF_WRITE比特位是否为1取决于处理器; 6. .dynstr,该section包含了用于动态链接的字符串,通常是符号表项名称字符串; 7. .dynsym,该section包含了动态链接符号表; 8. .fini,该section包含了用于终止进程可执行指令代码; 9. .got,该section包含了全局偏移表; 10. .hash,该section包含了符号hash表; 11. .init,该section包含了用于初始化进程的可执行代码,也就是说,当一个程序开始运行的时候,系统将会执行在该section中的代码,然后才会调用程序的入口点(对于C程序而言就是main); 12. .interp,该section包含了程序解释其的路径; 13. .line,该section包含了符号调试信息的行号,其用于描述程序源代码和机器码之间的相应关系; 14. .note,该section包含了供应商及程序兼容信息等; 15. .plt,该section包含了程序链接表; 16. .relname和.relaname,该section包含了relocation信息,该section的属性包括了SHF_ALLOC比特位,通常,name为将要被重组的section的名称,例如如果要重组.text,那么名称就为.rel.text或者.rela.text; 17. .rodata和.rodata1,该section包含了只读数据,通常进程中的不可写段,例如Program Header; 18. .shstrtab,该section包含了section名称; 19. .strtab,该section包含了符号表项名称字符串,如果文件包含了一个可加载的并且包含了符号字符串表的segment,则section的SHF_ALLOC比特位属性将被设置; 20. .symtab,该section包含了符号表,如果文件包含了一个可加载的并且包含了符号表的segment,则section的SHF_ALLOC比特位属性将被设置; 21. .text,该section包含了程序的可执行指令。 虽然上面的例子文件中,对于text和data段而言,文件偏移和逻辑地址取模4KB后都是相等的。但是: 1. text的第一个页面包含了ELF header,program header table以及其他的信息; 2. text的最后一个页面包含了data的开始部分数据的拷贝; 3. data的第一个页面包含了text的末尾数据的拷贝; 4. data的最后一个页面也许包含了和运行进程不相关的文件信息; 理论上讲,系统对待每个段的内存权限都是相互独立的。段地址不得不调整来确保地址空间中的每个逻辑页面都有自己的权限;在上面的例子中,包含了text结尾和data开始的区域将要被映射两次:一次就是包含了text和data开始部分,另一个就是text末尾部分和data;data段的末尾还需要对为初始化数据的特殊处理,系统通常将其清零。

相关主题
文本预览
相关文档 最新文档