다양한 기록

ptr[-1], ptr[-2]가 가지는 의미 본문

보안개론

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이기 때문이다.

 

보호기법이 리눅스랑 맥이랑 좀 다른 것 같다.