• 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

     

  • 相关阅读:
    使用postman做接口测试(三)
    使用postman做接口测试(二)
    使用postman做接口测试(一)
    RobotFramework安装扩展库包autoitlibrary(四)
    RobotFramework安装扩展库包Selenium2Library(三)
    记录.gitattributes 设置合并时使用本地文件无效的解决方案
    golang 踩坑日记
    linux常用命令记录
    vim配置文件
    mysql case when记录
  • 原文地址:https://www.cnblogs.com/lxq20135309/p/5551658.html
Copyright © 2020-2023  润新知