리버싱 핵심 원리 | Stack Frame
리버싱 핵심 원리 | Stack Frame
스택 프레임
x64dbg에서 main caller에 break point를 걸고 확인
- main함수도 누군가에게 호출 됨 EBP 레지스터를 이용하여 스택 내의 로컬 변수, 파라미터, RET에 접근하는 기법
- EBP를 사용하는 이유: ESP 레지스터의 값은 프로그램 안에서 수시로 변경되기 때문에 스택에 저장된 변수, 파라미터에 접근하고자 할 때는 EBP를 사용하는 것이 효율적임
- EBP: 베이스 포인터, ESP: 스택의 최상단 주소를 가리키는 레지스터
- 함수가 호출될 때마다 스택 프레임이 만들어진다.
- 스택 프레임 안에는 함수의 매개변수(파라미터), 복귀 주소(RET), 지역 변수 등이 포함됨
스택 프레임의 구조
1
2
3
4
5
6
7
8
9
10
11
12
(함수의 프롤로그)
PUSH EBP
MOV EBP, ESP
-------
(함수 본체)
...
-------
(함수의 에필로그)
MOV ESP, EBP
POP EBP
RET
- 일단 기존의 EBP값을 어딘가에 저장해둬야하기 떄문에 EBP값을 스택에 저장해둠 (나중에 복구해야함)
- EBP는 함수가 종료될 때까지 유지됨 (함수 실행 중에는 ESP가 계속 변함)
- 그 다음 현재 ESP가 가리키는 값을 EBP에 갱신함
- 함수 실행
- 함수 실행이 종료되면 EBP가 가리키는 값을 다시 ESP에 저장
- EBP값을 pop하여, 함수 시작 전에 저장해둔 이전 함수의 프레임 포인터(EBP)를 되돌려줘서 스택 프레임을 원복함
스택 예제
1
2
3
4
5
6
7
8
9
int function(int a, int b) {
char buffer[10] = { 0 };
a = a + b;
return a;
}
void main() {
int c;
c = function(1, 2);
}
스택 예제 | main 함수의 prologue
1
메모리 연산자
- 특정 주소의 값을 참조하기 사용하는 연산자
1 2 3 4
BYTE PTR[...] WORD PTR[...] DWORD PTR[...] QWORD PTR[...]
- BYTE는 1바이트,
- WORD는 2바이트,
- DWORD(Double WORD)는 4바이트
- QWORD(Quad WORD)는 8바이트.
This post is licensed under
CC BY 4.0
by the author.
