Questions about this topic? Sign up to ask in the talk tab.
Difference between revisions of "User:Hatter/ELF format"
From NetSec
(→Parsing elf files) |
(→Parsing elf files) |
||
Line 124: | Line 124: | ||
'''Segmentation fault''' | '''Segmentation fault''' | ||
− | |||
− | |||
+ | == Headers == | ||
* '''Diagram of a 64-bit ELF Header:''' | * '''Diagram of a 64-bit ELF Header:''' | ||
0x0 - 0xf = "ELF Format Information" | 0x0 - 0xf = "ELF Format Information" | ||
Line 136: | Line 135: | ||
− | * '''Diagram of a 64-bit section header:''' ''( | + | * '''Diagram of a 64-bit section header:''' ''(length defined in ELF header)'' |
[0x0-0x3] shstrtab offset for section name. | [0x0-0x3] shstrtab offset for section name. | ||
shstrtab is defined between the end of | shstrtab is defined between the end of | ||
Line 147: | Line 146: | ||
[0x18-0x1f] section offset | [0x18-0x1f] section offset | ||
[0x20-0x27] section size | [0x20-0x27] section size | ||
+ | [0x28-0x2b] Section Link | ||
+ | [0x2c-0x2f] Section Info | ||
+ | [0x30-0x37] Section Align | ||
+ | [0x38-0x3f] Section EntSize | ||
+ | |||
− | * '''Diagram of a 64-bit symbol table entry:''' | + | == Symbol Tables == |
+ | * '''Diagram of a 64-bit symbol table entry:''' ''(0x18 bytes in length)'' | ||
− | [0x0-0x3] Name offset | + | [0x0-0x3] Name offset from next string table |
[0x4-0x5] Bind | [0x4-0x5] Bind | ||
[0x6-0x7] Ndx | [0x6-0x7] Ndx | ||
[0x8-0xf] Symbol pointer (Function pointer, data pointer, etc) | [0x8-0xf] Symbol pointer (Function pointer, data pointer, etc) | ||
[0x10-0x17] Null barrier | [0x10-0x17] Null barrier |
Revision as of 19:37, 9 September 2012
The Extecutable and Linkable Format (ELF) is used to construct binary executables for the Linux Operating System.
Reading ELF files
A variety of applications, debuggers, disassemblers, and resource viewers are available to read ELF formatted binaries:
- hexdump
- readelf
- objdump
Parsing elf files
It is relatively trivial to find your imagebase at runtime using some small assembly, but more difficult to actually parse out the ELF image. Here's an unstable (no error checking) assembly code that will dump its own symbols:
.section .data .section .text .globl _start _start: jmp startup getpc: mov (%rsp), %rax ret startup: xor %r15, %r15 push $0x0a0a0a mov %rsp, %r15 call getpc dec %rax xor %rcx, %rcx push $0x2 pop %rsi find_header: cmpl $0x464c457f, (%rax,%rcx,4) # Did we find our ELF base pointer? je find_sections dec %rax jmp find_header find_sections: # %rax now = base pointer of ELF image. xor %rbx, %rbx add $0x28, %bl xorl (%rax,%rbx,1), %ecx # %rcx = offset to section headers addq %rax, %rcx # %rcx = absolute address to section headers # each section header is 0x40 bytes in length. next_section: xor %rbx, %rbx xor %rbp, %rbp add $0x40, %rcx # %rcx now = address to first entry add $0x04, %bl xor (%rcx,%rbx,1), %ebp # %rbp now contains type cmp $0x02, %bpl je found_symbols jmp next_section found_symbols: xor %r8, %r8 mov %rcx, %r8 # %rcx = pointer to top of symbol section header add $0x40, %r8 # %r8 = pointer to top of string table section header xor %rbx, %rbx xor $0x18, %bl # pointer to actual section is $0x18 bytes from header base xor %r9, %r9 xor %r10, %r10 xor (%rcx,%rbx,1), %r9 xor (%r8,%rbx,1), %r10 addq %rax, %r9 # r9 should now point to the first symbol addq %rax, %r10 # r10 should now point to the first string next_symbol: add $0x24,%r9 xor %rcx, %rcx xor %rbp, %rbp xor %rdi, %rdi xor (%r9,%rcx,1), %ebp # %rbp now contains string offset. cmp %rbp, %rdi je next_symbol print_symbol_name: mov %rbp, %rsi addq %r10, %rsi # %rsi should now be a pointer to a string push $0x01 pop %rax push %rax pop %rdi call strlen syscall push $0x01 pop %rax push %rax pop %rdi push $0x02 pop %rdx push %r15 pop %rsi syscall jmp next_symbol strlen: xor %rdx, %rdx next_byte: inc %rdx cmpb $0x00, (%rsi,%rdx,1); jne next_byte ret |
[hatter@bha soinject]$ ./test_parser getpc next_section print_symbol_name __bss_start Segmentation fault
Headers
- Diagram of a 64-bit ELF Header:
0x0 - 0xf = "ELF Format Information" Entry-point = 0x18 - 0x1f Start of section headers = 0x28 - 0x2f Size of each section = 0x3a - 0x3b Number of section headers = 0x3c - 0x3d
- Diagram of a 64-bit section header: (length defined in ELF header)
[0x0-0x3] shstrtab offset for section name. shstrtab is defined between the end of .text and the beginning of the section headers
[0x4-0x7] section type - 0 is null, 1 is progbits, 2 is symtab, 3 is strtab [0x8-0xf] section flags [0x10-0x17] section address [0x18-0x1f] section offset [0x20-0x27] section size [0x28-0x2b] Section Link [0x2c-0x2f] Section Info [0x30-0x37] Section Align [0x38-0x3f] Section EntSize
Symbol Tables
- Diagram of a 64-bit symbol table entry: (0x18 bytes in length)
[0x0-0x3] Name offset from next string table [0x4-0x5] Bind [0x6-0x7] Ndx [0x8-0xf] Symbol pointer (Function pointer, data pointer, etc) [0x10-0x17] Null barrier