로컬 변수 저장, 함수 파라미터 전달, 복귀 주소 저장 등의 다양한 용도로 사용되는 스택(Stack)에 대한 내용입니다.
프로세스에서 스택 메모리의 역할
1. 함수 내의 로컬 변수 임시 저장
2. 함수 호출 시 파라미터 전달
3. 복귀 주소(return address) 저장
이런 역할을 수행할 때는 스택의 FILO(First In Last Out) 구조가 유용합니다.
프로세스에서 스택 포인터(ESP)의 초기 값은 Stack Bottom쪽에 가깝습니다. PUSH 명령에 의해서 Stack에 값이 추가되면 스택 포인터는 Stack Top을 향해 (위쪽으로) 움직이고, POP 명령에 의해 스택에서 값이 제거되면 스택 포인터는 Stack Bottom을 향해 (아래쪽으로) 움직입니다.
즉 높은 주소에서 낮은 주소 방향으로 스택이 자라납니다. (아래에서 윗 방향) 이런 스택의 특성 때문에 보통 "스택은 거꾸로 자란다."
라는 표현을 쓰기도 합니다.
스택이라는 단어는 무언가를 쌓는다라는 뜻이기 때문에 쌓을수록 위로 올라오는 것이 직관적이기 때문입니다.
초기 상태의 스택입니다. 스택 포인터(ESP)의 값은 19FF74입니다. 우측 하단의 스택 창에는 ESP가 가리키는 주소와 그 값을 보여줍니다.
Step Into[F7] 명령으로 401000 주소의 PUSH 100 명령을 실행합니다.
PUSH 100 명령을 실행하자 ESP 값이 19FF70으로 4바이트만큼 줄어든 것을 볼 수 있습니다. 스택 포인터(ESP)가 가리키는 주소 19FF70에는 PUSH 명령에 의해 100이 저장되어 있습니다.
스택에 값을 집어 넣었더니 ESP가 위쪽 방향으로 이동한 것을 볼 수 있습니다.(ESP 값이 4만큼 줄어듬.) 다시 Step Into[F7] 명령으로 401005 주소의 POP EAX 명령을 실행합니다.
ESP의 값은 다시 4바이트만큼 증가하여 19FF74가 되었고, 스택은 초기 상태와 같아졌습니다.
스택에서 값을 꺼냈더니 ESP는 아래 방향으로 이동하였습니다.
스택에 값을 넣을 때와 꺼낼 때 스택 포인터의 변화
스택의 특징은 스택 포인터의 초기 값이 스택 메모리의 아래쪽에 있다는 것입니다.
ⓒ 리버싱 핵심 원리