study/보안

윈도우 메모리 구조

lucykorea414 2023. 9. 7. 21:56
728x90

섹션

  • 윈도우의 PE 파일은 PE 헤더와 1개 이상의 섹션으로 구성되어 있음
  • 섹션: 유사한 용도로 사용되는 데이터가 모여있는 영역
    • .text: PE의 코드가 적혀있음
    • .data: PE가 실행중에 참조하는 데이터가 적혀있음

 

PE 헤더에 저장되는 섹션에 관한 데이터

  • 섹션의 이름
  • 섹션의 크기
  • 섹션이 로드될 주소의 오프셋
  • 섹션의 속성과 권한

 

.text

  • 실행 가능한 기계 코드가 위치하는 영역
  • 읽기/실행 권한 부여 (프로그램이 동작하려면 실행할 수 있어야함)
  • 쓰기 권한은 제거함 -> 공격자가 악의적인 코드 삽입 가능

ex) 정수 31337을 반환하는 main 함수가 컴파일 되면 554889e5b8697a00005dc3라는 기계코드로 변환되는데, 이 코드가 세그먼트에 위치하게 됨

int main() { return 31337; }

 

 

.data

  • 컴파일 시점에 값이 정해진 전역 변수들이 위치
  • 읽기/쓰기 권한 부여 (CPU가 이 섹션의 데이터를 읽고 쓸 수 있어야함)

ex) .data 섹션에 포함되는 여러 데이터의 유형

int data_num = 31337;
char data_rwstr[] = "writable_data";        // data
int main() { ... }

 

 

 

.rdata

  • 컴파일 시점에 값이 정해진 전역 상수와 참조할 DLL 및 외부 함수들의 정보가 저장됨
  • 읽기 권한 부여 (CPU가 이 섹션의 데이터를 읽어야함)
  • 쓰기 불가능

ex) .rdara 섹션에 포함되는 여러 데이터의 유형

const char data_rostr[] = "readonly_data";
char *str_ptr = "readonly";  // str_ptr은 .data, 문자열은 .rdata
int main() { ... }
  • 여기서 str_ptr 라는 변수는 "readonly"라는 문자열을 가리키고 있는데, str_ptr는 전역 변수로서 .data에 위치하고 "readonly" 는 상수 문자열로 취급되어 .rdata에 위치

 

 

 

섹션이 아닌 메모리

스택

  • 보통 지역 변수나 함수의 리턴 주소가 저장됨
  • 읽기/쓰기 권한 부여
  • '아래로 자람' -> 스택이 확장될 때, 기존 주소보다 낮은 주소로 확장됨

ex) 지역변수 choice가 스택에 저장

void func() {
  int choice = 0;
  scanf("%d", &choice);
  if (choice)
    call_true();
  else
    call_false();
  return 0;
}
  • scanf로 받음 -> 스택에 저장됨

 

 

  • 모든 종류의 데이터가 저장됨
  • 스택보다 큰 데이터 저장 가능
  • 전역적으로 접근 가능
  • 실행 중 동적으로 할당받음
  • 보통 읽기/쓰기 권한을 가짐 (어떨 때는 실행 권한도 가짐)

ex) heap_data_ptr에 malloc()으로 동적 할당한 영역의 주소를 대입하고, 이 영역에 값을 씀.

int main() {
  int *heap_data_ptr =
      malloc(sizeof(*heap_data_ptr));  // 동적 할당한 힙 영역의 주소를 가리킴
  *heap_data_ptr = 31337;              // 힙 영역에 값을 씀
  printf("%d\n", *heap_data_ptr);  // 힙 영역의 값을 사용함
  return 0;
}
  • heap_data_ptr에 malloc()으로 동적 할당한 영역의 주소를 대입하고, 이 영역에 값을 씀.
  • heap_data_ptr은 지역변수이므로 스택에 위치하고 malloc 으로 할당받은 힙 세그먼트의 주소를 가리킴
728x90