본문 바로가기
보안/리버싱

[리버싱] 02 Binary 와 컴파일 과정 이해

by Nobb 2024. 1. 28.

**개념 preview  ----------------------------------------------------------------------------------

 

- 프로그램 : 컴퓨터가 실행해야 할 명령어의 집합 ( = Binary)

- 소스코드 : cpu가 수행해야할 명령들을 프로그래밍 언어로 작성한 것

 

- 전처리 : 소스코드 --> 컴파일에 필요한 형식      가공 과정

- 컴파일 : 소스코드 --> 어셈블리어      번역 과정

- 어셈블 : 어셈블리코드 --> 기계어      번역 과정

 

- 링크 : 여러 개의 목적파일을 하나로 묶고, 필요한 라이브러리와 연결하는 과정

 

- 디스어셈블 : 바이너리 --> 어셈블리어      번역 과정

- 디컴파일 : 바이너리 --> 고급언어      번역 과정

 

------------------------------------------------------------------------------------------------------------

 

기계어

 : 컴퓨터 과학자들이 컴퓨터에 명령 내리기 위해 정의한 컴퓨터 언어

    - 필요한 연산을 컴퓨터가 대신하도록   기계어로 명령 내림

 

    >> 0,1로만 구성 --> 이해 어려움, 비효율적 --> '어셈블리어'+'어셈블러' 개발

 

 

어셈블리어 (Assembly Lang)
 : 사람이 이해하기 쉬운 새로운 언어
어셈블러
 : 어셈블리어-->기계어    번역기

    >>여전히 규모 큰 프로그램 개발엔 부족 --> '고급언어'+'컴파일러' 개발

 

고급언어

 : 사람이 이해하기 쉬운 언어

컴파일러

 : 고급언어-->고급언어    번역기

 

 

------------------------------------------------------------------------------------------------------------

<프로그램과 컴파일>

 

프로그램

 : 연산장치가 수행해야 하는 동작들 정의한   일종의 "문서"

    > 프로그램을 연산장치에 전달 --> CPU가 거기 적혀있는 명령들 처리 및 수행

 

   -사용자가 정의한 프로그램  해석,명령 처리 가능한 연산장치  : 'programmable' 연산장치

   - 그 외 일반 계산기 : 대표적인 'non-programmable' 연산장치

 

  -역사)  컴퓨터 내부 저장 장치 없었을 때(프로그램 저장 불가)

    *         '에니악 컴퓨터' (ENIAC):   사람이 전선 연결하여 컴퓨터에 전달 

                                                    --프로그램 바뀔때마다 배선 재배치-->비효율적, 크기 크면 사용 어려움

-->>보완: 'Stored-Program Computer' :프로그램을 메모리에 전자적/광학적으로 저장 가능

                            > 기존 컴퓨터들보다 훨씬 많은 프로그램 저장 가능, 저장 프로그램 사용도 간편

                            > 지금의 컴퓨터 대부분이 이러한 형태로 개발됨

 

 - 정보분야 엔지니어들이 프로그램을 바이너리(Binary)라고 부르는 이유

 : Stored-Program Computer에서 프로그램이 이진(Binary) 형태로 저장장치에 저장되기 떄문

 

 

 

컴파일러 vs 인터프리터

컴파일 : 소스코드-->기계어 형식으로 번역하는 것

    -> 컴파일 해주는 sw : '컴파일러'

 

인터프리팅 : 사용자가 작성한 스크립트를 그때그때 번역하여 CPU에 전달

      > 컴파일 필요없음 _ 동작이 통역과 비슷해서 'Interpreting' 이라고 불림

    -> 인터프리팅 해주는 프로그램: '인터프리터'

 

 

 

컴파일 과정

 

-예) C언어로 작성된 코드 ---> Binary 번역 과정

 : 전처리 -> 컴파일 -> 어셈블 -> 링크

 

1 전처리

 : 컴파일러가 소스코드-->어셈블리어  컴파일 전에,

   필요한 형식으로 가공하는 과정

   > 주석제거

   > 메크로 치환(#define-->이름을 값으로 치환)

   > 파일 병합

 

2 컴파일

 : 고급언어로 작성된 소스코드-->어셈블리어 코드   번역 과정

    > 코드에 문법적 오류 있으면 컴파일 멈추고 에러 출력

 

3 어셈블

 : 컴파일로 생성된 어셈블리어 코드 --> 목적파일   변환 과정

    > 목적파일로 변환되고 나면,  어셈블리 코드가 기계어로 번역됨 >> 사람이 해석 어려움

 

4 링크

  : 여러 목적 파일들을 연결 --> 실행 가능한 Binary로 만드는 과정

   -예) printf함수 호출 시, libc라는 공유 라이브러리 필요 > libc의 함수가 실행될 수 있도록 연결해줌

 

 

 

 

디스어셈블 - 디컴파일

 

디스어셈블

 : 바이너리 분석 시, 바이너리 --> 어셈블리어재번역 (이해 문제 때문)

   ** 어셈블리어 - 기계어   : 거의 1:1 대응됨

 

디컴파일

 : 바이너리 --> 고급언어로 번역

    (여전히 규모 큰 binary동작을 어셈블리 코드만으론 이해 어렵)

   **고급언어-기계어: 대응관계 없으므로, 바이너리의 소스코드와 동일한 코드 생성은 불가

         > 하지만 이 오차가 동작을 왜곡하진 않고, 디스어셈블러보다 압도적 분석 효율 보임

 

 

 

 

 

 

 

 

내용 출처:

https://dreamhack.io/lecture/roadmaps/4

 

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

[리버싱] 스택 프레임  (0) 2024.02.04
[리버싱] 레지스터  (0) 2024.02.04
[리버싱] 스택  (0) 2024.02.04
[리버싱] 03 소프트웨어 분석 기법  (0) 2024.01.28
[리버싱] 01 리버싱이란  (0) 2024.01.28