IT/시스템 보안

[Stack Frame] 프로시저 호출 시의 스택 프레임 살펴보기

kykyky 2024. 2. 20. 04:43

코드가 쭉 진행되다가 특정 프로시저가 호출되면, 프로시저가 실행되고 나서 다시 원래의 실행 흐름으로 돌아옵니다.
 

예시 코드

 
0x400000: call func: push  &  jmp 
0x400005: mov esi, eax
...

0x401000: push rbp 
0x401001: mov rbp, rsp 
0x401004: sub rsp, 0x30 
0x401008: mov BYTE PTR[rsp], 0x3 
...
0x401020: leave: mov rsp, rbp  &  pop rbp 
0x401021: ret: pop rip  &  jmp rip 

 

 

빠르게 보는 전 과정의 메모리 변화

 

 

상세한 작동

 

1. 프로시저 호출
2. function prologue: 기존 상태의 기록, 새로운 stack frame의 마련
3. 호출된 프로시저가 새 stack frame을 사용함
4. function epilogue: 원래의 실행 흐름으로 복구
5. 다음 코드가 실행됨
 
 
 
 

call 전

 
 
✅ 0x400000: call func: push  &  jmp
➡️ return address (프로시저 호출이 없었다면 원래 흘러갔을 다음 코드의 주소: 0x400005)를 stack에 저장한 뒤, 호출한 프로시저의 첫 번째 코드 위치로 jump 

 
 

call 후, push 전

 
 
✅ 0x401000: push rbp 
➡️ 현재의 rbp를 stack에 저장

 
 

push 후, mov 전

 
 
✅ 0x401001: mov rbp, rsp 
➡️ 새 stack frame을 형성하기 위해, rbp를 rsp와 같은 곳을 가리키게 함
 
 

mov 후, sub 전

 
 
✅ 0x401004: sub rsp, 0x30 
➡️ rsp에서 0x30만큼을 뺌으로써, 새 stack frame의 공간을 할당

 

sub 후, mov 전

 
 
✅ 0x401008: mov BYTE PTR[rsp], 0x3 
➡️ 할당된 stack frame 공간에 지역변수 할당

 
 

mov 후, leave 전

 

mov 후, leave 전

 
 
 
✅ 0x401020: leave: mov rsp, rbp  &  pop rbp 
➡️ rsp를 rbp와 같은 곳을 가리키게 함으로써 stack이 쪼그라들고,
현재 stack의 top에 있는 값 (= 이전 rbp)을 꺼내 rbp에 할당함으로써 rbp가 이전 위치로 복귀

 
 

leave 후, ret 전

 
 
 
✅ 0x401021: ret: pop rip  &  jmp rip 
➡️ 현재 stack의 top에 있는 값 (= return address)을 꺼내 rip에 할당함으로써 rip가 return address를 가리키게 하고,
이 address로 jump함으로써 원래의 실행 흐름으로 복귀
 
 

ret 후

 
 
0x400005: mov esi, eax