readelf elf文件格式分析
首先需要介绍的概念是目标文件(Object file)的概念。目标文件是计算机科学中编译器或汇编器处理源代码后所生成的代码(目标代码,Object code)的计算机文件,它常被称作二进制文件(binaries)。这个文件类型主要是区别于你看得懂的用人话写的代码文件(.c、.cpp etc.)、中间文件(.i)、汇编文件(.s)。常见的.exe、.dll、.so啥的都算目标文件。
目标文件有三种类型:
编译的过程如下图所示
代码文件经过语言预处理器、编译器、汇编器和链接器处理,最终生成可执行目标文件。
下面以一个简单的c语言文件为例:
sum.c源文件内容如下:
1 2 3 4 5 6 7 8 9 |
int sum(int *a, int n) { int i, s = 0; for (i = 0; i < n; ++i) { s += a[i]; } return s; } |
通过运行C预处理器(cpp)可以生成sum.i中间文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 1 "sum.c" # 1 " |
通过运行C编译器(cc1),将中间文件生成为sum.s汇编文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
.file›"sum.i" .text .globl sum .type›sum, @function sum: .LFB0: .cfi_startproc movl $0, %eax movl $0, %edx jmp›.L2 .L3: movslq %edx, %rcx addl (%rdi,%rcx,4), %eax addl $1, %edx .L2: cmpl %esi, %edx jl .L3 rep ret .cfi_endproc .LFE0: .size›sum, .-sum .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)" .section .note.GNU-stack,"",@progbits |
最终生成通过汇编器(as)生成一个可重定位目标文件(reloacatable object file)。
系统里的目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不相同。
从贝尔实验室诞生的第一个Unix系统使用的是a.out格式(直到今天,可执行文件仍然称为a.out文件)。Windows使用可移植可执行(PortableExecutable,PE)格式。Mac OS-X使用Mach-O格式。现代x86-64Linux和Unix系统使用可执行可链接格式(Executable and Linkable Format,ELF)。
ELF格式的文件在Linux系统下有.axf、 .bin、 .elf、 .o、 .prx、 .puff、 .ko、 .mod和.so等等
前面介绍了这么多ELF的背景知识,下面回来来说说readelf这个指令。这个指令正是用来查看目标文件的内容的。
典型的ELF可重定位目标文件的格式如下图:
其中:
-g
参数编译时才会有,用于debug-g
参数编译时才会有符号表每节定义如下:
1 2 3 4 5 6 7 8 9 |
typedef struct { int name; /* String table offset */ char type:4, /* Function or data (4 bits) */ binding:4; /* Local or global (4 bits) */ char reserved; /* Unused */ short section; /* Section header index */ long value; /* Section offset or absolute address */ long size; /* Object size in bytes */ } Elf64_Symbol; |
具体解释如下:
以上面的sum.c生成的sum.o为例,我们选取readelf
的-all
参数输出全部内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
$readelf -all sum.o ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 536 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 11 Section header string table index: 10 Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .text PROGBITS 0000000000000000 00000040 000000000000001b 0000000000000000 AX 0 0 1 [ 2] .data PROGBITS 0000000000000000 0000005b 0000000000000000 0000000000000000 WA 0 0 1 [ 3] .bss NOBITS 0000000000000000 0000005b 0000000000000000 0000000000000000 WA 0 0 1 1 int sum(int *a, int n) 2 { [ 4] .comment PROGBITS 0000000000000000 0000005b 000000000000002e 0000000000000001 MS 0 0 1 [ 5] .note.GNU-stack PROGBITS 0000000000000000 00000089 0000000000000000 0000000000000000 0 0 1 [ 6] .eh_frame PROGBITS 0000000000000000 00000090 0000000000000030 0000000000000000 A 0 0 8 [ 7] .rela.eh_frame RELA 0000000000000000 000001a8 0000000000000018 0000000000000018 I 8 6 8 [ 8] .symtab SYMTAB 0000000000000000 000000c0 00000000000000d8 0000000000000018 9 8 8 [ 9] .strtab STRTAB 0000000000000000 00000198 000000000000000b 0000000000000000 0 0 1 [10] .shstrtab STRTAB 0000000000000000 000001c0 0000000000000054 0000000000000000 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) There are no section groups in this file. There are no program headers in this file. Relocation section '.rela.eh_frame' at offset 0x1a8 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported. Symbol table '.symtab' contains 9 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS sum.i 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3 5: 0000000000000000 0 SECTION LOCAL DEFAULT 5 6: 0000000000000000 0 SECTION LOCAL DEFAULT 6 7: 0000000000000000 0 SECTION LOCAL DEFAULT 4 8: 0000000000000000 27 FUNC GLOBAL DEFAULT 1 sum No version information found in this file. |
其中第一部分是ELF头(ELF header)中的描述信息。(用-h
参数可以单独得到)。
最后一部分是符号表部分(用-s
参数可以单独得到该部分),前面八个条目是链接器内部使用的局部符号,最后一行是全局符号sum
定义的条目。可以通过最后一行看出,它是一个位于.text节中偏移量为0处的27字节函数。(Ndx部分表示在哪个节中,1表示.text节,3表示.data节,对应上面输出的Section Headers
部分)
Android NDK /Android/Sdk/ndk/16.1.4479499/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-readelf libserial_port.so -a >>serail_info.txt
此处涉及到逆向分析汇编原理部分 进一步了解
【精选】逆向分析-010Editor_010editor怎么用_° LuK的博客-CSDN博客
参考 :ELF 文件解析 1-前述+文件头分析 - 知乎