일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- Android
- HOS
- pwndbg
- 계산기
- windows kernel
- kernel debug
- brop
- kaslr
- return to libraty
- sgerrand
- RAO
- dangling pointer
- house of force
- elf 헤더
- WinDBG
- ioploaddrivers
- canary leak
- PLT
- JOP
- libc-database
- libc.so
- cmake
- randtbl
- windows
- frida-dump
- ntwritefile
- SCP
- top chunk
- patchelf
- fastbin
- Today
- Total
sh711 님의 블로그
ELF 헤더 분석 본문
1. ELF 파일
ELF(Executable and Linkable File) 파일이란 리눅스 및 유닉스 계열 운영체제에서 실행 파일, 오브젝트 파일, 공유 라이브러리 및 코어 덤프 파일을 위한 표준 포멧이다.
ELF 파일은 크게 다음과 같은 구조로 이루어져 있다.
- ELF Header => 파일의 전체적인 정보를 담고 있음
- Program Header => 실행 가능한 세그먼트 정보 (실행 파일에 존재)
- Section Header => 개별 섹션 정보 (오브젝트 파일에 존재)
- Segment Data => 실제 프로그램 코드 및 데이터
- Section Data => 개별 섹션 데이터 (.text, .data, .bss 등)
이 중에 ELF Header는 파일의 가장 첫 부분에 위치하며, 파일의 전체적인 구조 및 속성을 나타낸다
ELF 헤더 구조체 정보
typedef struct {
unsigned char e_ident[16]; // ELF 매직 넘버 및 파일 식별자
uint16_t e_type; // 파일 타입 (실행 파일, 오브젝트 파일 등)
uint16_t e_machine; // CPU 아키텍처 정보
uint32_t e_version; // ELF 버전
uint64_t e_entry; // 프로그램의 진입점(Entry Point) 주소
uint64_t e_phoff; // 프로그램 헤더 테이블 오프셋
uint64_t e_shoff; // 섹션 헤더 테이블 오프셋
uint32_t e_flags; // 프로세서 관련 플래그
uint16_t e_ehsize; // ELF 헤더 크기
uint16_t e_phentsize; // 프로그램 헤더 크기
uint16_t e_phnum; // 프로그램 헤더 개수
uint16_t e_shentsize; // 섹션 헤더 크기
uint16_t e_shnum; // 섹션 헤더 개수
uint16_t e_shstrndx; // 섹션 이름 문자열 테이블 인덱스
} Elf64_Ehdr;
1. e_ident (16bytes)
매직넘버를 포함한 파일 속성을 나타낸다
오프셋 | 크기 | 내용 |
0x00 | 4 | Magic Number |
0x04 | 1 | 클래스 (32비트 : 1, 64비트 : 2) |
0x05 | 1 | 데이터 인코딩 (리틀엔디안 : 1, 빅엔디안 : 2) |
0x06 | 1 | ELF 버전 (현재 1) |
0x07 | 1 | OS 및 ABI 정보 |
0x08 | 8 | 예약 (0으로 채움) |
Magic Number
파일 종류 | Magic Number |
ELF(Executable and Linkable File) | 0x7F 45 4C 46 |
Windows PE(Portable Executable) | 0x4D 5A |
MS-DOS EXE | 0x4D 5A |
Mach-O | 32bit : 0xFE ED FA CD, 64bit : 0xFE ED FA CF |
2. e_type (2bytes)
ELF 파일의 타입을 정의한다
값 | 의미 | 설명 |
0x0000 | ET_NONE | 미정의(Unknown) ELF 파일 |
0x0001 | ET_REL | Relocatable 파일 (링킹 전 오브젝트 파일 .o) |
0x0002 | ET_EXEC | 실행 가능한 ELF 파일 (바이너리 실행 파일) |
0x0003 | ET_DYN | 공유 라이브러리 (.so) 또는 PIE 실행 파일 |
0x0004 | ET_CORE | 코어 덤프(.core) 파일 |
3. e_machine (2bytes)
어떠한 CPU 아키텍처에서 실행되는지 나타낸다
값 | 의미 |
0x03 | x86 (Intel 80386) |
0x3E | x86_64 (AMD64) |
0x28 | ARM |
0xB7 | AArch64 |
4.e_entry (8bytes)
프로그램이 실행될 때 첫 번째로 실행되는 주소를 의미하며 일반적으로 .text 섹션(코드 영역) 내의 주소를 가르킨다
4.e_phoff (8bytes)
프로그램 헤더 테이블이 파일 내에서 어디서 시작하는지를 나타낸다
오브젝트 파일에는 존재하지 않을 수 있다
5. p_shoff (8bytes)
ELF 파일에서 섹션 헤더 테이블이 위치하는 파일 오프셋을 가르킨다
6. e_flags (4bytes)
CPU 아키텍처 플래그를 나타내며 x86에서는 일반적으로 0x0이지만 ARM이나 MIPS 등에서는 다른 값이 될 수 있다
7. e_ehsize (2bytes)
ELF 파일의 헤더의 크기를 나타낸다
8. e_phentsize & e_phnum (각각 2bytes 씩)
- e_phentsize : 프로그램 헤더 엔트리 하나의 크기
- e_phnum : 프로그램 헤더 테이블의 엔트리 개수
9. e_shentsize & e_shnum (각각 2bytes 씩)
- e_shentsize : 섹션 헤더 테이블의 각 엔트리 크기
- e_shnum : 섹션 헤더 테이블의 엔트리 개수
10. e_shstrndx (2bytes)
섹션 헤더에서 섹션 이름을 저장하는 .shstrtab 섹션의 인덱스를 나타낸다
2. 파일 식별
readelf를 통한 헤더 정보 식별
readelf -h test
xxd를 통해 실제 바이너리 값 확인
xxd -l 100 test
헤더를 통해 알 수 있는 것은 다음과 같다
1. ELF 포멧 => 0x7f 45 4c 46
2. 64비트 => 0x2
3. 리틀엔디안 => 0x1
4. ELF 버전 => 0x1
5. 파일 타입 => ET_DYN
6. 실행 아키텍처 => x86_64
7. entry point => 0x1050
8. 헤더 테이블 시작 지점 => 0x40
9. 섹션 헤더 테이블 오프셋 => 0x3690
10. 아키텍처 플래그 => 0x0
11. ELF 헤더 크기 => 0x40
12. 프로그램 헤더 엔트리 하나의 크기 => 0x38
13. 프로그램 헤더 테이블의 엔트리 개수 => 0xd
14. 섹션 헤더 테이블의 각 엔트리 크기 => 0x40
15. 섹션 헤더 테이블의 엔트리 개수 => 0x1f
16. .shstrtab 인덱스 => 0x30
'Study > Linux' 카테고리의 다른 글
Linux Kernel - 1 (0) | 2025.03.26 |
---|---|
srandom_r & random_r (1) | 2025.03.20 |
House of Force - 1 (0) | 2025.03.11 |
Return to Library (0) | 2025.03.01 |
Stack Buffer Overflow & Stack Canary (0) | 2025.02.26 |