IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 分析ELF二进制文件 -> 正文阅读

[系统运维]分析ELF二进制文件


分析平台: x86_64机器

简单的C程序

$ cat hello.c
int main() {
  return 0;
}

将该文件用gcc 编译成可重定位文件, 利用hexdump -C得到其16进制的文本(用vim -b 打开, 再用:%!xxd -g 1也可以得到)

$ gcc hello.c -c
$ hexdump -C hello.o

得到的文本:

00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  01 00 3e 00 01 00 00 00  00 00 00 00 00 00 00 00  |..>.............|
00000020  00 00 00 00 00 00 00 00  10 02 00 00 00 00 00 00  |................|
00000030  00 00 00 00 40 00 00 00  00 00 40 00 0b 00 0a 00  |....@.....@.....|
00000040  55 48 89 e5 b8 00 00 00  00 5d c3 00 47 43 43 3a  |UH.......]..GCC:|
00000050  20 28 47 4e 55 29 20 38  2e 35 2e 30 20 32 30 32  | (GNU) 8.5.0 202|
00000060  31 30 35 31 34 20 28 52  65 64 20 48 61 74 20 38  |10514 (Red Hat 8|
00000070  2e 35 2e 30 2d 31 30 29  00 00 00 00 00 00 00 00  |.5.0-10)........|
00000080  14 00 00 00 00 00 00 00  01 7a 52 00 01 78 10 01  |.........zR..x..|
00000090  1b 0c 07 08 90 01 00 00  1c 00 00 00 1c 00 00 00  |................|
000000a0  00 00 00 00 0b 00 00 00  00 41 0e 10 86 02 43 0d  |.........A....C.|
000000b0  06 46 0c 07 08 00 00 00  00 00 00 00 00 00 00 00  |.F..............|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000d0  01 00 00 00 04 00 f1 ff  00 00 00 00 00 00 00 00  |................|
000000e0  00 00 00 00 00 00 00 00  00 00 00 00 03 00 01 00  |................|
000000f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000100  00 00 00 00 03 00 02 00  00 00 00 00 00 00 00 00  |................|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 03 00 03 00  |................|
00000120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000130  00 00 00 00 03 00 05 00  00 00 00 00 00 00 00 00  |................|
00000140  00 00 00 00 00 00 00 00  00 00 00 00 03 00 06 00  |................|
00000150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000160  00 00 00 00 03 00 04 00  00 00 00 00 00 00 00 00  |................|
00000170  00 00 00 00 00 00 00 00  09 00 00 00 12 00 01 00  |................|
00000180  00 00 00 00 00 00 00 00  0b 00 00 00 00 00 00 00  |................|
00000190  00 68 65 6c 6c 6f 2e 63  00 6d 61 69 6e 00 00 00  |.hello.c.main...|
000001a0  20 00 00 00 00 00 00 00  02 00 00 00 02 00 00 00  | ...............|
000001b0  00 00 00 00 00 00 00 00  00 2e 73 79 6d 74 61 62  |..........symtab|
000001c0  00 2e 73 74 72 74 61 62  00 2e 73 68 73 74 72 74  |..strtab..shstrt|
000001d0  61 62 00 2e 74 65 78 74  00 2e 64 61 74 61 00 2e  |ab..text..data..|
000001e0  62 73 73 00 2e 63 6f 6d  6d 65 6e 74 00 2e 6e 6f  |bss..comment..no|
000001f0  74 65 2e 47 4e 55 2d 73  74 61 63 6b 00 2e 72 65  |te.GNU-stack..re|
00000200  6c 61 2e 65 68 5f 66 72  61 6d 65 00 00 00 00 00  |la.eh_frame.....|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000250  1b 00 00 00 01 00 00 00  06 00 00 00 00 00 00 00  |................|
00000260  00 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |........@.......|
00000270  0b 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000280  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000290  21 00 00 00 01 00 00 00  03 00 00 00 00 00 00 00  |!...............|
000002a0  00 00 00 00 00 00 00 00  4b 00 00 00 00 00 00 00  |........K.......|
000002b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000002c0  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000002d0  27 00 00 00 08 00 00 00  03 00 00 00 00 00 00 00  |'...............|
000002e0  00 00 00 00 00 00 00 00  4b 00 00 00 00 00 00 00  |........K.......|
000002f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000300  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000310  2c 00 00 00 01 00 00 00  30 00 00 00 00 00 00 00  |,.......0.......|
00000320  00 00 00 00 00 00 00 00  4b 00 00 00 00 00 00 00  |........K.......|
00000330  2e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000340  01 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000350  35 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |5...............|
00000360  00 00 00 00 00 00 00 00  79 00 00 00 00 00 00 00  |........y.......|
00000370  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000380  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000390  4a 00 00 00 01 00 00 00  02 00 00 00 00 00 00 00  |J...............|
000003a0  00 00 00 00 00 00 00 00  80 00 00 00 00 00 00 00  |................|
000003b0  38 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |8...............|
000003c0  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000003d0  45 00 00 00 04 00 00 00  40 00 00 00 00 00 00 00  |E.......@.......|
000003e0  00 00 00 00 00 00 00 00  a0 01 00 00 00 00 00 00  |................|
000003f0  18 00 00 00 00 00 00 00  08 00 00 00 06 00 00 00  |................|
00000400  08 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
00000410  01 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
00000420  00 00 00 00 00 00 00 00  b8 00 00 00 00 00 00 00  |................|
00000430  d8 00 00 00 00 00 00 00  09 00 00 00 08 00 00 00  |................|
00000440  08 00 00 00 00 00 00 00  18 00 00 00 00 00 00 00  |................|
00000450  09 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
00000460  00 00 00 00 00 00 00 00  90 01 00 00 00 00 00 00  |................|
00000470  0e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000480  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000490  11 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
000004a0  00 00 00 00 00 00 00 00  b8 01 00 00 00 00 00 00  |................|
000004b0  54 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |T...............|
000004c0  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000004d0

可利用二进制工具readelf, objdump来分析该可重定位文件是怎么排列的.

分析可重定位文件(hello.o)

可以看到分文件由"*"号附近分为两部分(都是十六进制):

  1. 00000000~00000200
  2. 00000210~ 00000250~ 000004c0

第1部分是ELF头和各个section的内容.
第2部分是描述各个sction的section header的结构体内容.

$ readelf -h hello.o
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x0
  程序头起点:              0 (bytes into file)
  Start of section headers:          528 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         64 (字节)
  节头数量:         11
  字符串表索引节头: 10

可以看到section header是从528(十六进制为210)开始的, 且节头为64字节:

typedef struct {
	Elf64_Word	sh_name; // 4 B (B for bytes)
	Elf64_Word	sh_type; // 4 B
	Elf64_Xword	sh_flags; // 8 B
	Elf64_Addr	sh_addr; // 8 B
	Elf64_Off	sh_offset; // 8 B
	Elf64_Xword	sh_size; // 8 B
	Elf64_Word	sh_link; // 4 B
	Elf64_Word	sh_info; // 4 B
	Elf64_Xword	sh_addralign; // 8 B
	Elf64_Xword	sh_entsize; // 8 B
} Elf64_Shdr; // total size: 64 B

利用

readelf -SW hello.o

可以得到各个section的信息:

There are 11 section headers, starting at offset 0x210:

节头:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00000b 00  AX  0   0  1
  [ 2] .data             PROGBITS        0000000000000000 00004b 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          0000000000000000 00004b 000000 00  WA  0   0  1
  [ 4] .comment          PROGBITS        0000000000000000 00004b 00002e 01  MS  0   0  1
  [ 5] .note.GNU-stack   PROGBITS        0000000000000000 000079 000000 00      0   0  1
  [ 6] .eh_frame         PROGBITS        0000000000000000 000080 000038 00   A  0   0  8
  [ 7] .rela.eh_frame    RELA            0000000000000000 0001a0 000018 18   I  8   6  8
  [ 8] .symtab           SYMTAB          0000000000000000 0000b8 0000d8 18      9   8  8
  [ 9] .strtab           STRTAB          0000000000000000 000190 00000e 00      0   0  1
  [10] .shstrtab         STRTAB          0000000000000000 0001b8 000054 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

00000210~ 00000250全是0, 对于index[0]的section.
同理,下面的也是各个section header.
下一个的sh_name 1b为偏移, 刚好为1b8+1b=1d3 是.text的名字, 以此类推.

可以看到其偏移为40, 大小为b, 使用objdump -dr hello.o可以看到其二进制代码为:

$objdump -dr hello.o
hello.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	b8 00 00 00 00       	mov    $0x0,%eax
   9:	5d                   	pop    %rbp
   a:	c3                   	retq   

而对应的偏移[0x40,0x40 + 0xb)的位置信息:
55 48 89 e5 b8 00 00 00 00 5d c3
刚好为该段代码的二进制.

接下来节.data, .bss大小都为0
.comment是[0x4b, 0x4b+2e), 即[0x4b, 0x79),
从二进制看
00000040 00 47 43 43 3a
00000050 20 28 47 4e 55 29 20 38 2e 35 2e 30 20 32 30 32
00000060 31 30 35 31 34 20 28 52 65 64 20 48 61 74 20 38
00000070 2e 35 2e 30 2d 31 30 29 00

为comment信息 GCC: (GNU) 8.5.0 210514 (Red Hat 8.5.0-10)

接下来是.note.GNU-stack, 大小都为0.

接着是.eh_frame [0x80, 0x80+38), 因为对其是8, 所以从0x80开始.
具体内容有兴趣可继续研究.

接下来是.symtab, [0xb8, 0xb8+0xd8), 即[0xb8, 0x190),
typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) /
unsigned char st_info; /
Symbol type and binding /
unsigned char st_other; /
Symbol visibility /
Elf64_Section st_shndx; /
Section index /
Elf64_Addr st_value; /
Symbol value /
Elf64_Xword st_size; /
Symbol size */
} Elf64_Sym;
共9个符号入口9x24=216=0xb8

接下来是.rela.eh_frame是放了一个重定位, 对于该机器来说, 一个重定位大小为0x18,即24字节.

typedef struct elf_internal_rela {
bfd_vma r_offset; /* Location at which to apply the action /
bfd_vma r_info; /
Index and Type of relocation /
bfd_vma r_addend; /
Constant addend used to compute value */
} Elf_Internal_Rela;
内容;
所以该节大小都是24(0x18)的整数倍.

参考文献

Linux ELF 详解2 – Section Header & Section https://blog.csdn.net/helowken2/article/details/113757332

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 21:01:04  更:2022-03-22 21:02:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:23:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码