?? elf-file-format.txt
字號:
ELF文件格式一例分析
ELF文件格式一例分析:以nasm生成一盡量小的ELF文件,以二進制方式,以objdump方式,以readelf方式,分析加載入內存及運行規律,得出結論。 編輯一個小的asm文件如下:
crq@ $ cat new18.asm
global _start
_start:
ud0
ud1
ud2很簡單,只有 ud0, ud1, ud2 三個指令,都是產生非法 Opcode 碼所用。編譯生成ELF如下:
crq@ $ nasm -f elf new18.asm
crq@ $ ld new18.o這樣就生成了a.out是ELF格式文件,再使用objcopy除去無關緊要的節:
crq@ $ objcopy -S -R .comment -R .bss a.out運行:
crq@ $ ./a.out
Illegal instruction果如所料,程序接收到一個 SIGILL 信號默認動作是被 kill 掉了,再使用 objdump 反匯編一下:
crq@ $ objdump -d a.out
a.out: file format elf32-i386
Disassembly of section .text:
08048080 <.text>:
8048080: 0f ff (bad)
8048082: 0f b9 ud2b
8048084: 0f 0b ud2a正文段只有三行匯編語言指令。文件大?。?
crq@ $ ls -l a.out
-rwxr-xr-x 1 crq users 272 Nov 22 09:22 a.out剩余 272 Bytes. 再使用 readelf 分析:
crq@ $ readelf -a a.out
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: 0x8048080
Start of program headers: 52 (bytes into file)
Start of section headers: 152 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 3
Section header string table index: 2
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 08048080 000080 000006 00 AX 0 0 16
[ 2] .shstrtab STRTAB 00000000 000086 000011 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x00086 0x00086 R E 0x1000
Section to Segment mapping:
Segment Sections...
00 .text
There is no dynamic segment in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.ELF Header部分正常,Section Headers中有三項,第一項按慣例為空的。 Program Headers只有一項。再印出二進制碼如下:
crq@ $ hexdump -C a.out
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 |............4...|
00000020 98 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00 |........4. ...(.|
00000030 03 00 02 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 86 00 00 00 86 00 00 00 05 00 00 00 |................|
00000050 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000080 0f ff 0f b9 0f 0b 00 2e 73 68 73 74 72 74 61 62 |........shstrtab|
00000090 00 2e 74 65 78 74 00 00 00 00 00 00 00 00 00 00 |..text..........|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000c0 0b 00 00 00 01 00 00 00 06 00 00 00 80 80 04 08 |................|
000000d0 80 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 10 00 00 00 00 00 00 00 01 00 00 00 03 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 86 00 00 00 11 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000001100x000~0x034 是 ELF Header; 0x034~0x054 是一項Program Headers; 0x054~0x080 是填充零字節; 0x080~0x086 是 .text 段內容; 0x086~0x098 是 .shstrtab 段內容; 0x098~0x110 是三項Section Headers; 對照 elf.h 文件分析如下:
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 |............4...|
00000020 98 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00 |........4. ...(.|
00000030 03 00 02 00 |.... |
typedef struct elf32_hdr {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry; /* Entry point */
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;其中 ELF32_Half 是16位,其余類型 ELF32_Word, ELF32_Addr, ELF32_Off 等都是32位。 宏 EI_NIDENT 定義為 16,即 ELF Header 頭部有16Bytes特征字節。
00000030 01 00 00 00 00 00 00 00 00 80 04 08 | ............|
00000040 00 80 04 08 86 00 00 00 86 00 00 00 05 00 00 00 |................|
00000050 00 10 00 00 |.... |
typedef struct elf32_phdr{
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;00000080 0f ff 0f b9 0f 0b |...... |
00000080 00 2e 73 68 73 74 72 74 61 62 | ..shstrtab|
00000090 00 2e 74 65 78 74 00 00 |..text.. |
00000090 00 00 00 00 00 00 00 00 | ........|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 0b 00 00 00 01 00 00 00 06 00 00 00 80 80 04 08 |................|
000000d0 80 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 10 00 00 00 00 00 00 00 |........ |
000000e0 01 00 00 00 03 00 00 00 | ........|
000000f0 00 00 00 00 00 00 00 00 86 00 00 00 11 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;又查閱 nasmdoc.txt 一文中對這三個 UD 指令的描述如下:
B.4.320 `UD0', `UD1', `UD2': Undefined Instruction
UD0 ; 0F FF [186,UNDOC]
UD1 ; 0F B9 [186,UNDOC]
UD2 ; 0F 0B [186]
`UDx' can be used to generate an invalid opcode exception, for
testing purposes.
`UD0' is specifically documented by AMD as being reserved for this
purpose.
`UD1' is documented by Intel as being available for this purpose.
`UD2' is specifically documented by Intel as being reserved for this
purpose. Intel document this as the preferred method of generating
an invalid opcode exception.
All these opcodes can be used to generate invalid opcode exceptions
on all currently available processors.有趣的是,注意 objdump 的這一段輸出:
8048080: 0f ff (bad)
8048082: 0f b9 ud2b
8048084: 0f 0b ud2a在 nasm 中的三條合法指令在 GNU as 中是只有兩條合法的,并且名稱也不相同,ud2a 和 ud2b,三條用途都是產生 opcode 異常。
ELF文件格式分析之二:符號表
Symtab & Relocation info (符號表與重定位表)
寫了一個2.4內核模塊,正是分析Relocation所需要的。
readelf 先按次序讀 ELF header, Section Headers, Program Headers, Relocation entries, Symbol table entries, version information.
crq@4 $ readelf -a dptest.o
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: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 312 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 11
Section header string table index: 8
Section Headers:
[Nr] Name Type Addr Off Size ES *** Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000049 00 AX 0 0 4
[ 2] .rel.text REL 00000000 0004a0 000028 08 9 1 4
[ 3] .data PROGBITS 00000000 000080 000018 00 WA 0 0 4
[ 4] .rel.data REL 00000000 0004c8 000008 08 9 3 4
[ 5] .bss NOBITS 00000000 000098 000000 00 WA 0 0 4
[ 6] .modinfo PROGBITS 00000000 000098 000025 00 A 0 0 1
[ 7] .comment PROGBITS 00000000 0000bd 000033 00 0 0 1
[ 8] .shstrtab STRTAB 00000000 0000f0 000046 00 0 0 1
[ 9] .symtab SYMTAB 00000000 0002f0 000120 10 10 d 4
[10] .strtab STRTAB 00000000 000410 000090 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no program headers in this file.
Relocation section '.rel.text' at offset 0x4a0 contains 5 entries:
Offset Info Type Sym.Value Sym. Name
00000005 00000d01 R_386_32 00000000 print_drop
00000028 00000301 R_386_32 00000000 .data
0000002d 00000e02 R_386_PC32 00000000 nf_register_hook
0000003c 00000301 R_386_32 00000000 .data
00000041 00000f02 R_386_PC32 00000000 nf_unregister_hook
Relocation section '.rel.data' at offset 0x4c8 contains 1 entries:
Offset Info Type Sym.Value Sym. Name
00000008 00000201 R_386_32 00000000 .text
There are no unwind sections in this file.
Symbol table '.symtab' contains 18 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS dptest.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 5
5: 00000000 0 SECTION LOCAL DEFAULT 6
6: 00000000 25 OBJECT LOCAL DEFAULT 6 __module_kernel_version
7: 00000000 36 FUNC LOCAL DEFAULT 1 hook
8: 00000000 24 OBJECT LOCAL DEFAULT 3 op
9: 00000024 17 FUNC LOCAL DEFAULT 1 init
10: 00000038 17 FUNC LOCAL DEFAULT 1 clean
11: 00000019 12 OBJECT LOCAL DEFAULT 6 __module_license
12: 00000000 0 SECTION LOCAL DEFAULT 7
13: 00000000 0 NOTYPE GLOBAL DEFAULT UND print_drop
14: 00000000 0 NOTYPE GLOBAL DEFAULT UND nf_register_hook
15: 00000000 0 NOTYPE GLOBAL DEFAULT UND nf_unregister_hook
16: 00000024 17 FUNC GLOBAL DEFAULT 1 init_module
17: 00000038 17 FUNC GLOBAL DEFAULT 1 cleanup_module
No version information found in this file.其中就有Relocation Section有.rel.text和.rel.data,
.rel.text section
000004a0 05 00 00 00 01 0d 00 00 28 00 00 00 01 03 00 00 |........(.......|
000004b0 2d 00 00 00 02 0e 00 00 3c 00 00 00 01 03 00 00 |-.......<.......|
000004c0 41 00 00 00 02 0f 00 00 |A....... |
.rel.data section
000004c0 08 00 00 00 01 02 00 00 | ........|
000004d0
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -