카테고리 없음

[운영체제] 버퍼 오버플로우 1 (buffer overflow)

pxatd 2022. 6. 26. 17:34
728x90

1. x86 아키텍쳐

- CPU

- 메모리

- 입출력 장치 (I/O)

 

1) 연산장치 (ALU, Arithmetic and Logic Unit)

- CPU의 핵심 부분 중 하나로, 산술과 논리 연산을 수행하는 연산 회로 집합으로 구성

- 관련 레지스터: 범용 레지스터 (EAX, EBX, ECX, EDX), 플래그 레지스터 (EFLAGS)

* 레지스터 : 연산을 위해 사용되는 변수 

* 플래그 레지스터 : 특수 목적 레지스터, 아키텍쳐의 제약으로 인해 생성되는 부산물들을 저장함 

 

2) 제어 장치 (Control Unit)

- 입력, 출력, 기억, 연산 장치를 제어하고 감시

- 주기억 장치에 저장된 명령을 차례로 해독하여 연산 장치로 보내 처리되도록 지시

  • 프로그램 카운터 (PC): 다음에 실행할 명령의 주소 저장
  • 명령 포인터 레지스터 (IP): 현재 실행 중인 명령 저장
  • 스택 포인터 레지스터: EBP, ESP

 

3) 컴퓨터 아키텍쳐의 종류

- 32-bit 아키텍쳐 vs 64-bit 아키텍쳐

- 한 번에 처리할 수 있는 양이 몇 bit인지에 따라 다름 (크기) 

- 2^32-1, 2^64-1

- 이에 따라, 사용할 수 있느 프로세스 메모리 주소 공간 또한 달라짐

- 통상 Intel에서는 32-bit를 x86 (IA-32), 64-bit을 x86-64 (amd64) 아키텍쳐라고 포현함

- opcoed에 전달된 명령어에 따라 실행됨 

 

 

2. 프로그램 컴파일 과정 

- hello.c->hello.s = 사람이 읽을 수 있는 마지막 포맷

- 어셈블리 -> 목적 프로그램 = 컴퓨터 읽을 수 있도록 컴파일

- 목적파일 + 라이브러리 = 바이너리 파일 

- 로더에 의해 메모리에 적재

- 메모리에 적재된 파일이 CPU에 로드되어 하나씩 실행됨 

 

 

3. 바이너리 포맷의 구성

- 세그멘테이션과 세그먼트

  • 세그멘테이션이란, 컴퓨터 메인 메모리를 가상 메 모리 내에 논리적으로 구분된 여러 개의 세그먼트 로 나누는 과정
  • 메모리에 적제되는 단위로 사용
  • 각각 베이스(base) 어드레스를 가짐
  • 코드 세그멘트, 데이터 세그멘트, bss 세그먼트 등 각각의 세그먼트 존재 

 

4. 로더의 역할

- 크게 보면, 바이너리를 실제 메모리 상에 적재하는 것

- 운영체제: 보조기억장치로부터 주기억장치에 적재하는 시스템 소프트웨어

- 메모리가 적재될 때의 단위가 세그먼트 

 

 

5. 세그먼테이션 폴드(SegFault)

- 프로그램이 허용되지 않은 메모리 영역에 접근을 시도하거나 허용되지 않은 방법으로 메모리 영역에 접근할 경우 발생

- 프로그램이 동작 중 잘못된 주소를 참조할 때 발생하는 오류

 

 

6. 스택 (sack) 의 구조

- LIFO 원리를 따르는 데이터 구조

- Queue와 반대의 데이터 구조임

- 스택에 데이터를 넣는 것을 Push, 빼는 것을 Pop

1) 바이너리에서의 힙과 스택

- 데이터, 코드 영역 외에 스택과 힙 영역이 있음

  • 스택 영역: 함수 호출 시 생성되는 지역 변수 및 매개 변수가 저장
  • 힙 영역: 동적으로 할당된 메모리를 관리
  • 힙은 위로 (낮은 메모리주소에서 높은 주소), 스택은 아래로 (높은 주소에서 낮은 주소) 자람
  • 스택의 top주소값이 감소했다 = 스택에 새로운 값이 들어왔다
  • malloc, free 동적할당 함수 : 힙(Heap) 영역에 메모리 공간을 할당했다가 다시 놓아주는 것 

 

 

7. x86 레지스터의 종류 

1) 레지스터란 

- CPU 내에 있는 고속 메모리 장치

- 아키텍쳐 만큼의 크기를 가짐 (컴퓨터 아키텍쳐에 따라 크기 및 종류가 다양함)

- 레지스터의 크기 (32비트 ‘E’로 시작, 64비트 ‘R’로 시작)

- 기본은 WORD (16비트)

 

2) 스택오버플로우와 관련된 x86 주요 레지스터

- 범용 레지스터

  • EAX, EBX, ECX, EDX

-스택 포인터 레지스터

  • ESP: 스택의 Top을 가리킴 (스택 세그먼트에서 현재 호출되어 사용되는 함수의 시작 주소 값 저장, 함수로 전달되는 지역변수 등을 참조할 때 기준, ESP 레지스터와 함께 사용되어 스택 프레임(stack frame)을 형성)
  • EBP: 현재 스택 프레임의 베이스 주소를 가리킴 (현재 스택 영역에서 가장 하위 주소를 저장)

- 명령어 포인터 레지스터, 상태 레지스터, 세그먼트 레지스터

  • EIP: 명령어 주소를 계산하는데 사용, PC (Program Counter)라고도 칭함
  • EFLAGS: x86 프로세서의 상태를 저장하기 위해 사용
  • 세그먼트 레지스터: 각 세그먼트의 위치를 가리킴, 물리 주소 변환에 사용 (코드 세그먼트 (CS), 스택 세그먼트 (SS), 데이터 세그먼트 (DS), bss 세그먼트)
728x90