• Linux及安全实践四——ELF文件格式分析


    Linux及安全实践四——ELF文件格式分析

    一、ELF文件格式概述

    1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西、以及都以什么样的格式去放这些东西。

    二、分析一个ELF文件

    以一个最简单的helloworld程序为例

    1. ELF文件头

    使用工具查看ELF文件头:readelf -h obj

     

    在/usr/include/elf.h中可以找到文件头结构定义:

     

    大小总共为64字节,换算成十六进制为0x40。在十六进制代码中找到前0x40字节,即为文件头信息部分(阅读时注意反序问题):

     

    (1)identification

     

    第一部分:占四个字节。7f 45 4c 46,对应ASCII码.ELF,表示这是一个ELF对象。

    第二部分:占一个字节。02表示是一个64位对象。

    第三部分:占一个字节。01表示是小端表示法。

    第四部分:占一个字节。01表示文件头版本。

    其余默认为0。

    (2)information

     

    e_type:两个字节,01 00表示是一个重定位文件。

    e_machine:两个字节,3e 00表示是intel80386处理器体系结构。

    e_version:四个字节,01 00 00 00表示是当前版本。

    e_entry:八个字节,00 00 00 00 00 00 00 00表示当前程序没有入口点。

    e_phoff:八个字节,00 00 00 00 00 00 00 00表示没有程序头表。

    e_shoff:八个字节,90 02 00 00 00 00 00 00表示段表的偏移地址在00 00 00 00 00 00 02 90处。

    e_flags:四个字节,00 00 00 00表示未知处理器特定标志#define EF_SH_UNKNOWN 0x0。

    e_ehsize:两个字节,40 00表示elf文件头大小为00 40(64个字节)。

    e_phentsize:两个字节,00 00表示重定位文件没有程序头表。

    e_phnum:两个字节,00 00表示重定位文件没有程序头表。

    e_ehentsize:两个字节,40 00 表示段头大小为00 40(64字节),section header table中每个header的大小。

    e_shnum:两个字节,0d 00表示段表入口有13个,即段表有13段。

    e_shstrndx:两个字节,0a 00 表示段表字符串在段表中的索引号,.shstrab段的段表索引号为00 0a,即10。

    2. 通过文件头找到各个节

    使用工具查看段表信息:readelf -S obj

    (1)找到段表

    在文件头中e_shoff可以找到段表偏移地址00 00 00 00 00 00 02 90,从这个地址去查找段表。

    段表长度由e_ehentsize为00 40(64字节)。

    段表个数由e_shnum可知有13个。

    /usr/include/elf.h中可以找到段表结构:

     

    (2)分析一个段表

    第一个段:全为零,不表示任何段。

     

    第二个段:

     

    sh_name:四个字节,20 00 00 00表示该段名称在.shstrtab中偏移量,为.test节。

    sh_type:四个字节,01 00 00 00表示这个段拥有程序所定义的信息,其格式和含义完全由该程序确定,这里表示PROGBITS。

    sh_flags:八个字节,06 00 00 00 00 00 00 00表示alloc和execute。

    sh_addr:八个字节,00 00 00 00 00 00 00 00表示是section在内存中的虚拟地址,.o文件不需要执行,这里都是0。

    sh_offset:八个字节,40 00 00 00 00 00 00 00表示是section与文件头之间的偏移。

    sh_size:八个字节,11 00 00 00 00 00 00 00表示文件里面section占用的大小。

    sh_link:四个字节,00 00 00 00表示没有链接信息。

    sh_info:四个字节,00 00 00 00表示没有辅助信息。

    sh_addralign:八个字节,01 00 00 00 00 00 00 00表示字节对齐长度。

    sh_entsize:八个字节,00 00 00 00 00 00 00 00表示没有入口。(3)所有段表

    第三个段:

     

    段名:.rel.text

    类型:RELA

    标志:info

    相对文件头偏移:0x1e0

    占用大小:0x30

    第四个段:

     

    段名:.data

    类型:PROGBITS

    标志:write、alloc

    相对文件头偏移:0x51

    占用大小:0

    第五个段:

     

    段名:.bss

    类型:NOBITS

    标志:write、alloc

    相对文件头偏移:0x51

    占用大小:0

    第六个段:

     

    段名:.rodata

    类型:PROGBITS

    标志:alloc

    相对文件头偏移:0x51

    占用大小:0x0b

    第七个段:

     

    段名:.comment

    类型:PROGBITS

    标志:merge、strings

    相对文件头偏移:0x5c

    占用大小:0x26

    第八个段:

     

    段名:.note.GNU-stack

    类型:PROGBITS

    标志:无

    相对文件头偏移:0x82

    占用大小:0

    第九个段:

     

    段名:.eh_frame

    类型:PROGBITS

    标志:alloc

    相对文件头偏移:0x88

    占用大小:0x38

    第十个段:

     

    段名:.rela.eh_frame

    类型:RELA

    标志:info

    相对文件头偏移:0x210

    占用大小:0x18

    第十一段:

     

    段名:.shstrtab

    类型:STRTAB

    标志:无

    相对文件头偏移:0x228

    占用大小:0x61

    第十二段:

     

    段名:.symtab

    类型:STRTAB

    标志:无

    相对文件头偏移:0xc0

    占用大小:0x0108

    第十三段:

     

    段名:.strtab

    类型:STRTAB

    标志:无

    相对文件头偏移:0x1c8

    占用大小:0x11

    三、理解常见节

    1. .text节:本节中是可执行指令的集合

    通过刚才的信息,我们可以从文件中偏移0x40处找到大小为0x11的 .text节:

     

    可以通过反汇编该程序来查看:

     

    2. .rodata:本节是只读数据,ro代表read only

    从偏移0x51处找到大小为0x0b的 .rodata节:

     

    使用ASCII码对照表翻译数据为hello 5309,即.c文件中的字符串:

     

    2. .comment:本节用来存放编译器版本信息

    从偏移0x5c处找到大小为0x26的 .comment节:

     

    3. .symtab:本节存放所有section中定义的符号名字,一般是变量、函数shstrtab及symtab经常引用strtab中的字符串

    从偏移0xc0处找到大小为0x0108的 .symtab节:

     

    4. .strtab:本节是段表的字符串表

    从偏移0x1c8处找到大小为0x11的 .strtab节:

     

    数据用“0”分隔出了三部分,用ASCII码翻译:

    65 6c 66 2e 63:elf.c

    6d 61 69 6e:main

    70 75 74 73:puts

     

  • 相关阅读:
    Oracle常用命令大全(很有用,做笔记)
    表格驱动编程在代码中的应用
    mac 利用svn下载远程代码出现Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
    FAILURE: Build failed with an exception.
    There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance
    react native TypeError network request failed
    Android向系统相册中插入图片,相册中会出现两张 一样的图片(只是图片大小不一致)
    react-native Unrecognized font family ‘Lonicons’;
    react-native SyntaxError xxxxx/xx.js:Unexpected token (23:24)
    Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.
  • 原文地址:https://www.cnblogs.com/lxq20135309/p/5551658.html
Copyright © 2020-2023  润新知