컴퓨터에서는 대부분의 실행 단위가 프로그램인데, 프로그램의 실행은 결국 CPU가 메모리에 값을 저장하고, 계산하는 과정이라고 볼 수 있다. 동작을 가능하게 하는 응용프로그램에 하드웨어(CPU, 메모리)가 계산 결과를 주게 되는데, 이 둘 사이에서 인터페이스 역할을 하는 운영체제가 결국 자원을 관리하게 된다. 그 중 리눅스에서는 다중작업이 가능한데, 동시에 여러가지 프로그램을 돌리게 되어 각 프로그램별로 필요로하는 메모리 공간을 차지하게 되면, 금방 메모리 부족 문제를 겪게 된다. 하지만 리눅스가 다중작업을 한다고 해도, 컴퓨터가 한 순간에는 한 가지 작업만 가능하다는 점과, 프로그램 자체를 실행할 때에도 순간마다 실행에 필요한 메모리 공간은 전체 필요 메모리 공간의 일부라는 점을 고려하여 메모리를 효과적으로 사용할 수 있는 방법(가상메모리 사용)이 고안되었다.
가상메모리
리눅스는 프로세스별로 4GB의 주소공간(가상주소)을 할당하는데, 3GB는 각각의 프로세스에 할당하고 1GB는 모든 모든 프로세스들의 공통영역인 커널공간에 해당한다. 더 많은 공간 확보하는 것 외에도 코드와 데이터를 보호하는 역할을 하며, 각각의 프로세스는 다른 프로세스들과 분리된 가상메모리주소를 가지고 있기 때문에, 실행중인 프로세스가 다른 프로세스에 영향을 줄 수 없다.
[스택]
메모리 위치 상 스택의 주소값을 계속 늘려나가는 식으로 사용하게 되면 메모리 내의 커널 공간에 침입할 수 있기 때문에, 스택은 높은 주소부터 거꾸로 채워나가며 사용하게 된다. 물리적으로 존재하는 메모리 상의 스택에 스택프레임이 들어왔다 나가는 식으로 동작한다. 스택프레임은 함수를 실행할 때마다 생성되는 각각의 함수만의 공간이라고 볼 수 있기 때문에, 함수 호출 시에는 스택 프레임이 생성되어 스택에 적재되고, 함수 종료 시에는 스텍 프레임이 반납된다.
gdb로 C언어로 코딩한 ytest의 함수를 확인해주니 main함수와 서브루틴 함수인 plus함수가 확인되었다.
가장 위에서 main 함수의 스택 프레임을 생성하는 코드를 확인할 수 있었는데, 내 kali가 64비트여서 베이스 포인터 레지스터와 스택 포인터 레지스터가 ebp, esp가 아닌 rbp, rsp로 출력되었다.
스택프레임의 공간을 확보하기 위한 sub연산에서 0x10을 빼준 것을 보아 main함수의 스택프레임의 크기는 16인것 같다.
main함수
rsp와 rbp의 차이가 16으로 main함수 스택프레임의 크기가 16임을 다시 확인할 수 있었다.
작성한 코드(예상되는 데이터의 저장위치를 주석으로 달아주었다.)
1. 지역변수의 값(i=4)을 스택에 할당
rbp - 4 주소에 4가 할당되었다
2. plus함수 실행 시, 매개변수, 지역변수, return값 스택에 저장
$rbp-0x14에 매개변수로 넘겨준 0x4저장확인
$rbp-4에 plus함수 내 지역변수 y(7)저장 확인
eax에 저장되어 있는 plus함수의 return값 rbp-8주소 스택에 저장 확인
toH값은 동적할당해준 것이기 때문에 스택에 저장되지 않고, 힙에 저장되었을 것이다. 따라서 스택이 변화하지 않은 것을 확인 가능하다.
[힙]
힙영역에 값을 할당하고 싶어서 malloc함수를 main에 넣었던 것이다. malloc함수에 bt를 걸어주자.
7777에 해당하는 0x1e61이 heap에
잘 저장되어있다.
이건 print하기 위해 stack에 힙의 값이 저장된 것을 보여준다.
힙 영역해제
0x4052a0에 있던 0x1e61값이 0으로 초기화되었다.
데이터
BSS
'스터디 > N0Named 스터디' 카테고리의 다른 글
board (0) | 2020.09.27 |
---|---|
[3주차 스터디 과제 3] 패킷 분석 및 네트워크 기본이론 (0) | 2020.09.22 |
[3주차 스터디 과제 2] 리눅스 서버 구축(도커를 이용한 apm 구축) (0) | 2020.09.22 |
[2주차 스터디 과제2] pwntools을 이용한 간단한 문제풀이 (0) | 2020.09.13 |
[2주차 스터디 과제1] pwntools 사용법 및 기능 정리 (0) | 2020.09.13 |