I. Stack Frame : RSP와 RBP로 스택을 관리하는 기법
1. RSP와 RBP
① RSP : Stack Point Register
- 스택이 움직일 때마다 움직이며 스택의 맨 꼭대기 부분을 가리킨다.
- RBP의 반대 방향을 가리킨다.
② RBP : Base Point Register
- RSP는 스택이 움직일 때마다 움직이지만
RBP는 고정되어 있으며 움직이지 않는다.
2. 스택 (Stack)
- 스택 영역은 함수의 호출과 관련되는 지역변수와 매개변수가 저장되는 영역이다.
- 스택 영역은 함수 호출과 함께 할당된다. 함수의 호출이 끝나면 없어진다.
- 후입선출(LIFO : Last In First Out) 구조이다.
(프링글스 통, 엘리베이터 탑승 등을 생각하면 이해하기 쉽다.)
3. 스택프레임 (Stack Frame)
- RSP와 RBP로 스택을 관리하는 기법이다.
- 스택프레임에 의해서 스택을 관리한다.
- 함수가 호출이 되면 스택에
(1) 함수의 변수
(2) 호출이 끝난 후 돌아갈 주소
를 저장하는데, 이 스택에 저장된 정보를 스택프레임이라고 한다.
- 스택프레임을 그림으로 봐 보자! 뾰로롱.

- rsp를 rbp에 저장하여 두 개의 위치를 같게 한다. ( 초기값을 같게 설정한다. )

- 그림을 통해 알 수 있듯, RBP는 절대로 움직이지 않고 RSP는 스택이 변할 때마다 변한다.
- RSP는 꼭대기를 가리키면 RBP와 반대 방향이다.
4. 함수 프롤로그와 에필로그
4-(1) 함수 프롤로그

① push rbp
: 함수의 초기값을 스택에 저장한다.
② mov rbp,rsp
: 현재의 RSP를 RBP에 저장한다.
4-(2) 함수 에필로그

① leave
: RSP를 초기값으로 복원한다. 그리고 저장해뒀던 RBP값으로 복원한다.
② ret
: 함수를 종료한다.
II. PLT & GOT
① PLT ( Procedure Linkage Table ) :
- 실제로 호출할 코드를 담고 있는 테이블
- 프로그램 밖에 있는 프로시저를 연결해주는 테이블
- PLT를 이용해서 다른 라이브러리에 있는 프로시저를 호출하여 사용 가능하다.
※ 프로시저 ( procedure ) ???
- 프로그램을 여러 개의 단위로 분해한 것
- 프로그램 수정과 관리가 쉬워지며, 다른 프로그램에서 재사용도 할 수 있다.
② GOT ( Global Offset Table ) :
- PLT가 참조하는 테이블
- 프로시저의 주소가 들어있다.
위에서 언급한 것 처럼 PLT가 GOT를 참조한다음 함수를 호출하는데,
이 때, 프로그램 밖에 있는 라이브러리에서 주소를 가져오게 된다.



III. 어셈블리 코드 흐름




push rbp | rbp가 스택에 들어온다. |
mov rbp, rsp | rbp를 rsp에 복사한다. ( rbp와 rsp가 가리키는 주소가 같아진다.) |
sub rsp, 0x100 | rsp가 0x100 바이트 할당된 공간을 가리킨다. |
mov eax, 0 | eax가 0으로 초기화 된다. |
call setup | 함수를 호출한다. |

leave
ret
위에 두 줄은 함수 에필로그이다. 함수를 종료한다.
IV. 디버거 사용법
1. 디버그와 디버거
① 디버그(Debug) : 프로그래밍 중 발생하는 버그를 찾고 수정하는 것. 코드에서 버그를 제거하는 것.
② 디버거(Debugger) : 디버그를 하는 도구. 디버거를 사용하여 디버그 할 수 있다.
2. 디버거 명령어
(1) 시작하고 종료하는 명령어
- gdb 프로그램 이름 : 시작하기
- q(quit) 또는 단축키 Ctrl+d : 종료하기

(2) 실행중인 바이너리를 제어하는 명령어
- run(r) : 바이너리를 실행한다.

- breakpoint (b) : 실행 중인 프로그램을 멈추게 한다. (멈추는 지점)

- continue (c) : 다음 브레이크 포인트까지 실행한다.
- next(ni) : 다음 행을 수행한다. 단, 함수를 만났을 때 함수 안으로 들어가지 않는다.
-> next n : n번 수행한다.
- step(si) : 다음 행을 수행한다. 단, 함수를 만났을 때 함수 안으로 들어간다.



ni 명령어를 쳤더니 <main>을 가리키던 화살표가 다음 행인 <main+1>을 가리킨다.
- kill : 디버깅 중인 프로그램을 실행 취소한다.
- finish : 현재 함수를 수행하고 빠져나간다.
- return : 현재 함수를 수행하지 않고 빠져나간다.
(3) 출력 관련 명령어
- info(i) : 중단점의 정보 보기
-> info breakpoint : 현재 설정된 브레이크 포인트의 정보를 출력한다.
-> info function : 함수의 정보를 출력한다.

- print(p) : 출력하기
-> print value :
-> print $register : 해당 레지스터 값 출력
(4) 메모리 보기 포맷과 출력형식
- x 명령어는 메모리 특정 범위의 값들을 확인할 때 쓴다.
-> x/[원하는 범위][출력 형식][단위]
-> x/64x main

(5) 기타 명령어
- disassemble 함수이름 : 함수를 디스어셈블(분해?)한다.

- delete(d) 브레이크포인트 : 브레이크포인트를 삭제한다.

'Sunrin > Layer7' 카테고리의 다른 글
Webhacking Project - PHP와 MySQL (0) | 2020.08.12 |
---|---|
Dreamhack - Introduction of Webhacking 정리 (0) | 2020.08.07 |
Python 문법 (0) | 2020.07.08 |
C Pointer 실습 (0) | 2020.07.03 |
C pointer (0) | 2020.06.24 |