Post

리버싱 핵심 원리 | 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.