관리 메뉴

IT창고

System 컴파일 본문

보안/System

System 컴파일

방구석여포 2018. 1. 11. 21:47

시스템에 대해 알아보기 위하여 바이너리에 대해 알아야 합니다.


바이러리는 실행파일 즉 0과1로 구성된 기계어로 구성된 파일입니다.


바이너리에 대해 알기 위해서 실행파일을 만드는 법을 알고 반대로 만들어진 실행파일에서 어셈블러 언어를 알고 어셈블러 언어를 소스파일로 바꾸는걸 리버싱이라 합니다.


소스파일을 어셈블러로 바꾸는 과정을 컴파일이라고 합니다. 소스파일이 바이너리파일로 변하는 과정에 대해 알아보겠습니다. 

테스트에 리눅스에서 기본으로 제공하는 컴파일러 GCC 편집기는 vim을 사용합니다.



간단한 출력c파일을 만들고 GCC컴파일러를 사용합니다.


만든 파일은 test.c 파일로 간단히 gcc test.c를 입력하면 컴파일되서 바이너리 파일을 만들어줍니다.


a.out 파일을 실행시켜보면 정상적으로 출력됨을 확인할수 있습니다.


gcc에는 옵션이 있는데 그중 몇가지를 알아보겠습니다.


-o 옵션은 실행파일의 이름을 지정할수있습니다.

-v 옵션은 컴파일의 진행과정을 확인할수있습니다.

-g 옵션은 컴파일시 디버깅의 정보를 포함합니다.


그외의 옵션에 대해 알고싶다면 gcc --help를입력하면 도움말이 나옵니다. 여기서 옵션 정보를 확인할수있습니다.


컴파일 진행과정 정보를 확인해보겠습니다.



컴파일되는 과정은 전처리 -> 컴파일 -> 어셈블로 -> 링커 순서로 진행이 됩니다.


전처리 단계는 cpp(C preprocess)사용하며 매크로 헤더파일 등을 해석합니다.

컴파일 단계는 cc1를 사용하며 어셈블리 언어로 변환해줍니다.

어셈블로 단계는 as를 사용하며 목적파일(바이너리)를 생성합니다.

링커 단계는 collect2(혹은 ld)를 사용합니다.


as는 오래된 프로그램으로 현재는 as보다 nasm을 주로 사용합니다.


컴파일이 진행되면서 /tmp 디렉토리에 임시파일을 만드는데 컴파일이 모두 끝나면 /tmp 디렉토리에 임시파일들이 사라집니다.



GCC의 -save-temps 옵션을 사용하여 임시파일들이 지워지지 않고 확인할수있습니다.


.i확장자 파일이 전처리 단계에서 생기는 파일입니다.



cat으로 test.i 파일을 확인해보면 .c파일과 큰 차이는 없습니다.


차이를 확인해보기 위해서 test.c파일을 조금수정해보겠습니다.



매크로를 추가해보았습니다. gcc -v -save-temps test.c로 다시 컴파일을 해서 임시파일을 저장하고 test.i 파일을 확인해보겠습니다.



define의 임의값이 GSK 대신에 들어간걸 확인할수 있습니다. 이러한 과정을 전처리라고 합니다.


디렉토리에 보면 test.s 파일이 있습니다. .s 확장자는 어셈블파일 입니다. 어셈블 파일은 기계어와 어셈블러가 1:1로 이루어져있습니다.

test.s 파일을 확인해보면 어셈블리어로 되어있음을 확인할수 있습니다. 이 과정이 컴파일 단계입니다.


디렉토리에 보면 test.o 파일이 있습니다.  .o 확장자는 오브젝트 파일 혹은 기계어로 된 파일입니다.



cat으로 확인하면 파일이 깨져보입니다. 바이너리이기 때문에 확인하려면 objdump , xxd 와 같은 바이너리 툴로 확인해야합니다.

xxd는 보여주는 역활만 가능하고 objdump는 objdump --help를 입력하면 옵션의 도움말이 나옵니다.


xxd로 확인하니 안에 내용이 확인이 됩니다. 이 과정이 목적파일을 생성하는 어셈블로 단계입니다.

objdump -x 옵션을 사용한다면 헤더에 자세한 내용을 확인할수있습니다.





어셈블리 프로그래밍에 대해 알아보겠습니다.


어셈블리어는 각각의 세그먼트를 직접 지정해줘야합니다.

모든 실행파일은 메모리에 가서 실행이 됩니다 이걸 프로세스라하는데 리눅스 32bit를 사용하는다는 가정하에 32bit는 4G의 메모리를 사용합니다. 1G는 커널메모리로 정상적인 방법으로는 접근할수없습니다 나머지 3G는 일반 메모리로 그 안에서 3등분 나뉘어 집니다. text영역, data영역, stack영역으로 나뉘어지며 이런 영역을 segment, page 등으로 부릅니다. 실행파일의 구조는 리눅스와 윈도우가 다른데 리눅스는 ELF 윈도우는 PE의 구조를 가집니다.


이번에는 어셈블리어를 사용한 프로그램을 만들어보겠습니다.


먼저 C라이브러리를 이용한 어셈블리 프로그램을 만들어보겠습니다. as 대신 nasm으로 만들겠습니다.

test.asm 파일을 만들고 nasm의 문법으로 작성하였습니다. 


nasm -f elf -o test.o test.asm를 입력하여 .asm파일을 목적파일로 바꿔주고 

gcc -o test test.o 를 입력하여 실행파일로 만들어준후 실행해 봅니다.



이 방법이 C라이브러리를 사용하는 방법이고 이번에는 어셈블리만 사용해서 만들어보겠습니다.



C라이브러리를 사용할때와는 조금 소스가 달라졌습니다.


data segment는 읽기/쓰기가 가능한 메모리 영역으로 프로그램 실행에 필요한 데이터입니다.

text segment는 실행 가능한 메모리 영역(실행권한)으로 주로 실행할 명령어들이 들어있습니다.


 nasm -f elf -o test2.o test2.asm를 입력하여 .asm파일을 오브젝트 파일을 만들어 주고 직접 링크를 해주어야합니다.


링크 단계를 해주면 실행파일이 만들어집니다.

실행파일을 실행하면 정상적으로 실행되는 모습을 확인할수 있습니다.

'보안 > System' 카테고리의 다른 글

System 명령어와 분기문  (0) 2018.01.17
System 어셈블리어 사칙연산  (1) 2018.01.17
System 레지스터(Register)  (0) 2018.01.16
System 어셈블리어  (0) 2018.01.12
System Hacking 실습환경 구성  (0) 2018.01.10
Comments