[OS] 프로세스 구조

박성재·2021년 2월 22일
4

운영체제

목록 보기
9/10
post-thumbnail

패스트캠퍼스 컴퓨터 공학자 따라잡기 온라인 완주반
운영체제(이준희 님) 파트를 수강하며 공부한 내용을 정리한 자료입니다.

배너: godori님이 만드신 배너 메이커 활용


프로세스 구조와 컨텍스트 스위칭

프로세스 A를 실행하다가 스케쥴러가 어느 순간 실행하는 프로세스를 프로세스 B로 바꿔준다. 이때, 실행하는 프로세스를 바꿔주는 메커니즘을 컨텍스트 스위칭이라고 한다.

이 컨텍스트 스위칭을 이해하기 위해서는 프로세스의 구조에 대해서 알아볼 필요가 있다.

프로세스의 일반적인 구조

그림1. 프로세스 구조

프로세스의 일반적인 구조는 위의 그림과 같다.

  • text(CODE): 컴파일된 소스 코드가 저장되는 영역
  • data: 전역 변수/초기화된 데이터가 저장되는 영역
  • stack: 임시 데이터(함수 호출, 로컬 변수 등)가 저장되는 영역
  • heap: 코드에서 동적으로 생성되는 데이터가 저장되는 영역

함수를 실행하게 되면 함수의 결과가 리턴될 주소가 스택에 저장되고, 함수의 지역 변수들이 차례로 스택에 쌓이게 된다.
함수가 다 실행되고 나면 스택에 있던 데이터들이 차례로 삭제되고, 스택에 저장되어 있던 리턴될 주소 또한 지워지면서 그 주소로 이동하게 된다.

이렇듯 스택을 이용하여 만든, 함수를 실행하기 위한 구조를 '스택 프레임'이라고 한다.

프로세스와 컴퓨터 구조

  • PC(Program Counter): 코드를 한 줄 한 줄 가리키는 주소 레지스터
  • SP(Stack Pointer): 함수가 실행될 때 스택 프레임의 최상단 주소를 가리키는 레지스터

함수가 호출되면 현재 스택 포인터의 최상단 값을 스택에도 저장하고 EBP 라는 레지스터에도 저장하게 된다.
이는 함수 안에서 문제가 있었을 때, 어떤 문제인지를 빠르게 트래킹하기 위한 것이다.

그림2. 함수 실행 예시 (컴퓨터 구조)

  • 코드 예시는 파이썬이며, 본래 파이썬은 인터프리터 언어이지만 예시에서는 컴파일러 언어로 가정하고 이해한다.
  • EAX 레지스터에는 리턴할 결과값이 담기게 된다.
  • 함수를 리턴할 때 스택에 담겨있는 변수들을 차례로 삭제하고, 리턴 주소도 삭제하고, 함수를 실행할 때 스택에 저장된 EBP 레지스터의 값도 삭제가 된다. 그리고 나서 PC가 리턴 주소를 가리키게 다음 코드가 실행된다.
  • 이때, c에는 EAX 레지스터에 들어있던 값이 할당되고, DATA에 들어 있는 C의 값도 갱신된다.

이처럼 프로세스 실행은 컴퓨터 구조와 많은 연관을 가지고 있다.

프로세스 구조와 힙

프로세스 구조 중 힙(HEAP)은 컴파일 단에서 확인할 수 없는 동적인 요소를 생성할 수 있도록 지원하는 공간이다.

그림3. 함수 실행 예시 (힙)

  • C 언어를 예시로 하고 있다.
  • main() 또한 함수로 간주
  • 컴퓨터 구조와 관련된 부분은 예시에서 생략

위 예시를 살펴보면 main() 함수 내부에서 malloc() 함수를 통해 동적으로 할당한 공간이 HEAP에 담겨있는 것을 볼 수 있다.

BSS와 DATA

프로세스 구조 중 data는 다시 BSS와 DATA로 나누어 진다.

  • BSS: 초기화 되지 않은 전역 변수가 담긴다.
  • DATA: 초기값이 있는 전역 변수가 담긴다.

그림4. BSS와 DATA 예시

  • C 언어 예시
  • main() 함수 밖의 전역 변수 중 초기화되지 않은 data1은 BSS에, 값이 1로 초기화된 data2는 DATA에 저장되어 있는 것을 확인할 수 있다.
  • main() 함수 내부에 있는 지역 변수 data는 STACK에 저장되어 있다.

스택 버퍼 오버플로우

스택 버퍼 오버플로우 :
스택은 함수 처리를 위해 지역변수 및 매개변수가 위치하는 메모리 영역을 말한다.
스택에 할당된 버퍼들이 문자열 계산등에 의해 정의된 버퍼의 한계치를 넘는 경우 버퍼 오버플로우가 발생하여 복귀 주소(Return Address)를 변경하고 공격자가 원하는 임의의 코드를 실행한다.

출처: https://itragdoll.tistory.com/44

스택 버퍼 오버플로우는 주로 해커들의 공격에 활용되었다.

그림5. 스택 버퍼 오버플로우 1

  • 위 예시에서 문자열 6개가 들어가도록 버퍼 크기를 설정해주었다.
  • 프로그램 이름이 cpd 라고 하면 터미널에서 cpd aaaaaa 를 입력하면 argv 인자로 cpd와 aaaaaa가 넘겨진다.
  • 이때 argv[1]에는 aaaaaa가 넘겨져 copy() 함수를 통해 미리 정해진 크기의 버퍼에는 'aaaaaa'라는 문자들이 담기게 된다.

그림 6. 스택 버퍼 오버플로우 2

>

  • 하지만 strcpy() 라는 함수가 널 문자 ('\0')를 만날 때까지 모든 문자를 복사한다는 것과 프로세스의 구조를 잘 알고 있는 해커들은 의도적으로 버퍼의 크기를 뛰어 넘는 인자를 넘겨주어 스택 버퍼 오버플로우를 발생시킨다.
  • 이때 스택 버퍼 오버플로우가 발생하여 Return Address가 변경되고 공격자가 원하는 임의의 코드를 실행할 수 있게 된다.

1개의 댓글

comment-user-thumbnail
2022년 12월 21일

덕분에 잘보고갑니다 : )

답글 달기