2009년 7월 3일 금요일

ELF Header

ELF Header 혹은 ELF File Header는 보통 52바이트로 아래와 같이 내용을 살펴 볼 수 있다.

--------------------------------------------------------
Dukeru>readelf -h testApp
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: PowerPC
Version: 0x1
Entry point address: 0x48041110
Start of program headers: 52 (bytes into file)
Start of section headers: 275611 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 28
--------------------------------------------------------

0x0000-0x0003 (EI_MAG) Magic
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
이 파일이 ELF 파일임을 나태냄. 45 4C 46이 ASCII로 E L F임.

0x0004 (EI_CLASS) Class
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
32bit 환경에서 실행되는 ELF파일임을 뜻함.
01: 32bit
02: 64bit


0x0005 (EI_DATA Encoding)
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Data: 2's complement, big endian
이 파일에 데이터가 Big Endian 포맷임.
01: Little Endian
02: Big Endian

0x0006 (EI_VERSION)
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Version: 1 (current)
ELF Header Version을 뜻함. EV_CURRENT가 값으로 사용되며 일반적으로 EV_CURRENT는 1으로 정의되어 있음.

0x0007 - 0x000F (EI-PAD)
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
OS/ABI: UNIX - System V :ABI형식
ABI Version: 0
몇몇 가지 부가 정보가 있으나 일반적으로 모두 0임.

0x0010-0x0011 (E-TYPE)
0000010 00 02 00 14 00 00 00 01 48 04 11 10 00 00 00 34
Type: EXEC (Executable file)
1: Relocatable file
2: Executable file
3: Shared object file
4: Core file

0x0012-0x0013 (E-MACHINE)
0000010 00 02 00 14 00 00 00 01 48 04 11 10 00 00 00 34
Machine: PowerPC
0x03: Intel386
0x14: PowerPC

0x0014-0x0017 (E_VERSION)
0000010 00 02 00 14 00 00 00 01 48 04 11 10 00 00 00 34
Version: 0x1
Object file version
0:Invalid
1:Current version

0x0018-0x001B (E_ENTRY)
0000010 00 02 00 14 00 00 00 01 48 04 11 10 00 00 00 34
Entry point address: 0x48041110
Virtual Address Starting Process, 프로그램의 시작 주소, main이 아니라 _start 함수의 주소임. main은 _start에서 호출된다.

0x001C-0x001F (E-PHOFF) Program Header Offset
0000010 00 02 00 14 00 00 00 01 48 04 11 10 00 00 00 34
Start of program headers: 52 (bytes into file)
파일 시작위치에서 Program Header Table까지의 offset.

0x0020-0x0023 (E-SHOFF) Section Header Offset
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Start of section headers: 275611 (bytes into file)
파일 시작위치에서 Section Header Table까지의 offset.

0x0024-0x0027 (E_FLAGS)
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Flags: 0x0
Process Specific Flags.

0x0028-0x0029 (E_EHSIZE) ELF Header Size.
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Size of this header: 52 (bytes)
ELF header의 크기이면서 Program Header의 시작 위치

0x002A-0x002B (E-PHENTSIZE) Program Header Entry Size
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Size of program headers: 32 (bytes)
Program Header Table의 각 item의 크기. Program Header는 각 Segment당 한개씩 있음.

0x002C-0x002D (E_PHNUM) Program Header Number
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Number of program headers: 6
6개의 Segment, 즉 6개의 Program Header가 있다는 뜻.

0x002E-0x002F (E_SHENTSIZE) Section Header Entry Size
0000020 00 04 34 9b 00 00 00 00 00 34 00 20 00 06 00 28
Size of section headers: 40 (bytes)
Section Header Table의 각 item의 크기.

0x0030-0x0031 (E_SHNUM) Section Header Number
0000030 00 1d 00 1c 00 00 00 06 00 00 00 34 48 04 00 34
Number of section headers: 29
29개의 section header가 있다는 뜻.

0x0032-0x0033 (E_SHSTRNDX) Section Header String Index
0000030 00 1d 00 1c 00 00 00 06 00 00 00 34 48 04 00 34
Section header string table index: 28
Section Header table에서 String section의 header가 있는 index.
E-SHOFF + (E_SHSTRNDX * E_SHENTSIZE) 가 파일에서 String Section의 header의 위치가 된다.

해당 섹션의 이름을 얻는 방법:
원하는 Section Header의 sh_name은 section name이 string section의 시작으로부터 몇바이트 위치에 있는지 offset값을 가지고 있다.
따라서 section header table을 참조해서 string section의 시작주소를 구하고 여기에 sh_name을 더하면 된다. (section header에 대해서는 다음에 자세히 설명한다.)

string section의 시작주소는 section header table에서 구할 수 있다.

따라서 string section header에서 sh_offset을 읽어 원하는 section header의 sh_name을 더하면, 원하는 section의 이름을 얻을 수 있다.

Addr. of a section name = "sh_name" of the section + "sh_offset" of string section

ELF? 엘프?

ELF파일은 유닉스 계열 OS에서 가장 많이 사용되는 실행파일 형식으로 아래와 같은 파일을들이 이 형식을 사용한다.
  • Object file.
  • Executable file.
  • Shared Library.
  • core파일.
.a 확장자를 가지는 일반 Library파일은 단순한 archive파일로 ELF형식이 아니다.

아래 ELF파일의 구조에서 살펴보았듯이 ELF파일은 ELF file header, program header table, sections 그리고 section header table로 구성되어 있다.


ELF file구조 및 readelf 사용법.

ELF file구조
  • ELF file Header
  • Program Header Table
  • Section1
  • Section2
  • ...
  • Section Header Table
- Program Header Table은 오브젝트 파일에서는 optional이다. Program Header는 세그먼트에 대한 정보를 가지고 있는데, 오브젝트 파일은 이러한 정보가 없으므로 Program Header가 필요하지 않다.
- Section Header는 실행파일에서는 optional이다. Section header가 없거나 손상되어도 프로그램의 실행에는 지장이 없으나 이런 파일은 디버거를 사용하여 디버깅을 할 수 없다.

--------------------------------
ELF header
--------------------------------
Program Header 1
-----------------------
Program Header 2
-----------------------
Program Header 3
-----------------------
...
-----------------------
Program Header N
--------------------------------

sections...

--------------------------------
Section Header 1
-----------------------
Section Header 2
-----------------------
...
-----------------------
Section Header M
----------------------------------

readelf사용법
    Usage: readelf elf-file(s)
      Display information about the contents of ELF format files
        Options are:
        • -h Display the ELF file header
        • -l Display the program headers
        • -S Display the sections' header
        • -d Display the dynamic segment (if present)
          부연설명:
          ELF는 unix계열에서 현재 가장 널리 사용되는 실행 파일 포맷이다. a.out과 COFF는 이제 많이 사용되지 않는다. 단, MS Windows계열에서 사용하는 실행 파일 포맷인 PE(Potable Executable) 포맷이 COFF를 약간 수정한것이라고 한다.