file ./level5
1 2
| root@93393c52261a:/pwn# file level5 level5: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=f01f8fd41061f9dafb9399e723eb52d249a9b34d, not stripped
|
dynamically linked 动态链接程序
not stripped 没有去除符号表

动态库文件,也就是 .so 文件
1 2 3 4 5
| ╭─root@97b3a7509c5a /pwn/jarvisoj/level6/level6 ╰─# ldd freenote_x86 linux-gate.so.1 => (0xf7f61000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7d9f000) /lib/ld-linux.so.2 (0xf7f63000)
|
libc 库文件 libc.so.6
起始地址后三位是 0
想我们之后如果泄露 libc 地址,我们经常会看他的后三位是零,然后来判断这个地址泄露的是否正确
- 动态链接文件
- 静态链接文件
- 可以动过 file 指令或者 ldd 指令进行区分
ELF 文件格式

ELF 文件格式解析
我们可以用,readelf 命令和一些参数去查看 elf 文件结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ╭─root@97b3a7509c5a /pwn/jarvisoj/level6/level6 ╰─# readelf -h freenote_x86 ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x804857a Start of program headers: 52 (bytes into file) Start of section headers: 5132 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 28 Section header string table index: 27
|
-h 读取ELF文件头
有时候需要 dump binary ,有一个很重要的参考标准就是我是不是 dump 到地方了或者是哪个地方开始才是我们的二进制文件,我们就可以以 magic number 开头的 7f 作为一个标准
magic number : \x7f
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
| ╭─root@97b3a7509c5a /pwn/jarvisoj/level6/level6 ╰─# readelf -l freenote_x86
Elf file type is EXEC (Executable file) Entry point 0x804857a There are 8 program headers, starting at offset 52
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4 INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x01190 0x01190 R E 0x1000 LOAD 0x001190 0x0804a190 0x0804a190 0x00138 0x00160 RW 0x1000 DYNAMIC 0x00119c 0x0804a19c 0x0804a19c 0x000e8 0x000e8 RW 0x4 NOTE 0x000148 0x08048148 0x08048148 0x00044 0x00044 R 0x4 GNU_EH_FRAME 0x000d5c 0x08048d5c 0x08048d5c 0x0007c 0x0007c R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07
|
-l 参数显示程序头表,可以帮我们看一下这个 segment 有哪些
program headers 程序头表
- 描述文件的各种 segment
- 系统如何创建进行映像
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
| ╭─root@97b3a7509c5a /pwn/jarvisoj/level6/level6 ╰─# readelf -S freenote_x86 There are 28 section headers, starting at offset 0x140c:
Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4 [ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4 [ 4] .gnu.hash GNU_HASH 0804818c 00018c 00002c 04 A 5 0 4 [ 5] .dynsym DYNSYM 080481b8 0001b8 0000f0 10 A 6 1 4 [ 6] .dynstr STRTAB 080482a8 0002a8 00008c 00 A 0 0 1 [ 7] .gnu.version VERSYM 08048334 000334 00001e 02 A 5 0 2 [ 8] .gnu.version_r VERNEED 08048354 000354 000020 00 A 6 1 4 [ 9] .rel.dyn REL 08048374 000374 000018 08 A 5 0 4 [10] .rel.plt REL 0804838c 00038c 000058 08 AI 5 12 4 [11] .init PROGBITS 080483e4 0003e4 000023 00 AX 0 0 4 [12] .plt PROGBITS 08048410 000410 0000c0 04 AX 0 0 16 [13] .text PROGBITS 080484d0 0004d0 000702 00 AX 0 0 16 [14] .fini PROGBITS 08048bd4 000bd4 000014 00 AX 0 0 4 [15] .rodata PROGBITS 08048be8 000be8 000174 00 A 0 0 4 [16] .eh_frame_hdr PROGBITS 08048d5c 000d5c 00007c 00 A 0 0 4 [17] .eh_frame PROGBITS 08048dd8 000dd8 0003b8 00 A 0 0 4 [18] .init_array INIT_ARRAY 0804a190 001190 000004 00 WA 0 0 4 [19] .fini_array FINI_ARRAY 0804a194 001194 000004 00 WA 0 0 4 [20] .jcr PROGBITS 0804a198 001198 000004 00 WA 0 0 4 [21] .dynamic DYNAMIC 0804a19c 00119c 0000e8 08 WA 6 0 4 [22] .got PROGBITS 0804a284 001284 000004 04 WA 0 0 4 [23] .got.plt PROGBITS 0804a288 001288 000038 04 WA 0 0 4 [24] .data PROGBITS 0804a2c0 0012c0 000008 00 WA 0 0 4 [25] .bss NOBITS 0804a2e0 0012c8 000010 00 WA 0 0 32 [26] .comment PROGBITS 00000000 0012c8 00004e 01 MS 0 0 1 [27] .shstrtab STRTAB 00000000 001316 0000f6 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)
|
-S 读取节头表
section headers : 文件节区的信息,大小和偏移等等
一些常见的 section 和功能

- 32 bit
- eax 保存系统调用号
- ebx,ecx,edx,esi,edi 保存函数调用参数
- int 0x80 进行系统调用
- 返回值保存在 eax 中
write(1,esp,0xf0)
1 标准输出 stdout,改成0(stdin)也可以输出
esp 从esp开始
0xf0 输出0xf0个字节
注意⚠️:返回值保存在 eax 中

- 64 bit
- rax 保存系统调用号,前三个参数通过 rdi,rsi,rdx 储存
- 返回值保存在 rax 中
参考链接
https://blog.csdn.net/edonlii/article/details/8779075
ELF格式文件符号表全解析及readelf命令使用方法
https://blog.csdn.net/RobinZZX/article/details/96106184
关于 .init .fini .init_array .fini_array
https://visualgdb.com/gdbreference/commands/x
gdb x 命令
http://syscalls.kernelgrok.com/
32 linux syscall regerence
http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
用于X86 64的LINUX系统调用表