Sh4n3e

ELF(Excutable and Linkable Format)? 본문

System Hacking

ELF(Excutable and Linkable Format)?

sh4n3e 2017. 6. 27. 11:00

ELF는 위에서 써놨듯이 Excutable and Linkable Format의 약자이다. 약자를 해석해보자면, 실행가능하고, 링킹가능한 포멧의 파일이란 의미이다.

해당 파일은 많이들 봤듯이, Linux의 실행파일을 file이란 명령어를 통해 많이 봐왔을 것이다.

그럼 도대체 이 파일은 어떤 파일인지, 어떤 구조를 가지고 있는지 간단히 알아보자.

 

[skeleton@localhost skeleton]$ file golem
golem: setuid setgid ELF 32-bit LSB executable, Intel 80386, version 1, dynamically linked (uses shared libs), not stripped
[skeleton@localhost skeleton]$ file g.so
g.so: ELF 32-bit LSB shared object, Intel 80386, version 1, not stripped

 

file이란 명령어를 통해 파일에 golem이란 파일과 g.so파일에 대해서 한번 살펴봤다. 해당 파일은 ELF 32-bit 실행가능한 파일과 공유 오브젝트 파일임을 알 수 있었다.(해당 ELF파일을 좀더 정확히 보려면 readelf 명령어를 사용한다.)

그럼 실행가능한 파일은 뭐고? 공유 오브젝트는 뭔지?? 그것에 대해 점차 알아보도록 하겠다.

 

우선 실행파일이 뭔지? 에 대해서 알아보자.

실행이란것은 디스크에 저장되어있던 프로그램이 메모리영역에 올라가서 컴퓨팅자원을 사용하여 서비스를 제공해주는 것이다. 이렇게 실행중인 프로그램은 프로세스라는 이름으로 불린다. 이런 프로세스들은 가상의 주소공간을 갖는 메모리 영역이 주어진다.

이런 영역을 쉽게 말하면 세그먼트라고 할 수 있는데, ELF에서는 프로그램이 실행될때 메모리에 올라가야될 각각의 부분들을 미리 정의하여 관리하고 있으며, 이 것은 실행명령어와 동시에 정의되어 있는 부분을 메모리에 올리게 되는것이다.

이렇게 메모리 영역에 올라간 .text영역(코드 영역)에 존재하는 명령어(Instrument)들을 Line by Line으로 실행하며 프로세스는 동작한다.

 

그럼 다음으로 공유 오브젝트가 무엇인지 알아보자. 이 개념을 알아보기 위해서는 링킹이라는 개념에 대해서 알아야 한다.

링킹이라는 것은 사용할 라이브러리를 실행가능 프로그램에 적재하는 개념인데, 아래와 같이 세분화해서 나눠볼 수 있다.

 

리눅스 라이브러리 => 정적 라이브러리(Static), 공유 또는 동적 라이브러리(Shared)

Shared => 공유 라이브러리, 동적 라이브러리

 

이것을 좀더 보기 쉽게 보여주자면 아래와 같다.

 

종류 

 적재 시기

 사용 방식

 Static Library

 컴파일 시간

 컴파일 시 라이브러리를 적재한 해당 프로그램만 라이브러리 코드를 사용함.

 Dynamic Linking

 런타임 시간(프로그램 메모리에 적재시)

 메모리에 라이브러리가 적재되어 있다면, 그 라이브러리를 사용하는 프로그램끼리 그 메모리 영역을 공유함.

 Dynamic Loading 

 런타임 시간(프로그램 실행중 필요할 때)

 메모리에 라이브러리가 적재되어 있다면, 그 라이브러리를 사용하는 프로그램끼리 그 메모리 영역을 공유함.

 

정적 라이브러리의 경우, 컴파일시 라이브러리들을 모두 프로그램내에 적재하기 때문에 속도에서 장점을 가지지만, 필요한 코드들을 모두 프로그램 내에 적재하기 때문에, 프로그램의 크기가 엄청나게 커진다. 또한. 프로그램 패치나 재배포시에 불리한 점을 가진다.

 

공유 라이브러리의 경우, 해당 프로그램이 시작되는 순간에 적재하여 사용한다. 이 것은 해당 공유 라이브러리를 사용하는 다른 프로그램이 이미 실행되어 있다면(해당 라이브러리를 사용중이라면) 그 것을 참조해서 링킹한다. 하지만 없다면 라이브러리를 메모리에 올리고 링킹하게 된다. 공유 라이브러리는 프로그램 변경시 변경된 부분의 공유 라이브러리만 재배포하면 되기 때문에, 정적 라이브러리에 비해 프로그램 패치나 재배포시에 매우 유리한 점을 가진다. 하지만 공유 라이브러리를 메모리에 올리려면 찾고 올려야 하기 때문에, 성능저하의 부분을 감수해야 한다.

 

동적 라이브러리의 경우, 동적 적재라고도 부르는데 프로그램 도중 응용프로그램에서 특정 라이브러리를 사용할지 말지를 결정한다. 장점과 단점의 경우 공유 라이브러리와 동일하다.

 

그럼 다시 돌아와서 ELF파일에 대해서 좀 더 자세히 알아보자.

해당 ELF파일은 크게 3가지로 나눠볼 수 있다.

1. 재배치 가능한 파일(Relocable file) : 해당 파일은 링킹 가능한 파일로, 링크를 쉽게 할 수 있는 코드 및 데이터와 함께, 실행 파일을 만들거나 공유 Object파일을 생성하기 위해 다른 Object파일을 가지고 있는 형태의 파일이다.

2. 실행 가능한 파일(Executable file) : 해당 파일은 실행 가능한 파일로, 실행을 위해 적합한 구조를 가지는 파일이다. exec 시스템 콜이 어떻게 프로세스의 이미지를 프로그램을 이용해서 만들지를 기술하는 파일이다.

3. 공유 오브젝트 파일(Shared object file) : 실행 가능하면서 링킹가능한 파일로, 링크에 적합한 형태의 코드와 데이터를 가지는 파일로서, LD와 같은 링크 에디터가 이 파일과 함께, 다른 재배치 가능한 파일과 공유 Object파일을 처리해서 또 하나의 Object 파일을 생성해주게 되고, 이를 다시 동적 링커가 생성된 Object 파일을 실행 가능한 파일과 다른 공유 Object파일을 묶어서 프로세스의 이미지를 생성해주는 두 단계를 거치는 파일이다.

 

이제는 ELF파일의 구조에 대해서 알아보자.

ELF파일은 크게 ELF Header, Program Header Table, Section Header Table로 나눠볼 수 있다.

ELF Header는 실행가능한 파일이던지, 링킹가능한 파일이던지 무조건 가지는 부분이다. 이 부분은 현재 ELF에 대한 정의가 들어가 있으며, Program Header Table과, Section Header Table의 위치를 저장하고 있다.

Program Header Table은 실행가능한 파일에만 존재하며, 공유 Object 파일에도 존재한다. 해당 테이블은 세그먼트의 타입, 파일 오프셋, 물리주소, 가상주소, 메모리 이미지 크기, 정렬방식등을 정의한다.

Section Header Table의 경우는 링크 가능한 파일에만 존재하며, 공유 Object 파일에도 함꼐 존재한다. 해당 테이블은 섹션들의 이름, 메모리, 시작주소, 파일 오프셋, 크기, 정렬방식, 표현방식등을 정의한다. 여기서 나타날 수 있는 섹션들은 아래와 같다.

.bbs

.comment

.data and .data1

.debug

.dynamic

.dynstr

.dynsym

.fini

.got

.hash

.init

.interp

.line

.note

.plt

.rel.dyn

.relname and .relaname

.rodata and .rodata1

.shstrtab

.strtab

.symtab

.text

 

 

 

'System Hacking' 카테고리의 다른 글

Shared Library Hijacking  (0) 2017.06.26
Comments