ipwn

[Reversing] 함수 프롤로그, 함수 에필로그, 스택 프레임 본문

Reversing

[Reversing] 함수 프롤로그, 함수 에필로그, 스택 프레임

ipwn 2018. 1. 8. 10:46
1. 함수의 호출

함수를 호출할때 스택에 어떻게 PUSH 하고 어떻게 POP할까? 

함수 호출은 크게 다음과 같이 나눠진다.

1. 함수가 사용할 파라미터를 스택에 넣고 함수 시작지점으로 점프(함수 호출)한다.
2. 함수 내에서 사용할 스택프레임을 설정한다. (프롤로그)
3. 함수의 내용을 수행한다.
4. 수행을 마치고 처음 호출한 지점으로 돌아가기 위해 스택을 복원한다(에필로그)

이 때 2번 과정을 프롤로그(Prolog) 라고 부르며, 4번 과정을 에필로그(epilog) 라고 부른다.

함수 프롤로그

베이스포인터(ebp)를 스택에 저장하고 현재 스택포인터(esp)를 베이스포인터(ebp)에다가 저장한다.

push ebp
mov ebp, esp 의 어셈블리어를 이용해 스택 프레임을 설정한다.

함수 에필로그

현재 스택 포인터(esp)를 베이스포인터(ebp)로 복구한 후 베이스 포인터(ebp)를 복구해주고 

ret를 통해 다음에 가야에 adress로 점프한다. 

mov esp, ebp

pop ebp  의 어셈블리어를 이용해 스택을 복원한다.


2. 스택 프레임


스택 프레임이란 ESP(스택 포인터)가 아닌 EBP(베이스 포인터)레지스터를 사용하여 


스택 내의 로컬 변수, 파라미터, 복귀 주소에 접근하는 기법을 말한다.


ESP 레지스터는 스택 포인터 역할을 하고, EBP 레지스터는 베이스 포인터 역할을 합니다. ESP 레지스터의 값은 


프로그램 안에서 수시로 변경되기 때문에 스택에 저장된 변수, 파라미터에 접근하고자 할 때 ESP 값을 기준으로 하면 


프로그램을 만들기 어려워진다. 따라서 어떤 기준 시점(함수 시작)의 ESP 값을 EBP에 저장하고 이를 함수 내에서 


유지해주면, ESP 값이 아무리 바뀌어도 EBP를 기준으로 안전하게 해당 함수의 변수, 파라미터, 복귀 주소에 


접근할 수 있게 되는 것이다. 이러한 역할을 하는것이 EBP레지스터이다.


<스택 프레임의 구조>


스택 프레임을 어셈블리 언어로 보았을때 이런 구조로 되어 있다. 


 PUSH EBP

함수시작(EBP를 사용하기 전에 초기 값을 스택에 저장) 

 MOV EBP, ESP  

; 현재의 ESP를 EBP에 저장 

 

 

 ...

; 함수의 본체 

; 여기서 ESP가 변경되더라도 EBP가 변경되지 않으므로 

; 안전하게 로컬변수와 파라미터를 엑세스할 수 있음 

 

 

 MOV ESP, EBP 

; ESP를 정리(함수가 시작했을 때의 초기값으로 복원) 

 POP EBP

리턴되기 전에 저장해 놓았떤 원래 EBP 값으로 복원

 RETN

; 함수 종료 















이런 식으로 스택 프레임을 이용해서 관리를 한다면 아무리 함수 호출이 복잡해져도 스택을 완벽하게 관리할 수 있게 된다.


'Reversing' 카테고리의 다른 글

[Reversing] 어셈블리어  (0) 2018.01.08
Comments