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

댓글 없음: