Computer Security

#1 프로세스의 메모리 구조. 세그먼트(Segment) 본문

컴퓨터구조&어셈블리어

#1 프로세스의 메모리 구조. 세그먼트(Segment)

쿠리 Kuri 2022. 5. 11. 18:30

리눅스에서는  프로세스의 메모리를 크게 5가지의 세그먼트(코드 세그먼트, 데이터 세그먼트, BSS 세그먼트, 힙 세그먼트, 스택 세그먼트) 로 구분한다.

 

운영체제가 메모리를 용도별로 나누면, 각 용도에 맞게 적절한 권한을 부여할 수 있다.

권한은 읽기,쓰기,실행이 존재한다.

CPU는 메모리에 대해 권한이 부여된 행위만 가능하다.

 


코드 세그먼트(Code Segment) /  텍스트 세그먼트(Text Segment)

1.실행 가능한 기계코드가 위치하는 영역이다.

2.프로그램이 동작하려면 코드를 실행할 수 있어야 하므로, 이 세그먼트에는  읽기 권한과 실행 권한이 부여된다.

하지만, 쓰기 권한이 있으면, 공격자가 악의적인 코드를 삽입하기 쉬어지므로, 대부분의 운영체제에서 쓰기 권한은 없다.

 

int main() {return 31337;}

위 main함수가 컴파일 되면, 554889e5b8697a00005dc3라는 기계 코드로 변환 되는데, 이 기계 코드가

코드 세그먼트에 위치하게 된다.


데이터 세그먼트(Data Segment)

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

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

3.쓰기가 가능한 세그먼트와 쓰기가 불가능한 세그먼트로 분류 된다.

4.쓰기가 가능한 세그먼트(data 세그먼트)는 전역 변수와 같이 프로그램이 실행되면서 값이 변할 수 있는데이터들이 위치한다.

5.쓰기가 불가능한 세그먼트(rodata(read-only data)세그먼트)는 실행되면서 값이 변하면 안되는 데이터(전역으로 선언된 상수 등) 들이 위치한다.

 

int data_num=24251;    //data
char data_rwstr[]="writable_data";  //data
const char data_rostr[]="readonly_data";  //rodata
char *str_ptr="readonly" ;  //str_ptr은 data, 문자열은 rodata

str_ptr은 "readonly"라는 문자열을 가르키는데, 이문자열은 상수 문자열로 취급되어 rodata에 위치하며,

이를 가르키는 str_ptr은 전역 변수로서 data에 위치한다.

 


BSS 세그먼트(BSS Segment, Block Started By Symbol Segment)

1.컴파일 시점에 값이 정해지지 않은 전역  변수가 위치하는 메모리 영역이다.

2.개발자가 선언만 하고 초기화 하지 않은 전역변수 등이포함된다.

3.BSS세그먼트의 메모리영역은 프로그램이 시작될 때, 모두 0으로 값이 초기화 된다.

4.C코드를 작성할 때, 초기화 되지 않은 전역 변수의 값은 0 이된다.

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

int bss_data;

int main(){
printf("%d\n", bss_data); //0으로 초기화
return 0;
}

위와 같이 초기화 되지 않은 전역 변수인 bss_data 가 BSS 세그먼트에 위치한다.


스택 세그먼트(Stack Segment) (가장 늦게 저장된 데이터가 가장 먼저 인출) 

1.함수의 인자나 지역변수와 같은 임시 변수들이 실행중 여기에 저장된다.

2.스택 프레임이라는 단위로 사용된다. 스택 프레임은 함수가 호출될 때 생성되고, 반환될 때 해제된다.

3.이 프로세스가 얼마 만큼의 스택 프레임을 사용하게 될 지를 미리 계산하는 것은 거의 불가하다.

->그래서 운영체제는 프로세스를 시작할 때 작은 크기의 스택 세그먼트를 먼저 할당해주고, 부족해 질 때마다 이를 확장해준다.

4.스택이 확장될 때, 기존 주소보다 낮은 주소로 확장된다.

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

void func(){
int choice = 0;

scanf("%d",&choice);

if(choice)

 call_true();
 
else
 call_false();
 
  
return 0;
}

위와 같은 코드에서 지역변수 choice가 스택에 저장된다.

-> 유저가 입력한 choice값에 따라 call_true()가 호출되거나, call_false() 호출될 수 있다.


힙 세그먼트(Heap Segment) 

 

1.힙 데이터가 위치하는 세그먼트이다.

2.스택과 마찬가지로 실행중에 동적으로 할당될 수 잇으며, 리눅스에선 스택 세그먼트와 반대방향으로 자란다.

(충돌을 피하기 위해)

3.C언어에서 malloc() , calloc()등을 호출해 할당받는 메모리가 이 세그먼트에 위치한다.

4.보통 읽기와 쓰기권한이 부여된다.

int main(){
int *heap_data_ptr=
     malloc(sizeof(*heap_data_ptr)); //동적 할당한 힙 영역의 주소를 가르킴
  *heap_data_ptr  = 224255;  //힙 영역에 값을 씀
  printf("%d\n", *heap_data_ptr); //힙 영역의 값을 사용함
  return 0;
  
  }

 

 

ps) 특히 malloc함수를 정말 자주 사용하고있는 나한테  힙세그먼트 라는걸 배우니, 더욱 딥하게 접근하고 알게된것 같다.

'컴퓨터구조&어셈블리어' 카테고리의 다른 글

#6 컴퓨터구조와 명령어  (0) 2022.05.16
#5 컴퓨터 구조2  (0) 2022.05.15
#4 컴퓨터 구조1  (0) 2022.05.14
#3 어셈블리어 스택  (0) 2022.05.13
#2 어셈블리어 연산,비교,분기  (0) 2022.05.12
Comments