✔️ ELF(Executable and Linkable Format) 파일 형식
- Linux, Unix 시스템의 표준 바이너리 파일로 Object 파일 및 실행 파일이다.
- Window 시스템에서의 PE 파일 형식이 Linux에서 ELF 파일 형식이다.
- 링커를 거쳐 나온 실행파일이라 생각하면 된다.
디스크에 저장되어 있던 프로그램이 메모리 영역으로 올라가면 컴퓨팅 자원을 사용하여 서비스를 제공해주는 것
ELF에서는 프로그램이 실행될 때 메모리에 올라가야 할 각 부분들을 미리 정리해 관리하다가 실행시 정리된 부분(코드, 전역 데이터, 읽기 전용 데이터 등)을 메모리에 올리게된다.
이렇게 메모리에 올라온 주소 공간의 .text 섹션 (코드 영역)의 명령어를 한 라인씩 실행하며 프로세스가 진행된다.
✔️ ELF 파일 구조
ELF 파일은 ELF Header + Program header table + Section header table로 구성된다.
명칭 | 설명 |
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 | 스트링 테이블을 정보 |
🔗 참고
'Linux' 카테고리의 다른 글
[Linux] NFS(Network File System) (0) | 2022.03.21 |
---|---|
[Linux] SELinux (Security Enhanced Linux) (0) | 2022.03.20 |
[Linux] DataBase (MariaDB) 설치 및 설정 (0) | 2022.03.11 |
[Linux] HTTPS (HTTP Secure), openssl (0) | 2022.03.11 |
[Linux] 가상 호스트 (Virtual Hosts) (0) | 2022.03.11 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!