힙 오버플로우/ 스택 오버플로우

 

 

  • 힙 영역에서는 malloc 에 의해 메모리가 더 할당될수록, 점점 사용하는 메모리의 범위가 아래로 늘어남
  • 마찬가지로 스택 영역에서도 함수가 더 많이 호출 될수록 사용하는 메모리의 범위가 점점 위로 늘어남
  • 이렇게 점점 늘어나다 보면 제한된 메모리 용량 하에서는 기존의 값을 침범하는 상황도 발생
  • 이를 힙 오버플로우 또는 스택 오버플로우라고 한다.

 

사용자에게 입력 받기

스택은 우리가 여태껏 많이 써왔던 get_int나 get_string 과 같은 함수에서도 사용된다. 만약 이런 함수들을 직접 구현한다면 아래와 같은 코드가 될 것

 

[get_int 코드]

 

[get_string 코드]

 

 

  • 위 코드들에서 scanf라는 함수사용자로부터 형식 지정자에 해당되는 값을 입력받아 저장하는 함수
  • get_int 코드에서 int x를 정의한 후에 scanf에 s가 아닌 &x로 그 주소를 입력해주는 부분을 유의하기
  • scanf 함수의 변수가 실제로 스택 영역 안에 x가 저장된 주소로 찾아가서 사용자가 입력한 값을 저장하도록 하기 위함
  • 반면 get_string 코드에서는 scanf에 그대로 s를 입력해줬다.
  • 그 이유는 s를 크기가 5인 문자열, 즉 크기가 5인 char 자료형의 배열로 정의하였기 때문
  • clang 컴파일러는 문자 배열의 이름을 포인터처럼 다룹니다. 즉 scanf에 s라는 배열의 첫 바이트 주소를 넘겨주는 것

 

파일 쓰기

사용자로부터 입력을 받아 파일에 저장하는 프로그램도 작성하기

  • fopen이라는 함수를 이용하면 파일을 FILE이라는 자료형으로 불러올 수 있다.
  • fopen 함수의 첫번째 인자는 파일의 이름, 두번째 인자는 모드로 r은 읽기, w는 쓰기, a는 덧붙이기를 의미
  • 사용자에게 name과 number라는 문자열을 입력 받고, 이를 fprintf 함수를 이용하여 printf에서처럼 파일에 직접 내용을 출력할 수 있다.
  • 작업이 끝난 후에는 fclose함수로 파일에 대한 작업을 종료해줘야 한다.

 

파일 읽기

파일의 내용을 읽어서 파일의 형식이 JPEG 이미지인지를 검사하는 프로그램을 작성하기

 

 

  • 위 코드에서 main 함수를 보면 사용자로부터 입력을 받는 것을 알 수 있다. 여기서는 파일의 이름을 입력으로 받을 예정
  • 만약 argc가 2가 아니라면, 파일명이 입력되지 않았거나 파일명 외의 다른 인자가 입력되었기 때문에 1(오류)을 리턴하고 프로그램을 종료
  • 만약 argc가 2라면 프로그램이 그대로 진행
  • 입력받은 파일명(argv[1])을 ‘읽기(r)’ 모드로 불러옴
  • 만약 파일이 제대로 열리지 않으면 fopen 함수는 NULL을 리턴하기 때문에 이를 검사해서 file을 제대로 쓸 수 있는지를 검사하고 아니라면 역시 1(오류)를 리턴하고 프로그램을 종료
  • 만약 파일이 잘 열렸다면, 프로그램이 계속 진행
  • 그 후 크기가 3인 문자 배열을 만들고, fread 함수를 이용해서 파일에서 첫 3바이트를 읽어옴
  • fread 함수의 각 인자는 (배열, 읽을 바이트 수, 읽을 횟수, 읽을 파일)을 의미
  • 그리고 마지막으로 읽어들인 각 바이트가 각각 0xFF, 0xD8, 0xFF 인지를 확인
  • 이는 JPEG 형식의 파일을 정의할 때 만든 약속으로, JPEG 파일의 시작점에 꼭 포함되어 있어야 함
  • 따라서 이를 검사하면 JPEG 파일인지를 확인할 수 있다.

디지털 포렌식에서 쓰이는 매직 넘버들
.jpg는 FFD8 / .gif는 47 49 46 38 [GIF89] / .png는  89 50 4E 47 .PNG
사진파일 확장자 뿐만아니라 .mp3 49 44 33 [ID3] / .avi 52 49 46 46 [RIFF] / .zip 50 4B 03 04 [PK]
등이 있다.

 

 

 

+ Recent posts