Array Operations
int val[5];
배열은 많은 경우 공격 대상이 됨
주소 크기는 시스템에 따라 다름
32비트 시스템에선 포인터 32비트 차지
64비트 시스템에선 포인터 64비트 차지 (실제론 48비트만 씀)
val[-3]
val[0]에서 -12바이트 전으로 가서 읽으려고 할 것
퍼미션이 있으면 접근 가능
typedef int zip_dig[5];
zip_dig cmu = {1, 5, 2, 1, 3};
zip_dig mit = {0, 2, 1, 3, 9};
zip_dig ucb = {9, 4, 7, 2, 0};
스택 보호 기법이 있는 경우, 32비트
-> 제일 먼저 선언된게 낮은 주소에 들어감
| ucb [높은주소] .. {9, 4, 7, 2, 0} |
| mit .. {0, 2, 1, 3, 9} |
| cmu [닞은주소] ... {1, 5, 2, 1, 3} |
cmu[8] => 3
cmu[11] => 4
ucb[-5] => 0
ucb[-15] => 뭐가 나올 지 알 수 없음
cmu[12] => 7
mit[-5] => 1
mit[-4] => 5
mit[8] => 2
mit[9] => 0
*(cmu + 9) => 9
*(cmu + 11) => 4
*(mit - 4) => 5
*(ucb - 5) => 0
스택 보호 기법이 없는 경우, 32비트
| cmu [높은주소] .. {1, 5, 2, 1, 3} |
| mit .. {0, 2, 1, 3, 9} |
| ucb [닞은주소] ... {9, 4, 7, 2, 0} |
먼저 선언된게 높은 주소에 할당
mit[-5] => 9
mit[-4] => 4
mit[8] => 1
mit[9] => 3
스택 보호 기법이 있는 경우, 64비트
| ucb [높은주소] .. {9, 4, 7, 2, 0, _, _, _} |
| mit .. {0, 2, 1, 3, 9, _, _, _} |
| cmu [닞은주소] ... {1, 5, 2, 1, 3, _, _, _} |
32비트로 테스트할 땐 딱 맞아도, 64비트로 바꾸니 더미 공간이 생김
** 시스템마다 다를 수 있음
** 배열들의 시작 주소를 보면 더미 공간이 있는지 없는지 알 수 있음
#include <stdio.h>
int main() {
int k = 100;
int a[4] = {0, 1, 2, 3};
int b[4] = {4, 5, 6, 7};
int c[4] = {8, 9, 10, 11};
a[-1] = 91;
a[7] = 92;
a[10] = 93;
c[-2] = 101;
c[-6] = 102;
return 0;
}
스택 보호 있음, 32비트
| c {...} |
| b {...} |
| a {...} |
| k |

k => 91 - (a[-1])
b[3] => 92 - (a[7])
c[2] => 93 - (a[10])
b[2] => 101 - (c[-2])
a[3] => 102 - (c[-6])
스택 보호 없음, 32비트
| k |
| a {...} |
| b {...} |
| c {...} |

b[-3] => 91 - (a[-1])
a[7], a[10], c[-2], c[-6] => 뭘 가리키는지 알 수 없음