일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- leetcode 5
- 블로그 이전했어요
- leetcode 561
- 배열
- leetcode 49
- leetcode 344
- ctf-d
- docker로 airflow 설치하기
- leetcode 234
- leetcode 937
- leetcode 238
- leetcode 819
- 스파크 완벽 가이드
- 문자열 조작
- Hortonworks Sandbox
- leetcode125
- Hadoop
- Python
- 데이터레이크와 데이터웨어하우스
- leetcode
- wargame.kr
- leetcode 121
- webcrawler
- MapReduce 실습
- leetcode 15
- airflow docker
- 올바른 변수명 짓기
- 머신러닝
- 컴퓨터구조
- 빅데이터를 지탱하는 기술
- Today
- Total
HyeM
[0]Stack & StackFrame 본문
#1. Stack
# 스택 : 함수 호출과 관련된 지역변수와 매개변수가 저장되는 영역으로 , FILO(First In Last Out)구조이다.
*FILO(First In Last Out) : 먼저 들어간 것(push)이 나중에 나온다.(pop) // 스택은 이와 달리 FIFO(First In First Out)
# 프로세스에서 스택 메모리의 역할
1. 함수 내의 지역변수 임시저장
2. 함수 호출시 파라미터 전달 (매개변수 저장)
3. 복귀 주소(return address) 저장
# 스택의 특징
"스택은 거꾸로 자란다." : 높은 주소에서 낮은 주소로 스택이 자란다.
프로세스에서 일반적으로 ESP(스택포인터)는 초기값으로 스택의 아래쪽(높은 주소)에 가깝다.
Push 명령어로 스택이 쌓이면 ESP는 stack Top(낮은주소;위)로 움직이고,
POP 명령어에 의해 스택이 제거되면서 ESP는 stack Bottom(높은주소;아래)으로 움직인다.
즉, 스택은 아래(높은주소)-> 위(낮은주소)로 자란다.
#2. StackFrame
# 스택프레임 : 프로그램에서 선언되는 로컬 변수와 함수 호출에 사용된다.
ESP(스택포인터)가 아닌 EBP(베이스포인터)레지스터를 사용하여, 스택의 로컬변수, 파라미터, 복귀 주소에 접근하는 것을 말한다.
※ EBP 레지스터를 사용하는 이유 :
ESP레지스터는 프로그램 안에서 수시로 변경되기 때문에, ESP값을 기준으로 스택에 저장된 변수나 파라미터에 접근하기 어렵다.
따라서, 함수시작과 같은 어떤 기준점의 ESP값을 EBP에 저장하여 함수 내에서 유지하면, ESP값이 아무리 변해도 미리 저장한 EBP를 기준으로 해당함수의 변수, 파라미터, 복귀 주소에 접근할 수 있다.
즉, EBP는 베이스 포인터 역할로, 이전에 가지고 있던 값을 스택에 백업해 두기 위한 용도이다.
스택프레임은 main()함수 시작하자마자 생성된다.
# 예제
int main(void)
{
func1();
return 0;
}
void func1(){
func2();
}
void func2(){
}
위의 코드에서 함수 실행 순서는 다음과 같다.
main1( ) -> func1( ) 호출 -> func2( ) 호출 -> func2( ) 종료 -> func1( )종료 -> main( )종료
위의 코드를 예제로 하여 스택프레임이 어떻게 형성되는 지 알아보자.
Step 1. main()
프로그램 실행되면, main이 가장 먼저 호출되고, main함수의 스택 프레임이 스택에 저장된다.
Step 2. func1() 호출
main에서 func1을 호출하면, 함수 호출시의 매개변수, 반환 주소값, 지역변수 등의 스택프레임이 스택에 저장된다.
Step 3. func2() 호출
func1에서 func2를 호출하면, func2의 스택프레임이 스택에 새롭게 추가된다.
Step 4. func2 () 종료
fun2 함수의 모든 작업이 완료되어 반환되면, fun2의 스택프레임이 스택에서 제거된다.
Step 5. func1 () 종료
fun1 함수의 모든 작업이 완료되어 반환되면, fun1의 스택프레임이 스택에서 제거된다.
Step 6. main() 종료
main의 모든 작업이 완료되면, main의 스택프레임도 스택에서 제거되면서 프로그램이 종료된다.
++어셈블리어로 알아보기++
함수 시작
PUSH EBP 함수 시작하니, 이전의 EBP값을 스택에 저장함
MOV EBP, ESP 그리고 함수시작위치를 가리키고있는 ESP값을 EBP에 저장
( 스택엔 이전 함수 위치를 저장, EBP에는 새 함수시작 주소)
함수 끝
MOV ESP, EBP 함수가 끝이니, 함수시작 주소로 돌아가기 위해 EBP값을 ESP에 넘겨준다.
POP EBP 리턴전에 저장해 놓은 EBP값을 복원한다.
RETN
(EBP에는 함수 시작 위치가 들어있었는데, 함수가 끝나니 이를 ESP에게 넘기고, 스택에서 저장해 놓았던 전 EBP값으로 복원)
'스택 FILO' 이미지 출처 : velog.io/@jangwonyoon/TIL20.03.19-Immersive-4-2
'스택특징' 이미지 출처 : m.blog.naver.com/PostView.nhn?blogId=aaasssddd25&logNo=220908525653&proxyReferer=https:%2F%2Fwww.google.com%2F
'스택프레임 예제' 이미지 출처 : tcpschool.com/c/c_memory_stackframe
'Study > Reversing' 카테고리의 다른 글
[2]PE구조&wow64 fs redirection + a (0) | 2020.09.20 |
---|---|
[1]호출규약 + wargame 정리 + a (0) | 2020.09.14 |
[1]Dreamhack_Rev 0번 문제 (0) | 2020.09.12 |
[1]abex' crackme #1 (0) | 2020.09.12 |
[0]32bit Register (0) | 2020.09.05 |