함수의 프롤로그(prologue) 및 에필로그(epilogue)

Posted by dw0rdptr
2015. 4. 10. 03:51 System/LOB
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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkknight
        - FPO
*/
 
#include <stdio.h>
#include <stdlib.h>
 
void problem_child(char *src)
{
    char buffer[40];
    strncpy(buffer, src, 41);
    printf("%s\n", buffer);
}
 
main(int argc, char *argv[])
{
    if(argc<2){
        printf("argv error\n");
        exit(0);
    }
 
    problem_child(argv[1]);
}
cs

r

LOB darkknight의 소스이다. strncpy함수를 호출하는데 딱 1바이트만 오버플로우를 일으킬 수 있다.

이문제는 FPO(Frame Pointer Overflow)기법으로 풀어야 하는데 그전에 함수 프롤로그와 에필로그를 먼저 이해해야 한다.



참고) mov %esp(source),%ebp(destination)   -> AT&T 문법

  mov ebp(destination), esp(source)        -> intel 문법       

둘은 같은 명령을 의미(표기방법의 차이. 자세한건 구글신)


main에서 p(problem_child)함수를 호출했다.

어셈블리에선 생략되어있지만 우선 ret이 생성된다.

higher address

------------

      ret

------------ <-esp

lower address



먼저 push %ebp를 한다. 현재 ebp에는 main함수의 frame pointer(base pointer라고도 함)값이 있는데 이를 push해서 저장한 공간을 sfp(saved frame pointer) 라고 한다. push하였기 때문에 esp가 움직인다.

higher address

------------

      ret

------------

sfp(main의 ebp)

------------ <- esp

lower address



그리고 mov %esp, %ebp로 현재의 esp값을 ebp에 넣는다.(ebp를 esp로 이동시킨다)

현재까지의 스택상황을 보면

higher address

------------

      ret

------------

sfp

------------ <- ebp,esp

lower address


지금 ebp의 위치가 p함수의 frame pointer가 되는것이다

여기까지가 함수 프롤로그.



이제 p함수내에서 버퍼를 선언하면

higher address

------------

      ret

------------

sfp

------------ <- ebp


  buffer[40]

------------ <- esp

lower address


이렇게 esp에서 할당할 만큼의 공간을 빼면서 진행한다




* 아무래도 intel문법이 편해서 지금부턴 intel문법을 쓰겠다.




함수에필로그 과정은  leave와 ret이 있다

각각의 부분에서 실행하는 명령어는 다음과 같다

leave

ret

mov esp, ebp

 pop eip

pop ebp

 jmp eip


먼저 leave에서 p함수는 mov esp, ebp로 그동안 함수내에서 진행한 esp를 ebp값으로 돌려놓는다, 즉 위에서 진행했던 p함수의 프롤로그가 진행된 직후 상태로 되돌린다.

higher address

------------

      ret

------------

sfp

------------ <- ebp,esp

lower address




그리고 pop ebp명령어를 통해 sfp에 들어있던 main의 frame pointer 값이 ebp로 들어가게 된다 (ebp는 이제 main의 frame pointer를 가리키게 됨) pop했으니 esp 4증가.

higher address

------------

      ret

------------ <- esp

lower address



마지막으로 pop eip를 하면 ret에 있는 주소가 eip에 들어가게되고 jmp eip로 점프해 main함수 안의 p함수를 호출한 직후로 가게된다.





darkknight의 풀이는 다음글에서 다룰것이다. 이 글을 이해했으면 굳이 다음 글을 읽지 않아도 해결할 수 있을 것이다.



'System > LOB' 카테고리의 다른 글

[LOB] darkknight -> bugbear  (0) 2015.04.12
[LOB] golem -> darkknight  (0) 2015.04.11
[LOB] skeleton -> golem  (0) 2015.04.07
[LOB] vampire -> skeleton  (0) 2015.04.01
[LOB] troll -> vampire  (0) 2015.04.01