Post List

elf (Executable and Linking Format)



[정의]
- ELF는 Executable and Linking Format의 약자로 실행 파일, 목적 파일, 공유 라이브러리 그리고 코어 덤프를 위한 X86 기반 유닉스. 유닉스 계열 시스템들의 표준 바이너리 파일 형식.

- ELF 파일은 ELF 헤더가 맨 앞에 위치하고, 프로그램 헤더 테이블과 섹션 헤더 테이블이 그 뒤에 위치한다.

- ELF 파일의 헤더 구조는 elf.h에 저장되어 있다.


[ELF Types]
- ELF 파일 type은 3가지(재배치 파일(relocatable), 실행 파일(execute), 공유 목적파일(shared object))로 구분된다.


[ELF 구조]

* ELF Header
ELF 헤더(header)는 파일의 구성을 나타내는 로드맵(road map)과 같은 역할을 하며, 파일의 첫 부분을 차지한다. (offset 0에 위치)

- readelf -h {FILENAME} 명령으로 확인 가능

- 구조체 정의 (32bit)
typedef struct

unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;

- 구조체 정의 (64bit)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /* Object file type */
Elf64_Half e_machine; /* Architecture */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size in bytes */
Elf64_Half e_phentsize; /* Program header table entry size */
Elf64_Half e_phnum; /* Program header table entry count */
Elf64_Half e_shentsize; /* Section header table entry size */
Elf64_Half e_shnum; /* Section header table entry count */
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;


* Program Header Table
프로그램 로딩에 필요한 바이너리 세그먼트를 정의한다. 세그먼트는 디스크에 저장된 실행 파일이 커널에 의해 로드되는 과정에서 어떤 메모리 구조로 매핑될 것인지 정의한다

ELF 헤더의 e_phoff로 지정된 offset에 위치하며, e_phentsize의 크기와 e_phnum 개수로 정해진 크기를 갖는 테이블이다.

- readelf -l {FILENAME} 명령으로 확인 가능

- 구조체 정의 (32bit)
typedef struct
{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
Elf32_Addr p_vaddr; /* Segment virtual address */
Elf32_Addr p_paddr; /* Segment physical address */
Elf32_Word p_filesz; /* Segment size in file */
Elf32_Word p_memsz; /* Segment size in memory */
Elf32_Word p_flags; /* Segment flags */
Elf32_Word p_align; /* Segment alignment */
} Elf32_Phdr;

- 구조체 정의 (64bit)
typedef struct
{
Elf64_Word p_type; /* Segment type */
Elf64_Word p_flags; /* Segment flags */
Elf64_Off p_offset; /* Segment file offset */
Elf64_Addr p_vaddr; /* Segment virtual address */
Elf64_Addr p_paddr; /* Segment physical address */
Elf64_Xword p_filesz; /* Segment size in file */
Elf64_Xword p_memsz; /* Segment size in memory */
Elf64_Xword p_align; /* Segment alignment */
} Elf64_Phdr;


* Section Header Table
-  파일의 섹션들에 대해서 알려주는 정보를 가지는데, 모든 섹션은 이 테이블에 하나의 엔트리(entry)를 가져야 한다. 각각의 엔트리는 섹션 이름이나, 섹션의 크기와 같은 정보를 제공해 준다. 만약 파일이 링킹하는 동안 사용된다면, 반드시 섹션 헤더 테이블을 가져야하며, 다른 object파일은 섹션 헤더 테이블을 가지고 있지 않을 수도 있다. 

- readelf -s {FILENAME} 명령으로 확인 가능

- 구조체 정의 (32bit)
typedef struct
{
Elf32_Word sh_name; /* Section name (string tbl index) */
Elf32_Word sh_type; /* Section type */
Elf32_Word sh_flags; /* Section flags */
Elf32_Addr sh_addr; /* Section virtual addr at execution */
Elf32_Off sh_offset; /* Section file offset */
Elf32_Word sh_size; /* Section size in bytes */
Elf32_Word sh_link; /* Link to another section */
Elf32_Word sh_info; /* Additional section information */
Elf32_Word sh_addralign; /* Section alignment */
Elf32_Word sh_entsize; /* Entry size if section holds table */
} Elf32_Shdr;

- 구조체 정의 (64bit)
typedef struct
{
Elf64_Word sh_name; /* Section name (string tbl index) */
Elf64_Word sh_type; /* Section type */
Elf64_Xword sh_flags; /* Section flags */
Elf64_Addr sh_addr; /* Section virtual addr at execution */
Elf64_Off sh_offset; /* Section file offset */
Elf64_Xword sh_size; /* Section size in bytes */
Elf64_Word sh_link; /* Link to another section */
Elf64_Word sh_info; /* Additional section information */
Elf64_Xword sh_addralign; /* Section alignment */
Elf64_Xword sh_entsize; /* Entry size if section holds table */
} Elf64_Shdr;



[주요 Section Table 정보]

.Text         : 프로그램 코드 명령어(기계어, 어셈블)가 저장되어있다.

.plt           : 공유 라이브러리에서 import한 함수를 호출하기 위한 정보가 저장되어있다.

.got.plt     : .plt 정보를 통해 얻어진 공유 라이브러리의 함수 포인터가 모두 저장되어 있으며, 해당 섹션을 수정하여 원하는 지점의 명령어를 수행하는
                  공격도 가능하다 (Hooking)

.dynsym   : 공유 라이브러리로부터 import된 동적 및 전역 심볼 정보를 담고 있으며, 런타임시 할당되어 메모리에 로드된다.

.symtab    : .dynsym 섹션, 지역 심볼, 전역 변수 및 지역 함수 등의 모든 종류의 심볼정보가 저장된다.
                   (해당 정보를 통해 static function 추적 및 디버깅이 가능하다.)







댓글 없음:

댓글 쓰기