해당 게시물은 드림핵의 강좌 내용을 정리한 것이다. 예제 코드는 포함하지 않았다.
해커들의 놀이터, Dreamhack
해킹과 보안에 대한 공부를 하고 싶은 학생, 안전한 코드를 작성하고 싶은 개발자, 보안 지식과 실력을 업그레이드 시키고 싶은 보안 전문가까지 함께 공부하고 연습하며 지식을 나누고 실력 향
dreamhack.io
Ⅰ. 서론
기계어(Machine Language) : 컴퓨터에게 명령을 내리기 위한 언어
어셈블리어(Assembly Language) : 0과 1을 대신한 사람이 이해하기 쉬운 언어
어셈블러(Assembler) : 어셈블리어를 기계어로 번역해주는 프로그램
컴파일러(Compiler) : C, C++, GO, Rust과 같은 어셈블리어보다 이해하기 쉬운 언어들을 번역해주는 프로그램
고급 언어(High-Level Language) : 사람이 이해하기 쉬운 언어
저급 언어(Low-Level Language) : 컴퓨터가 이해하기 쉬운 언어
Ⅱ. 프로그램과 컴파일
▶ 프로그램(Program) : 연산 장치가 수행해야 하는 동작을 정의한 일종의 문서
사용자가 정의한 프로그램을 해석하여 명령어를 처리할 수 있는 연산 장치를 programmable 하다고 한다.
→ 현대의 컴퓨터 : programmable 연산 장치
→ 일반 계산기 : non-programmable 연산 장치
과거에는 프로그램을 내부 저장 장치에 저장이 불가능 했음
→ 사람이 전선을 직접 연결해 컴퓨터로 전달
→ 천공 카드(Punched card)에 프로그램을 기록해 재사용

애니악(ENIAC) : 전자의 방식을 사용한 컴퓨터. 프로그램이 바뀔 때마다 배선을 재배치해야 했으므로 매우 비효율적이었고, 크기가 큰 프로그램 사용에도 어려움이 있었음.
Stored-Program Computer : 애니악의 단점을 해결한 컴퓨터. 프로그램을 메모리에 전자적 / 광학적으로 저장할 수 있음.
→ 프로그램 저장 공간과 저장된 프로그램의 사용이 더 간편해짐. 따라서 컴퓨터의 대부분이 Stored-Program Computer의 형태로 개발되기 시작함.
많은 정보 분야의 엔지니어들이 프로그램을 바이너리(Binary)라고 부름.
→ Stored-Program Computer에서 프로그램이 저장 장치에 이진(Binay) 형태로 저장되기 때문.
※ 텍스트가 아닌 다른 데이터들도 바이너리라고 불리긴 하나, 대부분 바이너리라고 하면 프로그램을 의미함.
▶ 컴파일러와 인터프리터
프로그래밍 언어(Programming Language) : 프로그램을 개발하기 위해 사용하는 언어
소스 코드(Source Code) : CPU가 수행해야 할 명령들을 프로그래밍 언어로 작성한 것
컴파일(compile) : 소스 코드를 컴퓨터가 이해할 수 있는 기계어 형식으로 번역하는 것
인터프리팅(Interpreting) : 사용자가 작성한 스크립트를 그때그때 번역하는 것
인터프리터(Interpreter) : 인터프리팅을 처리해주는 프로그램
종류 | 속도 | 장/단점 |
컴파일 | 느림 | 한 번 번역하면 또 번역하지 않아도 됨 |
인터프리팅 | 빠름 | 실행할 때마다 번역해야 함 |
▶ 컴파일 과정
C언어로 작성된 코드는 일반적으로
전처리(Preprocess) → 컴파일(Compile) → 어셈블(Assemble) → 링크(Link)
의 과정을 거쳐 바이너리로 번역됨
▶ 전처리
전처리(Preprocessing) : 컴파일러가 소스 코드를 어셈블리어로 컴파일하기 전, 필요한 형식으로 가공하는 과정
> 전처리 과정
- 주석 제거 : 주석은 프로그램의 동작과 상관이 없으므로 모두 제거됨
- 매크로 치환 : #define으로 정의한 매크로의 이름은 값으로 치환됨
- 파일 병합 : 여러 개의 소스와 헤더 파일로 이루어진 프로그램을 합치고 컴파일 하기도 함
▶ 컴파일
컴파일(Compile) : C로 작성된 소스 코드를 어셈블리어로 번역하는 것.
컴파일 과정에서 소스 코드의 문법을 검사해 문법적 오류가 있다면 에러를 출력해주고, 몇몇 조건을 만족하면 최적화 기술을 통해 효율적인 어셈블리 코드를 생성해줌
▶ 어셈블
어셈블(Assemble) : 컴파일로 생성된 어셈블리어 코드를 ELF형식의 목적 파일(Object file)로 변환하는 과정
ELF : 리눅스 실행파일 형식
윈도우에서 어셈블 한다면 목적 파일은 PE형식을 가짐
목적 파일로 변환되고 나면 어셈블리 코드가 기계어로 번역 되어 사람이 해석하기 어려워짐
▶ 링크
링크(Link) : 여러 목적 파일들을 연결해 실행 가능한 바이너리로 만드는 과정
c언어의 printf 함수의 경우 직접 printf 함수를 선언하지 않음.
이 함수의 정의는 libc라는 공유 라이브러리에 존재함.
libc는 gcc의 기본 라이브러리 경로에 있는데, 링커는 바이너리가 printf를 호출하면 libc의 함수가 실행되도록 연결해줌.
Ⅲ. 디스어셈블과 디컴파일
▶ 디스어셈블
디스어셈블(Disassemble) : 어셈블의 역과정
▶ 디컴파일
디컴파일러(Decompiler) : 어셈블리어보다 고급 언어로 바이너리를 번역하는 프로그램
어셈블리어와 기계어는 거의 1:1로 대응되어 오차가 없음.
그러나 고급 언어와 어셈블리어 사이에서는 대응 관계가 없고
컴파일 과정에서 작성한 코드가 변형된다.
'Reverse Engineering' 카테고리의 다른 글
스택 프레임(Stack Frame) (0) | 2022.08.28 |
---|---|
Dreamhack | Reverse Engineering | Stage 2 | Background: Static Analysis vs. Dynamic Analysis (0) | 2022.07.09 |