반응형




안녕들 하시죠!


오늘은 스택 프레임에 대해 알아보겠습니다.


스택 프레임은 프로그램에서 선언되는 로컬 변수와 함수 호출에 사용됩니다.

이번 실습을 진행하기 위해서는 지난시간에 공부했던 'IA-32 Register' 의 ESP, EBP 개념이 필요합니다.


ESP는 스택포인터로서 프로그램 안에서 ESP 레지스터는 수시로 변경되기 때문에 스택에 저장된 변수, 파라미터에 접근하고자 할 때 ESP 값을 기준으로 하면 프로그램을 만들기 힘들고, CPU가 정확한 위치를 참고할 때 어려움이 있습니다.

따라서, 어떤 기준 시점( 함수 시작 )의 ESP값을 -> EBP에 저장하고 이를 함수내에서 유지해줍니다.

그러면 ESP값이 아무리 변하더라고 EBP를 기준으로 안전하게 해당 함수의 변수, 파라미터, 복귀 주소에 접근이 가능합니다.

이것이 EBP 레지스터의 베이스 포인터 역할입니다.


PUSH EBP  

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


MOV EBP, ESP

현재의 ESP( 스택포인터 ) 를 EBP에 저장.


///


함수 본체 

여기서 ESP가 변경되더라도 EBP에 저장되어 있으므로 안전하게 로컬 변수와 파라미터를 엑세스 할 수 있다.


///


MOV ESP, EBP

ESP를 정리 ( 함수 시작했을 때의 값으로 복원시킴 )


POP EBP

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


RETN

함수종료


이런 식으로 스택 프레임을 이용해 함수 호출을 관리하면 스택을 완벽하게 관리할 수 있습니다.


이제, 아주 간단한 프로그램을 통해 스택 프레임을 이해해보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
// StackFrame.cpp
#include<stdio.h>
 
long add(long a, long b){
    long x = a, y = b;
    return (x+y);
}
 
int main(int argc, char* argv[]){
    long a = 1, b = 2;
    printf("%d\n", add(a,b));
    return 0;
}
cs


위에있는 코드를 StackFrame.exe로 빌드한 후 Ollydbg를 이용해 열어보겠습니다.

아래에 파일도 같이 첨부하겠습니다.


StackFrame.exe



Go to 명령어로 401000 주소로 이동하겠습니다.


위에 올렸던 코드를 부분부분 찾아 이해해보겠습니다. 


1. StackFrame.exe


1.1. Main() 함수 


우선, Main() 함수 부분 ( 201020 ) 주소 에 BP를 설치[F2] 한 후 [F9]로 실행하겠습니다.




ESP 19FF3C, EBP 19FF80 이고 아래 ④번을 보시면 ESP가 가리키고 있는 19FF3C에 저장된 값 401250은 Main() 함수의 실행이 끝난 후,

돌아갈 리턴 주소입니다.


00401020        PUSH EBP

위의 명령은 'EBP값을 스택에 집어넣어라' 라는 뜻입니다. 

Main() 함수에서 EBP가 베이스 포인터의 역할을 하게 될테니 EBP가 이전에 가지고 있던 값을 스택에 백업해두기 위함입니다.


00401021        MOV EBP, ESP

위의 명령은 'ESP값을 EBP로 옮겨라' 라는 뜻입니다.



이젠 ESP와 EBP 둘다 19F88값을 가지게 되었구요, 19FF80 주소에는 19FF80이라는 값이 저장되어 있습니다.

19FF80은 Main() 함수가 시작할 때 EBP가 가지고 있던 초기 값입니다.


1.2. 지역 변수



로컬 변수 ( a, b )를 위한 공간을 만들고 값을 입력한다.

위의 명령은 'ESP 값에서 8을 빼라' 라는 뜻입니다.



위의 자료형 크기표를 보시면 long 은 4byte로 되어있습니다.

a 와 b 는 long 타입으로 선언되었습니다.

long 타입이 2개이니 8byte를 SUB로 빼주면 a와 b 두 변수가 스택에 저장될 공간이 생기게 됩니다.


위의 명령은 '[EBP-4] 에는 1을 넣고, [EBP-8] 에는 2를 넣어라' 입니다.



다음 게시물에 이어서...



참고서적 이승원 「리버싱 핵심원리」 인사이트(2018) p75~82

+ Recent posts