스택프레임 생성

push rbp
mov rbp, rsp
라는 어셈블리 코드가 스택프레임을 생성하는 코드라고 하는데 혹시 위 코드가 어떠한 방식으로 스택프레임을 생성하게 되는지 자세한 과정을 설명해주실 수 있나요.. 계속 생각을 해봐도 이해가 가지 않습니다.

#리버싱 #배경지식
작성자 정보
답변 2
avatar
wyv3rn
무플 방지 위원회장

이걸 어디부터 알려드려야할지... ㅠㅠ

해당 코드는 일반적으로 함수에 진입했을때 제일 처음 실행되는 코드입니다.

push rbp
mov rbp rsp
sub 0x10 rsp
와 같은 코드가 일반적입니다.

프로그램이 a 함수 내에서 b 함수를 호출한다고 가정합시다.

rbp는 함수에서 사용되는 스택의 가장 낮은 지점(큰 주소값)을 나타냅니다.
rsp는 함수에서 사용되는 스택의 가장 높은 지점(작은 주소값)을 나타냅니다.

이 둘 사이의 공간이 해댕 함수가 사용하는 스택이고요.

a 함수 중간즈음에서 b함수를 호출하면 b가 종료된 뒤 다시 a로 돌아가야하는데
a가 사용하던 스택의 공간은 훼손하지 않은 채 b가 사용할 공간을 새로 할당해야하기 때문에
a가 사용하던 가장 낮은 지점의 주소를 저장하고 이 다음부터 b가 사용할 스택을 확보하기 위해 rbp와 rsp 값을 동일하게 만듭니다.

이를 다시 보면
코드가 아래와 같고

push rbp
mov rbp rsp
sub 0x3 rsp

a 함수에서 기존의 스택의 공간이 아래와 같다고 가정합시다.

0x10 rsp위치
0x11
0x12
0x13 rbp위치

여기서 b 함수를 호출하면 push rbp에 의해

0x9, 0x13 값이 들어감, rsp 위치
0x10
0x11
0x12
0x13 rbp위치

mov rbp rsp에 의해

0x9, 0x13 값이 들어감, rsp위치 rbp위치
0x10
0x11
0x12
0x13

sub 0x3 rsp에 의해

0x6 rsp위치
0x7
0x8
0x9 rbp 위치
0x10
가 됩니다.

즉 6~9 는 b 함수의 스택 공간
10~13은 a 함수의 스택 공간이 됩니다.

2023.04.11. 06:13
avatar
Rosieblue
워게임 고인물

스택프레임은 보통 어떤 새로운 함수를 call할 때 생성되죠?
그러면 새 함수를 callee, callee를 호출한 함수를 caller라고 해볼게요

스택프레임의 맨 아래를 가리키는 포인터를 우리는 rbp(x64기준)라고 불러요! 이를 통해서 스택프레임을 구분하는 역할을 하죠

callee가 호출되기 직전에 우리는 caller를 실행하고 있었을 거예요
그러면 caller의 스택프레임 맨 아래에는 caller의 스택프레임 시작을 가리키는 rbp도 있었을 거구요
이제 우리는 callee라는 새로운 함수를 호출하고 싶어요!
이제 callee로 들어갈거예요 그러면 우리는 callee의 스택프레임을 새로 할당해야해요
그런데 우리는 rbp로 스택프레임을 구분한다고 했어요

ㅡㅡㅡㅡㅡㅡㅡㅡ
callee 스택프레임
ㅡㅡㅡㅡㅡㅡㅡㅡ (스택 프레임 구분선)
caller 스택프레임 <-rbp
ㅡㅡㅡㅡㅡㅡㅡㅡ

이렇게 있었다면 이제 나는 caller가 아닌 callee 스택프레임에 있어! 라는 걸 나타내기 위해 callee스택프레임 맨 아래를 rbp가 가리켜야해요 그러기위해서는 위 스택에 있는 rbp의 위치가 callee쪽으로 옮겨져야겠죠?
아래처럼요!

ㅡㅡㅡㅡㅡㅡㅡㅡ
callee 스택프레임 <-rbp
ㅡㅡㅡㅡㅡㅡㅡㅡ (스택 프레임 구분선)
caller 스택프레임
ㅡㅡㅡㅡㅡㅡㅡㅡ

하지만 여기서 문제가 있어요
우리가 caller를 가리키는 rbp를 callee쪽으로 옮겨버렸기 때문에 우리는 caller로 다시돌아가도 caller의 rbp를 몰라서 어디서부터 caller의 스택프레임이 시작하는지 모르게돼요
그래서 우리는 push rbp 를 해주는거예요! rbp의 위치를 callee로 옮기기 전에요! 이거는 caller의 rbp 위치를 스택에 넣어주는 역할을 해요

이후에 mov rbp, rsp과정을 통해 rbp를 caller에서 callee스택으로 바꾸어준거예요 (rsp는 스택에 맨 위니까 거기서부터 callee 함수 스택프레임이 할당되겠죠) 그럼 callee의 스택 맨 아래는 caller의 rbp가 저장되어있고 여기를 callee의 rbp가 가리키고 있겠

그래서
push rbp
mov rbp, rsp
이 과정이 필요한 거랍니당

궁금한거 있으면 댓주세욥!

2023.04.11. 14:25
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기