농소

2. 컴파일 과정, ELF 실행파일 본문

Security/System Hacking

2. 컴파일 과정, ELF 실행파일

농소 2018. 1. 12. 02:41


컴파일러 란? - 컴퓨터가 이해할 수 있게 고급언어를 기계어로 변환해주는 작업


(쉬운 환경)

  - IDE (Intergrated Development Enviroment) : 통합 개발 환경

  - IDE = 컴파일러 + 편집기 + 디버거 + 등등..

  - ex) Visual Studio, Eclipse


(불편한 환경)

 현재 linux에서 사용하는것들 

  - compiler : GCC(컴파일러)   GCC = hello.c [ .c<-- ]   gcc hello.c

  - editor : VI 편집기     

  - debugger : GDB

  - 이 세개를 합치면 IDE


우리는 이러한 불편한 환경을 통해서 시스템의 구조를 파악해 나아간다.


1.컴파일 과정


hello.c(소스파일) -> hello.i -> hello.s -> hello.o


우선 간단한 hello, world를 표현하는 코드를 작성후 그 파일을 hello.c라고 치겠다

#> gcc -o hello hello.c 라고 입력을 하면 소스파일이 컴파일과정을 거쳐서 실행파일로 변환이 되는데

이 변환과정을 자세히 보기 위해

#> gcc -v -save-temps hello.c라고 입력하여 컴파일 과정을 살펴보겠다. 


1) 전처리 단계 : cpp (  C PreProcess  )


hello.c -> hello.i


-  전처리에서는 예를 들어 c언어에서 #include,#define 같은 지시문의 값을 치환해서 가져온다.


< cpp명령으로 지시문들을 치환하여 값을 가져와 전처리과정을 마무리하고 hello.i로 저장한다. >


2) 컴파일 단계 : cc1


hello.i -> hello.s


-  전처리 과정후 컴파일하여 c언어를 어셈블 언어로 변환한다.


< hello.i를 컴파일하여 어셈블 언어로 변환하여 hello.s로 저장한다. >


3) 어셈블로 단계 : as


hello.s -> hello.o 


-  목적파일(object file) 생성 

-  어셈블 언어를 이진언어로 변환해주는 과정


< 어셈블 언어를 이진언어로 변환하여 hello.o에 저장 >


이진언어 hello.o를 cat해보면 깨져서 추출되는데 printf같은걸 사용했을 때

 해당 라이브러리가 없기때문에 깨짐현상이 발생한다.

이를 해결하기 위해선 라이브러리를 합쳐야 하는데 그것을 4단계인 링커단계에서 수행한다.



4) 링커 단계 : ld , collect2


hello.o -> hello( 실행파일 )


-  여러개의 목적파일을 묶어서 하나의 프로그램을 만드는 과정

-  .o 파일은 링커에 의해 표준 라이브러리와 링크되어 실행파일(.exe)가 만들어지게 됨.


< 실행파일을 생성하는 과정 >


* 원래 gcc 옵션중에 -save-temps기능을 사용안하면 .i, .s, .o 파일들이 /tmp 에서 임시파일로 생성된 후 ,컴파일 후에 파일이 자동으로 삭제된다.


2.실행파일


각 운영체제별로 실행파일의 구조가 다르다

그렇기 때문에 예를들어 윈도우 실행파일을 리눅스에서 사용할 수 없다.

그래서 프로그램을 다운받을때 윈도우, 리눅스, 유닉스 전용파일 따로 있는게 바로 이러한 이유 때문. 


또, OS는 디스크에서 파일을 쉽게 찾기위해 특정 구조로 만들었는데


OS별 실행파일 종류

Linux : ELF

Window : PE

Unix : COFF


예를들어 LINUX의 경우의 흐름도


디스크(disk)에 있는 파일( =Program )을 os가 쉽게 찾기위해 elf구조로 만듬

 -> OS 시스템 콜에 의해 -> 메모리(ram)에 적재하여 실행


Linux의 경우 실행파일 확인 방법


1. file <실행파일>


< linux 실행파일을 확인해 본 장면 >


-  또, xxd명령어를 통해서도 elf파일인지 확인할 수 있는데 이는 16진수와 ascii형태로 볼 수 있다.


2. xxd <실행파일>


< xxd명령어로 확인해 본 모습 16진수로 표현된 7f45 4c46이 ELF인것을 확인할 수 있다. >