Layer7 동아리 과제

리버싱 2차시 과제

msh1307 2022. 7. 20. 12:10

리버싱이란?

리버싱 : Reverse engineering의 약자로 역공학이라는 뜻이다. 

바이너리의 구조, 기능, 동작을 분석한다. 

 

크게 두 가지 방법이 존재한다. 

정적 분석 : 파일을 실행하지 않고 파일 종류, 헤더, 디스어셈블러, 디컴파일러로 코드를 분석 

동적 분석 : 파일을 실행하면서 코드 흐름과 메모리 상태 등을 보면서 분석 

gcc 사용

코드를 작성하고 조금 옵션을 줘서 컴파일을 해보겠다. 

layer7.c는 원본 소스코드 파일이다.

layer7.i는 전처리된 소스코드 파일이다. 

layer7.s는 어셈블리어 파일이다. 

layer7.o는 어셈블러에 의해 기계어로 변환된 파일이다. 

layer7은 layer7.o가 링커가 링킹을 하고나서 나온 최종적인 바이너리 파일이다.

빌드는 이 전처리기, 컴파일러, 어셈블러, 링커를 거친걸 말하고 컴파일은 그 과정중 하나지만 편의상 사람들이 다 컴파일이라 한다. 

전처리기

전처리기(preprocessor)가 주석을 제거하고, 헤더 파일을 삽입한다.

또한 매크로 치환 작업도 수행한다. 

컴파일러

그다음 컴파일러(compiler)가 전처리된 소스 코드 파일을 어셈블리어 파일로 변환한다. 이때 문법 검사가 이루어진다.

컴파일러가 코드를 번역하는 시점에서 변수를 저장할 메모리 위치를 배정하는 것을 정적 메모리 할당(Static Memory Allocation)이라고 한다.

메모리의 크기가 하드 코딩되어 있어서 프로그램이 실행될 때 이미 해당 메모리의 크기가 결정된다.

데이터 영역이나 코드 영역이 정적 메모리 할당의 예시이다.

런타임에 메모리 할당하는 것을 동적 메모리 할당이라고 한다. heap이나 stack을 예시로 들 수 있다.

컴파일러의 구조는 프론트엔드, 미들엔드, 백엔드로 구성되어있다. 

프론트엔드에서는 언어 종속적인 부분을 처리한다. 소스 코드를 확인하고 IR(Intermediate Representation)인 GIMPLE 트리를 생성해서 미들엔드에 넘겨준다.

이렇게 소스 코드를 트리 형태로 표현한 구조를 GIMPLE 트리라고 한다. 

 

미들엔드에선 아키텍처 비종속적인 최적화를 수행한다. 

아키텍처 비종속적이라는 말의 의미는 x86 CPU건 arm이던 상관이 없다는 뜻이다.

GIMPLE 트리를 받아서 아키텍처 비종속적 최적화를 하고 백엔드에서 사용하는 RTL(Register Transfer Language)를 생성한다.


RTL이란 micro-operation을 register의 transfer로 나타낸것이다. IR의 종류중 하나인데 어셈블리어와 매우 가깝다고 한다.

RTL basic symbols다.

 

백엔드에서는 아키텍처 종속적인 최적화를 수행한다.

아키텍처 종속적이라는 말의 의미는 CPU 아키텍처별에 따라 다 다르다는 말이다. 

미들엔드에서 넘겨받은 RTL을 이용해서 아키텍처 종속적인 최적화를 수행하고 완료되면 어셈블리 코드를 생성한다.

아키텍처 종속적인 최적화를 수행하면 해당 아키텍처만 이해할 수 있는 언어가 된다. 

 

대부분의 컴파일러는 이 세 단계의 구조를 따른다. 약간 아닌 것도 존재한다. 

 

어셈블러

어셈블러가 어셈블리어 파일을 오브젝트 파일로 변환하는 과정이다. 

오브젝트 파일은 어셈블리 코드가 기계어로 변환된 파일을 말한다.

Linux는 ELF(Executable and Linking Format)

Windows는 PE(Portable Executable)

오브젝트 파일의 포맷을 이렇다.

비슷하게 되어있다.

 

링커

오브젝트 파일에서 사용하는 외부 함수, 예를 들어서 printf같은 함수들을 연결시키는 과정이다. 

라이브러리 파일들을 링크해서 실행 파일로 만드는 과정이다. 

동적 링킹, 정적 링킹이 있다. 동적 링킹은 libc를 메모리 올려놓고 필요할 때 쓰는 것이다. 

그래서 뒤져보면 libc.so.6가 심볼릭 링크로 libc-2.31.so가 걸려있다.

뒤에 so가 shared object를 의미한다. 공유되는 오브젝트 파일이라서 그렇게 붙인 거 같다. 

 

정적 링킹은 오브젝트 파일에 필요한 라이브러리 오브젝트를 올리는 것을 말한다. 

링커는 심볼 해석과 재배치를 주로 한다. 

심볼 해석은 각 오브젝트 파일의 심볼 참조를 어떤 심볼 정의와 연관시킬지 결정하는 과정이다.

 

재배치는 오브젝트 파일의 데이터 주소나 코드의 메모리 주소를 알맞게 배치하는 과정이다. 

링커가 컴파일러가 생성한 오브젝트 파일을 모아서 하나의 실행 파일을 만들때, 각 오브젝트 파일에 있는 데이터의 주소나 코드의 주소가 링커에 의해 합쳐진 실행 파일에서의 주소와 달라서 재배치를 해줘야 한다. 

같은 섹션끼리 합쳐지고 재배치가 일어난다. 

 

링킹하기 전 오브젝트 파일을 재배치 가능한 오브젝트 파일이라고 부르고 링킹 후 오브젝트 파일을 실행 가능한 오브젝트 파일이라고 부른다. 

PIC(Position Independet Code)와 헷갈릴 수 있는데, PIC는 instruction pointer를 참조해서 실행된다. 굳이 재배치될 필요도 없다.

아래에 자세히 설명되어있다.

http://davidad.github.io/blog/2014/02/19/relocatable-vs-position-independent-code-or/

 

Relocatable vs. Position-Independent Code (or, Virtual Memory isn't Just For Swap) - Technical Journal

Myth: “Virtual memory” is the mechanism that a kernel uses to make more memory available than is actually physically installed, by setting aside a disk partition for the overflow and copying pages between memory and disk as needed. I acquired this beli

davidad.github.io

 

내가 자주쓰는 명령어

ls : 디렉토리의 파일 확인

ls -l : 보기 좋게

ll : .bashrc에 alias로 ls -l랑 같음

ls -a : 앞에 .이 붙어있는 숨김 파일도 표시

cd : change directory 뒤에 상대 경로나 절대 경로 붙여서 이동

pwd : print working directory

cat : 파일 읽기

vi : vim 에디터 사용

 

Vim 단축키 

:wq : 저장하고 나가기

:q : 저장안하고 나가기

:q! : 강제로 저장 안 하고 나가기, :q 했을때 에러 뜨면 씀

a or i : insert 모드 들어가기

d 꾹 누르기 or 두번 누르기 : 에디터 모드 진입 안 한 상태에서 꾹 누르면 다 지워지고, 두 번 누르면 한 라인만 지워짐

'Layer7 동아리 과제' 카테고리의 다른 글

리버싱 4차시 과제  (0) 2022.07.26
리버싱 3차시 과제  (0) 2022.07.23
하드웨어 3, 4차시 과제  (0) 2022.06.19
하드웨어 2차시 과제  (0) 2022.06.11
하드웨어 1차시 과제  (0) 2022.06.08