ELF 란 용어를 많이 들어보셨을텐데요, ELF는 Executable and Linking Format의 약어입니다. UNIX / LINUX 기반에서 사용되는 실행 및 링킹 파일 포맷입니다. 지난 글에 이어 이번 글에서는 ELF 파일 포맷에서 Section 과 Section Header Table에 대해 알아보겠습니다.
[이전 글]
2018/08/27 - [Linux/Debugging & Testing] - [ELF] ELF Header
2018/08/29 - [Linux/Debugging & Testing] - [ELF] Segment와 Program Header
- Section Header Table
Section Header Table은 ELF file의 거의 모든 파트(?)에 대한 정보가 들어있습니다. '거의 모든' 이라고 말씀드린 이유는 ELF Header, Program Header Table, Section Header Table 이 3가지에 대한 정보는 포함되어 있지 않기 때문입니다. Section Header Table이란 이름에서 조금 감이 오셨을 텐데요, ELF을 구성하는 각기 다른 Section들을 정의하는 Section Header 구조체가 연속된 메모리에 나열되어 있기 때문입니다. 그럼 Section Header와 관련된 구조체를 보겠습니다.
section name, type, flags, virtual address 등 다양한 정보, 즉 Section에 대한 메타데이터를 가지는 녀석임을 쉽게 파악할 수 있습니다. 이런 Section Header의 위치가 어디에 나타나 있는지 기억하시나요? ELF Header에 program header와 함께 Section Header에 대한 정보도 있었던 것 같은데.. 기억나시나요? 다시 한번 살펴보겠습니다. 아래 그림은 readelf 툴로 ELF header를 살펴본 내용입니다. 하늘색 박스로 된 부분이 보이시나요?
Start of section headers, Size of section headers, Number of section headers 란 녀석을 집중적으로 보면 될 것 같습니다. 해석해 보면 Section Header들의 첫 시작은 ELF 파일의 시작주소로 부터 384byte 떨어진 곳부터 시작을 하는군요, Section Header의 사이즈는 64 byte이며 총 13개의 section headers들이 있습니다. 정리가 되시나요? 384 byte 떨어진 지점부터 시작한다는 건 그 중간에 어떠한 데이트들이 있단 얘기인데요, 앞에서 살펴본 ELF Header나 Program Header등이 중간에 차지하고 있겠죠?
Section의 메타데이터를 가지고 있는 Section Header에 대해 알아보았으니 그럼 이제 Section에 대해 살펴보겠습니다. 먼저 Section에 집중하기 전에 Section Format에 대해 알아보겠습니다. Section에는 2가지 형태의 Format이 존재합니다. String Table Format과 Symbol Table Format입니다.
String Format Table
- ELF file에서 사용되어 지는 모든 문자열의 리스트들을 나타내는 형태입니다. ELF file에는 dynamic symbol table, main symbol table, section header names와 같은 String Format Table이 존재합니다.
- Format은 아래와 같습니다.
\0 \0<string3>\0.... \0\0 Symbol Table Format
- 함수, 정적/전역 변수 그리고 다른 심볼 타입을 나타내기 위한 ELF 심볼 구조체의 집합입니다. Dynamic Symbol Table와 Main Symbol Table 두 가지로 또 다시 구분이 가능합니다.
- Dynamic Symbol Table은 ELF object에서 여러 심볼 정보들을 런타임에 찾기위해 사용하는 Table입니다.
- Main Symbol Table은 링킹 타임에 사용되는 정적 심볼 정보들입니다.
이제 Section에 대해 정리해 보겠습니다. 복잡하지 않도록 최대한 단순하게 정리해보려 합니다.
.bss section
- 초기화 되지 않은 전역 변수가 위치하는 섹션
.data section
- 초기화 된 전역, 정적 그리고 쓸수있는(writable) 변수들이 위치하는 섹션
.dynamic section
- dynamic linking에 대한 정보가 위치하는 섹션
.dynsym section
- 프로그램 실행에 필요한 심볼들과 전역 심볼들이 위치하는 섹션 (정적 심볼은 포함하지 않음)
.fini section
- 함수 __fini()를 위한 Instruction이 위치한 섹션
.init section
- 함수 __init()을 위한 instruction이 위치한 섹션
.interp section
- 프로그램 인터프리터의 경로명이 위치한 섹션
.rodata section
- 오직 읽기(read-only)만 가능한 const 값, 문자열 상수 등 constant 데이터가 위치하는 섹션
.shstrtab
- 여러 섹션들의 섹션 이름들이 위치하고 있는 String Table
.strtab
- Main symbol table을 위한 심볼 이름들이 위치하고 있는 섹션
.symtab
- 모든 정적 함수와 변수를 포함한 모든 Symbol table의 정보가 위치하는 섹션
.text
- ELF 파일의 실행가능한 코드들이 위치하고 있는 섹션
.got section(Global Offset Table)
- data 섹션에 있는 주소들의 테이블로 position-independent code를 위해 필요로 함. 좀 더 상세한 부분은 추후 다룰 예정
.hash section(Symbol hash table)
- ELF은 정확한 심볼을 찾기위해 다양한 심볼 테이블 이름들을 찾기위한 빠른 방법이 구현되어 있어야 합니다. 그 방법으로 HashTable을 사용하게 됩니다. 아래에 해당 HashTable이 어떻게 동작하는지 간략화한 그림이 있습니다. 상세한 내용은 기회가 된다면 나중에 설명들리겠습니다.
.plt section (Procedure Linkage Table)
- 주소공간에서 함수들을 찾는데 도움을 주는 기능들의 Instruction 리스트가 위치하는 섹션
.rel (relocation section)
- 주소 공간에서 shared library들이 로드될 수 있도록 prefix된 섹션.
ELF Section들과 Section Header Table에 대해 간략히 알아보았습니다. 각 섹션에 대해 상세한 내용을 분석하여 설명드리고 싶지만, 한번에 너무 많은 내용을 설명드리는 건 좋지 않을 것 같아, 추후에 심화적으로 분석하는 글을 작성하도록 하겠습니다.
감사합니다.
[참고자료]
Tool Interface Standards – Portable Formats Specification, Version 1.1
Self-Service Linux , MarkWilding and Dan Behman
How To Write Shared Libraries, Ulrich DrepperLinking, Randy Bryant and Dave O’Hallaron
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
http://man7.org/linux/man-pages/man5/elf.5.html
http://egloos.zum.com/recipes/v/5010841
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
'Linux > Debugging & Testing' 카테고리의 다른 글
[ELF] Symbol Resolution (2) | 2018.09.09 |
---|---|
[ELF] Stripping an ELF object (0) | 2018.09.09 |
[ELF] Segment와 Program Header (1) | 2018.08.29 |
[ELF] ELF Header (0) | 2018.08.27 |
[커널분석] Architecture 별 분석을 위한 설정 (ctags & cscope) (0) | 2018.08.21 |