HEADER
ELF Header
ELF 헤더는 ELF 파일 맨 앞에 존재하며 ELF 파일임을 나타냅니다. ELF 헤더 내용은 readelf -h(--file -header) 옵션을 사용해서 확인할 수 있습니다.
$ readelf -h hello 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: 0x8048320 Start of program headers: 52 (bytes into file) Start of section headers: 4436 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 9 Size of section headers: 40 (bytes) Number of section headers: 30 Section header string table index: 27 |
object파일의 경우 Type이 REL(Relocatable file)임을 알 수 있습니다. object 파일을 만드는 gcc 옵션은 -c 입니다.
$ readelf -h hello.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: 284 (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: 13 Section header string table index: 10 |
Program Header Table
프로그램 헤더는 readelf의 -l 옵션(--program-headers)으로 표시된다.
$ readelf -l hello Elf file type is EXEC (Executable file) Entry point 0x8048320 There are 9 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4 INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x005b8 0x005b8 R E 0x1000 LOAD 0x000f08 0x08049f08 0x08049f08 0x00118 0x0011c RW 0x1000 DYNAMIC 0x000f14 0x08049f14 0x08049f14 0x000e8 0x000e8 RW 0x4 NOTE 0x000168 0x08048168 0x08048168 0x00044 0x00044 R 0x4 GNU_EH_FRAME 0x0004dc 0x080484dc 0x080484dc 0x0002c 0x0002c R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 GNU_RELRO 0x000f08 0x08049f08 0x08049f08 0x000f8 0x000f8 R 0x1 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 08 .init_array .fini_array .jcr .dynamic .got |
프로그램 헤더는 다음과 같은 구조를 가집니다. 이는 readelf -l로 표시되는 프로그램 헤더의 각 행에 해당 하며 예제 바이너리에는 9개의 프로그램 헤더가 존재하는 것을 확인할 수 있습니다.
ElfN_Word p_type; /* Segment type * / ElfN_Off p_offset; /* Segment file offset * / ElfN_Addr p_vaddr; /* Segment virtual address */ ElfN_Addr p_paddr; /* Segment physical address */ ElfN_Word p_filesz; /* Segment size in file * / ElfN_Word p_memsz; /* Segment size in memory * / ElfN_Word p_flags; /* Segment flags * / ElfN_Word p_align; /* Segment alignment */ |
타입(p_type)에는 다음과 같습니다.
P_type |
값 |
설명 |
PT_LOAD |
1 |
로드된 프로그램 세그먼트 |
PT_DYNAMIC |
2 |
동적 링크 정보 |
PT_INTERP |
3 |
프로그램 인터프리터 (일반적인 실행 파일에서는 동적 링커를 의미) |
PT_NOTE |
4 |
추가 정보 |
PT_PHDR |
6 |
프로그램 헤더 테이블 자신 |
PT_TLS |
7 |
스레드 지역 저장소 |
PT_GNU_EH_FRAME |
0x6474e550 |
GNU .eh_frame_hdr 세그먼트 |
PT_GNU_STACK |
0x647e551 |
스택 실행 가능성 |
INTERP의 정보를 hexdump를 이용해 확인해보자. 프로그램 헤더 테이블 통해 확인 INTERP의 offset은 0x154이며 옵션을 이용해 출력하면 아래의 정보를 확인할 수 있다. hello바이너리는 /lib/ld-linux.so.2 동적 라이브러리를 사용하는것을 확인할 수 있다.
$ hexdump -C -s 0x154 -n 20 hello 00000154 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 78 2e 73 6f |/lib/ld-linux.so| 00000164 2e 32 00 00 |.2..| 00000168 |
Section Header
섹션 헤더는 readelf 의 -S 옵션( --section-headers)으로 표시된다.
$readelf -S hello There are 30 section headers, starting at offset 0x1154: 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 08048154 000154 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048168 000168 000020 00 A 0 0 4 [ 3] .note.gnu.build-i NOTE 08048188 000188 000024 00 A 0 0 4 [ 4] .gnu.hash GNU_HASH 080481ac 0001ac 000020 04 A 5 0 4 [ 5] .dynsym DYNSYM 080481cc 0001cc 000050 10 A 6 1 4 [ 6] .dynstr STRTAB 0804821c 00021c 00004a 00 A 0 0 1 [ 7] .gnu.version VERSYM 08048266 000266 00000a 02 A 5 0 2 [ 8] .gnu.version_r VERNEED 08048270 000270 000020 00 A 6 1 4 [ 9] .rel.dyn REL 08048290 000290 000008 08 A 5 0 4 [10] .rel.plt REL 08048298 000298 000018 08 A 5 12 4 [11] .init PROGBITS 080482b0 0002b0 000023 00 AX 0 0 4 [12] .plt PROGBITS 080482e0 0002e0 000040 04 AX 0 0 16 [13] .text PROGBITS 08048320 000320 000192 00 AX 0 0 16 [14] .fini PROGBITS 080484b4 0004b4 000014 00 AX 0 0 4 [15] .rodata PROGBITS 080484c8 0004c8 000014 00 A 0 0 4 [16] .eh_frame_hdr PROGBITS 080484dc 0004dc 00002c 00 A 0 0 4 [17] .eh_frame PROGBITS 08048508 000508 0000b0 00 A 0 0 4 [18] .init_array INIT_ARRAY 08049f08 000f08 000004 00 WA 0 0 4 [19] .fini_array FINI_ARRAY 08049f0c 000f0c 000004 00 WA 0 0 4 [20] .jcr PROGBITS 08049f10 000f10 000004 00 WA 0 0 4 [21] .dynamic DYNAMIC 08049f14 000f14 0000e8 08 WA 6 0 4 [22] .got PROGBITS 08049ffc 000ffc 000004 04 WA 0 0 4 [23] .got.plt PROGBITS 0804a000 001000 000018 04 WA 0 0 4 [24] .data PROGBITS 0804a018 001018 000008 00 WA 0 0 4 [25] .bss NOBITS 0804a020 001020 000004 00 WA 0 0 1 [26] .comment PROGBITS 00000000 001020 00002b 01 MS 0 0 1 [27] .shstrtab STRTAB 00000000 00104b 000106 00 0 0 1 [28] .symtab SYMTAB 00000000 001604 000430 10 29 45 4 [29] .strtab STRTAB 00000000 001a34 000250 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) |
'Hacking > Binary' 카테고리의 다른 글
Binary@library# 공유 라이브러리 (0) | 2018.02.25 |
---|---|
Binary@library# 정적 라이브러리 (0) | 2018.02.25 |
Binary@ELF# ldd - 공유 라이브러리 의존관계 확인 (0) | 2018.02.25 |
Binary@ELF# nm - 오브젝트 파일에 포함된 심볼 확인 (0) | 2018.02.17 |
How main() is executed on Linux (0) | 2017.05.29 |