Nullorm

Reversing 기초 | DreamHack | Background: Binary 본문

study_SECURITY/Reversing

Reversing 기초 | DreamHack | Background: Binary

Null0rm 2022. 6. 1. 21:25
반응형

1. C언어 코드의 바이너리 번역과정

code(.c)

--전처리--

preprocessed source file (.i)

--컴파일--

assembled file (.s)

--어셈블--

object file (.o)

--링크--

바이너리로 번역!

 

1-1. 전처리(preprocessing)

1. 주석제거

// 또는 /**/으로 구성되어있는 주석을 제거하는 과정

 

2. 매크로 치환

#define으로 정의된 매크로는 자주 쓰이는 코드나 상숫값을 단어로 정의한 것

#define HI 3  //HI를 3으로 치환하라는 명령어

 

3. 파일 병합

일반적인 프로그램은 여러개의 소스와 헤더파일로 구성. 컴파일러는 이런 것들을 컴파일 이후 합치기도 하지만 전처리단계에서 합친 이후에 컴파일하기도 함.

 

gcc에서는 -E 옵션을 사용하여 소스코드의 전처리 결과를 확인할 수 있음.(.c -> .i) 

$ gcc -E add.c > add.i

$ cat add.i

1-2. 컴파일(compile)

C로 작성된 소스코드를 어셈블리어로 번역하는 과정.

이 과정에서 소스코드의 문법을 검사하기도 함.

 

gcc에서는 -S 옵션을 사용하여 소스코드를 어셈블리 코드로 컴파일할 수 있음. (.i -> .s)

$ gcc -S add.i -o add.S

$ cat add.S

1-3. 어셈블(Assemble)

 

어셈블은 컴파일로 생성된 어셈블리 코드를 ELF형식의 목적파일(Obj)파일로 변환하는 과정임.

ELF는 리눅스의 실행파일 형식. PE는 윈도우의 실행파일 형식

 

gcc에서는 -c 옵션을 통해  어셈블리코드를 목적파일로 변활할 수 있음. (.s -> .o)

$ gcc -c add.S -o add.o

$ file add.o

$ hexdump -C add.o

1-4. 링크(Link)

여러 목적 파일들을 연결하여 실행 가능한 바이너리로 만드는 과정.

$ gcc add.o -o add -Xlinker --unresolved-symbols=ignore-in-object-files

$ file add

2. 디스어셈블

바이너리를 분석하기 위해서는 바이너리를 읽을 수 있어야 한다.

그런데 컴파일된 프로그램코드는 기계어로 이루어져있기 때문에 이를 그대로 이해하기는 매우 힘들다.

따라서 이를 어셈블리어로 재번역하는 과정이 디스어셈블(Disassemble) 이라고 함.

 

명령어 : $ objdump -d ./add -M intel

리버싱 과정

3. 디컴파일

디스어셈블러와 같은 개념. 어셈블리어로 된 파일을 고급언어로 바꾸어주는 역할을 한다.

하지만 100% 동일하게 바꾸어주지는 못한다. 

코드를 작성할 때 사용했던 변수나 함수의 이름은 컴파일 과정에서 사라지고 코드의 일부분은 최적화 등의 이유로 완전히 변형된다.

 

 

반응형