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 --0x154 -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)
 




























+ Recent posts