보안개론
ptr[-1], ptr[-2]가 가지는 의미
라구넹
2024. 5. 19. 01:56
#include <stdio.h>
int main() {
int num1 = 10;
int arr[5] = {50, 51, 52, 53, 53};
int num2 = 90;
int *ptr = arr;
printf("addr of num1 = %p\n", &num1);
printf("addr of arr[0] = %p\n", &arr[0]);
printf("addr of arr[1] = %p\n", &arr[1]);
printf("addr of num2 = %p\n", &num2);
printf("addr of ptr = %p\n\n", &ptr);
printf("arr = %p, %x\n", arr, (unsigned int)arr);
printf("ptr = %p, %x\n", ptr, (unsigned int)arr);
printf("*arr = %d, *ptr = %d\n", *arr, *ptr);
printf("ptr[0] = %d, ptr[1] = %d\n", ptr[0], ptr[1]);
printf("ptr[2] = %d, ptr[3] = %d\n", ptr[2], ptr[3]);
printf("ptr[-1] = %d, ptr[-2] = %d\n", ptr[-1], ptr[-2]);
return 0;
}
- 스택 보호 기법 있는 경우
ptr[-2] : 90
일반적으로 스택은 위에서 아래로 쌓이는데,
보호 기법 때문에 배열을 제외한 일반적인 변수를 낮은 주소에 먼저하고 배열을 나중에 할당
왼쪽이 낮은 주소라 하면
num1 - num2 - ptr - arr[0] - arr[1] .. 순서로 할당될 것, 이라고는 할 수 있는데 환경따라 다름
ptr이 가리키는게 arr이니, ptr[-2]는 90이 된다.

Mac OS에선 그냥 배열만 나중으로 빼고 위에서부터 넣는 것처럼 보이긴 하는데,
num1 에서 int가 4바이트인데도 arr과의 차이가 8바이트이다.
ptr - num2 - num1 - arr[0] - arr[1] 순서인데,

num1과 arr의 차이가 8바이트라 ptr[-2]가 num1을 가리키게 되어 10을 보인다.
- 스택의 보호 기법 해제 시
ptr[-1]이 90을 가지게 됨
ptr - num2 - arr[0] - arr[1] - num1 순서

보호를 해제하니 예상대로 ptr[-1]이 90이 나온다.
arr[0] 바로 밑에 저장된 값이 num2이기 때문이다.
보호기법이 리눅스랑 맥이랑 좀 다른 것 같다.