CS/Computer Architecture

함수의 프롤로그 & 에필로그

min_zu 2024. 8. 22. 22:11
728x90
반응형
.text:00401000 55                                      push    ebp
.text:00401001 8B EC                                   mov     ebp, esp
.text:00401003 68 F8 20 40 00                          push    offset Buffer   ; "Hello World :)"
.text:00401008 FF 15 B0 20 40 00                       call    ds:__imp__puts
.text:0040100E 83 C4 04                                add     esp, 4
.text:00401011 FF 15 B4 20 40 00                       call    ds:__imp__getchar
.text:00401017 33 C0                                   xor     eax, eax
.text:00401019 5D                                      leave
.text:0040101A C3                                      ret
.text:0040101A                         _main           endp

간단한 함수를 통해 프롤로그와 에필로그의 예시를 보고자 한다

해당 프로그램은 Hello world 를 출력하고 getchar()를 실행한다

더보기

[ printf와 puts ]

만약 해당 프로그램이 printf 함수로 짠 프로그램이더라도, 변수에 대한 출력이 없으면 자동으로 리버싱할 때 puts로 인식한다

함수는 언제나 시작하기 전 프롤로그 과정을, 마치고는 에필로그 과정을 거친다. 

이는 원활한 함수의 실행을 위해 필요한 부분이다

 

함수를 시작하기 전, EIP는 함수의 시작점을 가리키고 있고, ESP는 스택 프레임의 맨 꼭대기를 가리키고 있다

* ESP가 가리키는 공간은 해당 공간에 push, pop을 하는 곳

함수는 연속적으로 수행되기 때문에, 이전에 수행하는 함수의 데이터를 꾸준히 보존해주어야한다. 이런 과정을 함수에 프롤로그에서 진행함

프롤로그

이전에 사용하던 함수의 데이터를 보존하기 위해 진행하는 작업
함수가 시작될 때 stack pointer와 base pointer을 새로 지정한다

 

push ebp

이전 함수의 base pointer를 저장하고 esp를 4바이트 아래로 내린다

mov ebp, esp

호출된 함수의 시작을 지정하기 위해 esp를 ebp 위치로 옮긴다

 

프롤로그 실행 후

스택에서 SFP 라고 불리는 이전 함수의 EBP를 저장하는 부분과, 함수의 스택 시작 부분을 지정하는 역할을 프롤로그에서 하게 된다

 

에필로그

해당 함수를 호출한 함수로 돌아오기 위해 스택을 정리하는 과정
leave

leave는 두 개의 명령어로 표현할 수 있다

mov esp, ebp
pop ebp

함수를 진행하면서 이동한 esp를 다시 ebp의 위치로 이동시킨다

현재 esp가 가리키고 있는 ebp, 즉 SFP를 스택 프레임에서 뺀다

 

ret

ret는 아래 명령어로 표현할 수 있다

pop eip
jmp eip

esp가 가리키는 return addr에 eip를 옮긴다. 즉, 다음에 실행할 주소를 가리키도록 한다

다음에 실행할 주소로 점프한다

 

 

에필로그 실행 후

728x90
반응형