Linux

[Linux] ELF(Executable and Linkable Format) 파일 형식

TTOII 2022. 3. 12. 22:43
728x90

✔️ ELF(Executable and Linkable Format) 파일 형식 

  • Linux, Unix 시스템의 표준 바이너리 파일로 Object 파일 및 실행 파일이다. 
  • Window 시스템에서의 PE 파일 형식이 Linux에서 ELF 파일 형식이다. 
  • 링커를 거쳐 나온 실행파일이라 생각하면 된다.

디스크에 저장되어 있던 프로그램이 메모리 영역으로 올라가면 컴퓨팅 자원을 사용하여 서비스를 제공해주는 것

ELF에서는 프로그램이 실행될 때 메모리에 올라가야 할 각 부분들을 미리 정리해 관리하다가 실행시 정리된 부분(코드, 전역 데이터, 읽기 전용 데이터 등)을 메모리에 올리게된다. 

 

이렇게 메모리에 올라온 주소 공간의 .text 섹션 (코드 영역)의 명령어를 한 라인씩 실행하며 프로세스가 진행된다.

 

✔️ ELF 파일 구조

ELF 파일은 ELF Header + Program header table + Section header table로 구성된다.

https://rmagur1203.tistory.com/28

명칭 설명
ELF Header  파일의 구성을 나타내는 로드맵과 같은 역할 
ELF 파일 포맷임을 표시하는 magic number, 이미지의 형태(.o, .exec, .so)
실행되는 CPU 정보, Little-endian인지 Big-endian인지 표시하는 Byte 순서와 같은 파일 내용의 기본적인 정보를 포함한다.
Program Header Table 실행 파일의 메모리 구조 내용을 표시
ELF에서는 Segment로 알려진 내용을 Section으로 정의한다.
이 테이블에서는 어떠한 Section이 존재하는지 그 Section의 정보가 있는 곳이 어딘지 등을 가지고 있다.
프로세스의 이미지를 만들기 위해 사용되는 파일은 반드시 프로그램 헤더 테이블을 가져야하며 재배치 가능 파일의 경우에는 없어도 된다. 
Section Linking을 위한 Object 파일의 정보를 다량으로 가지고 있으며 명령, 데이터, 심볼 테이블, 재배치 정보 등이 담겨있다.
Section Header Table 파일의 섹션들에 대해 알려준다. 
모든 섹션은 이 테이블에 섹션 이름이나 크기 같은 정보를 제공하는 하나의 entry를 가져야한다.
만약 파일이 Linking하는 동안 사용되면, 반드시 섹션 헤더 테이블을 가져야하며 다른 Object 파일은 가지고 있지 않을 수 있다. (옵션)  

 

1. ELF Header

ELF 파일에 대한 메타 데이터를 제공하는 역할

readelf -h /bin/ls

멤버 설명
Magin(e_ident) 파일 식별 정보를 가지고 있다. 
첫 4 바이트는 "\x7fELF"이며 5번째 바이트에 파일이 32비트 또는 64비트인지를 저장하고, 6번째 바이트에 파일이 리틀 또는 빅엔디언 포맷인지 저장한다.  메모리 덤프를 통해 스캔 및 RAM에 매핑된 ELF 파일의 시작 부분을 찾기 위해 이 특성을 사용할 수 있다.
Class 파일의 클래스나 용량을 나타낸다.
ELFCLASSNONE 0 : Invalid class

ELFCLASS32 1 : 32bit objects
ELFCLASS64 2 : 64bit objects
ELFCLASSNUM 3 : ELF class number
Data 1이면 리틀 엔디안 2면 빅엔디안 
Version 1이면 32비트 2면 64비트 
Data Encoding ELF header version number
e_entry(Type) 파일 유형 (실행, 재배치 이미지, 공유 라이브러리 또는 코어 덤프)을 알려준다.
e_entry(Entry point address) 프로그램 동작시 실행되는 첫 명령의 주소를 가지고 있다. 
e_phoff 프로그램 헤더 테이블의 시작을 가리킨다.
e_shoff 섹션 헤더 테이블의 시작을 가리킨다.
e_phentisize 프로그램 헤더 테이블 항목의 크기
p_phnum 프로그램 헤더 테이블의 항목 수 
e_shentisize 섹션 헤더 테이블의 항목의 크기
e_shstrndx 섹션 이름에 매핑된 문자열의 섹션 헤더 테이블 내의 인덱스를 저장한다. 

 

2. Program Header

readelf -l /bin/ls

프로그램 헤더 테이블은 ELF헤더의 e_phoff로 지정된 오프셋에서 시작하고 e_phentsize와 e_phnum으로 정해진 크기를 갖는 테이블이다. 

다음의 출력 결과는 유형, 로드되는 가상 주소, 디스크상과 메모리상의 크기와 함께 헤더를 보여준다.  이 출력에서 헤더 유형들은 프로그램 헤더의 크기와 위치를 나타내는 PHDR, 사용하기 위한 동적 로더를 나열하는 INTERP, 코드나 데이터와 같이 실행 중 로드되는 어플리케이션의 세그먼트들인 LOAD들이 있다.

멤버  설명
PHDR 프로그램 헤더 테이블 자신의 위치와 크기 정보
INTERP  인터프리터 호출을 위한 내용
LOAD 로드 된 프로그램 세그먼트
DYNAMIC 동적 링크 정보 

 

3. Section Header

readelf -S /bin/ls

ELF 바이너리 파일은 일반적으로 여러개의 섹션으로 나누어져 있다. 

섹션 헤더의 e_shoff 멤버는 섹션 헤더의 엔트리가 시작하는 위치를 알려준다. 

오프셋은 파일 내의 각 섹션을 나타내는 Elf32_Shdr 또는 Elf64_Shdr 구조의 배열이다.

멤버 설명
Interp  interpreter의 경로 명을 가지는 섹션
Hash  symbol hash table을 가지는 섹션
Dynamic  동적 linking 정보를 가지는 섹션
Dynstr  동적 linking을 위해 필요한 스트링들
Plt  procedure(함수)의 링크 테이블
Got.plt global offset table을 가지는 섹션
Text  프로그램의 실행 가능한 명령어 정보
Data  초기화된 데이터를 가지는 섹션
Bss  초기화 되지 않은 데이터를 가지는 섹션
Shstrtab  섹션들의 이름들을 가지는 섹션
Symtab  심볼 테이블을 정보
Strtab  스트링 테이블을 정보

 

 

 

 

🔗 참고 

 

728x90