본문 바로가기
.study/pwnable

[포너블 기초] 스택 프레임

by Carry_on 2023. 9. 12.

 

스택 프레임(Stack Frame)이란 함수가 호출될 때, 그 함수만의 스택 영역을 구분하기 위하여 생성되는 공간이다. 이 공간에는 함수와 관계되는 지역 변수, 매개변수가 저장되며, 함수 호출 시 할당되고, 함수가 종료될때 소멸한다. 이렇게 스택 영역에 차례대로 저장되는 함수의 호출 정보를 스택 프레임이라고 하며, 스택 프레임 덕분에 함수의 호출이 모두 끝난 뒤에, 해당 함수가 호출되기 이전 상태로 되돌아갈 수 있다.

 

아래에서 부터는 자주 사용하는 어셈블리어에 대해 알아보고 간단한 예제를 통해 스택 프레임에 대해 알아보겠다.

 

자주 사용하는 어셈블리 명령어와 사용 예시

push

push eax: eax의 값을 스택에 저장한다.

pop

pop eax: 스택의 가장 상위에 있는 값을 꺼내서 eax에 저장한다.

mov

mov eax, ebx: eax에 ebx의 값을 넣는다.

inc

inc eax: eax의 값을 1증가시킨다.

dec

dec eax: eax의 값을 1감소시킨다.

add

add eax,ebx:eax와 ebx의 값을 더하여 eax에 저장한다.

sub

sub eax, ebx: eax에 ebx를 뺀 값을 eax에 저장한다.

call

call proc: 프로시저를 호출한다.

ret: 호출했던 바로 다음 지점으로 이동한다

cmp

cmp eax, ebx eax와 ebx의 값을 비교한다.

jump

jump proc: 특정한 곳으로 분기한다.

nop: 아무것도 하지않는다.

 

참고한 블로그: https://jiravvit.tistory.com/entry/%EC%8A%A4%ED%83%9D-%ED%94%84%EB%A0%88%EC%9E%84-Stack-Frame

 

스택 프레임 (Stack Frame)

출처 : 동빈나님 유튜브 youtu.be/TxWOaKE5w_s 유튜브를 보며 공부하던 중 두고두고 복습이 필요할 것 같아 정리를 하려고 한다.. 스택 프레임(Stack Frame)을 이해하기 위해서 간단한 예제를 만들어보겠

jiravvit.tistory.com

 

먼저 간단한 예제를 작성한 후

sum.c를 어셈블리어인 sum.a로 변환해주었다.

실습을 위해 -fno-stack-protector 옵션을 이용하여 보호기능을 꺼주었다.

 

main()함수에서 sum()함수를 호출했을 때의 스택모양을 간단히 나타내면 다음과 같다.

이제 코드에서 main()에서 sum()을 call하는 부분까지를 살펴보겠다.

 

        pushq   %rbp // RBP를 push해서 RET 위로 집어넣는다.
        movq    %rsp, %rbp // rsp를 rbp로 이동시켜 동일한 위치를 가리키게 한다.
        subq    $16, %rsp // rsp를 16만큼 빼주어서 16만큼의 공간을 확보한다.
        movl    $2, %esi //esi에 2를 넣는다.
        movl    $1, %edi // edi에 1을 넣는다.
        call    sum // sum 함수를 호출한다.

 

이걸 그림으로 나타내면 아래와 같다.

이제 sum 함수를 살펴보자.

        pushq   %rbp                // RBP를 push해서 RET 위로 들어가게 된다.
        movq    %rsp, %rbp     // rsp를 rbp로 이동시켜 같은 위치를 가리키게 한다.
        movl    %edi, -4(%rbp) // 1을 넣는다
        movl    %esi, -8(%rbp) // 2를 넣는다
        movl    -4(%rbp), %edx // 1의 값을 edx 레지스터에 넣는다.
        movl    -8(%rbp), %eax // 2의 값을 eax 레지스터에 넣는다.
        addl    %edx, %eax // edx값을 eax에 더해준다.
        popq    %rbp // rbp를 pop하여 ret으로 돌아가게 한다.

sum 함수 실행
sum 함수 종료

이제 아까 보지 못했던 main()의 남은 부분을 살펴보자.

 

        movl    %eax, -4(%rbp) // eax에 저장된 3을 rbp-4의 위치에 넣는다.
        movl    -4(%rbp), %eax // 3을 다시 eax에 넣는다.
        leave

        ret // 3이 반환된다.

'.study > pwnable' 카테고리의 다른 글

[포너블 기초] 함수 호출 규약  (0) 2023.09.14
[포너블 기초] Docker  (0) 2023.09.13
[포너블 기초] x86-32, x86-64 레지스터  (0) 2023.09.12
[포너블 기초] 메모리 구조  (0) 2023.09.11
[포너블 기초] 컴퓨터 구조  (0) 2023.09.10