bunta의 보조기억장치

[3주차 TIL] KnockOn Bootcamp ELF 파일 구조 본문

KnockOn Bootcamp

[3주차 TIL] KnockOn Bootcamp ELF 파일 구조

bunta 2025. 4. 21. 10:50
반응형

💡 ELF 파일이란?

ELF(Executable and Linkable Format) 파일은 Linux나 Unix 계열 운영체제에서 사용되는 실행 파일, 오브젝트 파일, 공유 라이브러리, 코어 덤프 파일의 표준 포맷이다.


🔎 ELF 헤더

헤더는 ELF 파일의 맨 앞에 위치하며 파일이 어떤 종류의 ELF인지, 어떤 구조를 따르는지 등의 정보를 담고 있다.

 

64비트 기준으로 헤더는 다음과 같은 형식으로 구성되어 있다.

typedef struct {
    unsigned char e_ident[16];  // ELF 마법 번호 및 식별 정보
    uint16_t      e_type;       // 파일 타입 (실행파일, 오브젝트파일 등)
    uint16_t      e_machine;    // 아키텍처 (예: x86_64)
    uint32_t      e_version;    // ELF 버전
    uint64_t      e_entry;      // 프로그램 진입 지점 주소
    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;

 

실제로 ELF 파일의 헤더를 조회하는 법은 아래와 같다.

readelf -h binary파일

 

결과 예시)

ELF Header:
  Magic:   7f 45 4c 46 ...
  Class:                             ELF64
  Data:                              2's complement, little endian
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Entry point address:               0x401000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          123456 (bytes into file)
  ...

🔎 ELF 섹션 헤더

섹션 헤더는 ELF 파일을 구성하는 각 섹션의 메타데이터를 담고 있다. 컴파일러, 링커, 디버거가 파일을 분석하거나 조작할 때 해당 정보를 활용한다.

 

64비트 기준으로 섹션 헤더는 다음과 같은 형식으로 구성되어 있다.

typedef struct {
    uint32_t sh_name;       // 섹션 이름 (문자열 테이블 인덱스)
    uint32_t sh_type;       // 섹션 타입 (예: SHT_PROGBITS, SHT_SYMTAB 등)
    uint64_t sh_flags;      // 섹션 속성 (읽기, 쓰기, 실행 등)
    uint64_t sh_addr;       // 메모리 상의 주소 (로드될 경우)
    uint64_t sh_offset;     // 파일 내 오프셋
    uint64_t sh_size;       // 섹션 크기
    uint32_t sh_link;       // 연관된 섹션 인덱스 (심볼 테이블 등에서 사용)
    uint32_t sh_info;       // 추가 정보 (용도는 타입에 따라 다름)
    uint64_t sh_addralign;  // 정렬 기준
    uint64_t sh_entsize;    // 엔트리 크기 (예: 심볼 테이블의 경우 1개 엔트리 크기)
} Elf64_Shdr;

 

실제로 ELF 파일의 섹션 헤더를 조회하는 법은 아래와 같다.

readelf -S binary파일

 

결과 예시)

Section Headers:
  [Nr] Name      Type       Address  Off    Size
  [ 0]           NULL       00000000 000000 0000
  [ 1] .text     PROGBITS   00400000 001000 02fc
  [ 2] .data     PROGBITS   00600000 002000 0010
  [ 3] .bss      NOBITS     00600010 002010 0004
  ...

🔎 ELF 프로그램 헤더

실행 파일이나 공유 라이브러리에서만 사용되는 헤더이며 운영체제가 프로세스를 메모리에 적재할 때 ELF 파일의 어느 부분을 어떻게 적재해야 하는지에 대한 정보를 담고 있다.

 

64비트 기준으로 프로그램 헤더는 다음과 같은 형식으로 구성되어 있다.

typedef struct {
    uint32_t p_type;    // 세그먼트 타입
    uint32_t p_flags;   // 세그먼트 접근 권한 (읽기, 쓰기, 실행)
    uint64_t p_offset;  // 파일 내 오프셋
    uint64_t p_vaddr;   // 가상 주소
    uint64_t p_paddr;   // 물리 주소 (거의 사용 안 함)
    uint64_t p_filesz;  // 파일 내 크기
    uint64_t p_memsz;   // 메모리 내 크기
    uint64_t p_align;   // 정렬 기준
} Elf64_Phdr;

 

실제로 ELF 파일의 프로그램 헤더를 조회하는 법은 아래와 같다.

readelf -l binary 파일

 

결과 예시)

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flags  Align
  LOAD           0x000000 0x00400000          0x00400000        0x001000 0x001000 R E    0x200000
  LOAD           0x001000 0x00600000          0x00600000        0x000200 0x000200 RW     0x200000
반응형
Comments