정보보안 공부/CTF(해킹)

[포너블] 리눅스 프로세스의 메모리 구조

pxatd 2022. 12. 30. 03:11
728x90

1. 세그먼트

리눅스에서는 프로세스의 메모리를 크게 5가지의 세그먼트로 나눈다.

세그먼트란 데이터의 용도별로 메모리를 나눈 것인데 크게 코드 세그먼트, 데이터 세그먼트, BSS 세그먼트, 힙 세그먼트, 그리고 스택 세그먼트로 구분한다.

운영체제가 메모리를 용도별로 나누면 각각의 세그먼트에 권한을 부여할 수 있다는 장점이 있다. (읽기 쓰기 실행 권한이 있으며 CPU는 이 권한에 따라 접근할 수 있다.)

 

 

1.1 코드 세그먼트

실행가능한 기계 코드가 저장되는 곳이다.

프로그램이 동작하려면 코드를 읽고 실행시켜야 하기 때문에 읽기, 실행 권한이 부여된다.

쓰기 권한이 부여되면 공격자가 악의적인 코드를 삽입하기 쉬우므로 쓰기 권한은 부여되지 않는다.

예를들어 정수 31337을 반환하는 main함수가 컴파일 되면 554889e5b8697a00005dc3라는 기계 코드로 변환되는데, 이 기계 코드가 코드 세그먼트에 위치하게 된다.

int main() { return 31337; }

 

 

1.2 데이터 세그먼트

컴파일 시점에 값이 정해진 전역 변수 및 전역 상수들이 위치한다.

CPU가 세그먼트의 데이터를 읽을 수 있어야 하므로 읽기 권한이 부여된다.

 

 

1.3 BSS 세그먼트

컴파일 시점에 값이 정해지지 않은 전역 변수가 위치한다.

예를들어 개발자가 선언만 하고 초기화를 하지 않은 변수들이 들어가게 된다.

이 세그먼트에는 읽기 권한 및 쓰기 권한이 부여된다.

 

 

1.4 스택 세그먼트

프로세스의 스택이 위치한다.

스택 세그먼트는 스택 프레임이라는 단위를 사용하는데 스택 프레임은 함수가 호출될 때 생성되고, 반환될 때 해제된다.

일반적인 사용자의 프로그램에서 실행 흐름은 사용자가 입력한 값에 따라 바뀌므로 예측할 수 없고 따라서, 어떤 프로세스가 실행될 때, 이 프로세스가 얼마 만큼의 스택 프레임을 사용하게 될 지를 미리 계산하는 것은 일반적으로 불가능하다.

따라서 운영체제가 이를 흐름에 따라 조절해준다.

CPU가 자유롭게 값을 읽고 쓸 수 있어야 하므로, 읽기와 쓰기 권한이 부여된다.

 

 

1.5 힙 세그먼트

C언어에서 malloc(), calloc() 등 동적할당을 호출해서 할당받는 메모리가 이 세그먼트에 위치하게 되며, 일반적으로 읽기와 쓰기 권한이 부여된다.

스택 세그먼트와 반대방향으로 자란다.

두 세그먼트가 동일한 방향으로 자라며, 연속된 메모리 주소에 각각 할당된다고 가정해자. 이 경우, 기존의 힙 세그먼트를 모두 사용하고 나면, 이를 확장하는 과정에서 스택 세그먼트와 충돌하게 된다.

이를 쉽게 해결하기 위해 리눅스는 스택을 메모리의 끝에 위치시키고, 힙과 스택을 반대로 자라게 한다.

728x90