코딩공작소
버퍼오버플로우 본문
오버플로우를 이해하기 전에 먼저 call명령어에 대해서 이해해야한다.
Main 영역에서 새로운 함수가 실행될 때, 그 함수가 끝나고 나서 돌아올 곳을 return-address라 한다.
foo라는 함수를 호출하게 되면 return-address는 그 다음 명령어인 mov의 주소값인 0x080484e4로 지정되게 되는 것이다.
call 0x804849c <foo> 의 의미는 foo함수를 호출하겠다는 의미이고 Code Area에 foo라는 함수는 0x804849c에 위치에서부터 시작한다는 것을 알 수 있다.
call함수의 명령 실행과정은 아래와 같다.
*call x --> push ret-add --> jump x
*push명령어가 있으므로 esp를 4만큼 감소시킨후 mem[esp]<-ret-add를 입력해준 후, x의 Code area로 이동(foo를 하게 된다.
그림과 같이 4가 감소된 esp의 stack부분에 데이터에 E4 84 04 08(return - address)이 입력되어 있음을 알 수 있다.
08 <- FFFFD5F0
04 <- FFFFD5EF
84 <- FFFFD5ED
E4 <- FFFFD5EC
함수에서 캐릭터배열을 선언하게 되면 stack영역에 적당한 위치에 맞게 주소가 선언된다.
디버깅을 통해 그 캐릭터배열의 시작 주소를 찾아낼 수 있다.
캐릭터배열을 scanf함수를 통해 받게 될때, 주어진 크기보다 길게 입력해서
ret-add까지 변경하게 되는 경우를 Stack overflow라 한다.
이러한 경우 , 함수가 종료되었을 때, 리턴을 제대로 하지 못하는 경우가 발생된다.
즉, 캐릭터배열과 ret-add까지의 거리를 계산하고, 그에 맞게 ret-add를 바꿔줄수 있는 것이다.