Reversing/리버싱_핵심원리

7장 스택 프레임

dcho 2019. 8. 7. 21:02
SMALL
스택 프레임이란?
쉽게 말해 ESP(스택 포인터)가 아닌 EBP(베이스 포인터)레지스터를 사용해 스택 내의 로컬 변수, 파라미터, 복귀 주소에 접근하는 기법을 말한다.

ESP는 수시로 변하기 때문에 스택에 저장되어진 변수, 파라미터에 접근하고자 할때 ESP 값을 기준으로 하면 프로그램을 만들기 힘들고 CPU가 정확한 위치를 참고할 때 어려움이 있기 때문에 어떤 기준 시점(함수 시작)의 ESP의 값을 EBP에 저장하고 이를 함수 내에서 유지해준다면, ESP 값이 아무리 변하더라도 EBP를 기준(base)으로 안전하게 해당 함수의 변수, 파라미터, 복귀 주소에 접근할 수 있다. 이게 바로 EBP 레지스터 베이스 포인터 역할이다.

// 스택 프레임의 구조
PUSH EBP                            ; 함수 시작(EBP를 사용하기 전에 기존의 값을 스택에 저장)    
MOV EBP, ESP                     ; 현재의 ESP(스택포인터)를 EBP에 저장

...                                         ; 함수 본체
                                            ; 여기서 ESP가 변경되더라도 EBP가 변경되지 않으므로
                                            ; 안전하게 로컬 변수와 파라미터를 엑세스 할 수 있음

MOV ESP, EBP                    ; ESP를 정리(함수 시작 했을 때의 값으로 복원시킴)
POP EBP                             ; 리턴되기 전에 저장해 놓았던 원래 EBP 값으로 복원
RETN                                  ; 함수 종료
스택 프레임을 이용해서 함수 호출을 관리하면, 아무리 함수 호출 DEPTH가 깊고 복잡해져도 스택을 완벽하게 관리할 수 있다.

※ 최신 컴파일러는 최적화 (Optimization) 옵션을 가지고 있어 간단한 함수 같은 경우에 스택 프레임을 생성하지 않는다.
※ 스택에 복귀 주소가 저장된다는 점이 보안 취약점으로 작용될 수 있다. buffer overflow 기법을 사용하여 복귀 주소가 저장된 스택 메모리를 의도적으로 다른값으로 변경 가능하기에.


어셈블리 언어를 처음 접하는 사람에게는 DWORD PTR SS:[EBP-4] 라는 형식이 생소하게 보일 것이다. C언어의 포인터와 같은 개념으로 생각하면 된다.

최대한 간겨라게 번역해보면 "EBP-4 주소에서 4바이트 크기의 메모리 내용"이라고 할 수 있다.

※DWORD PTR SS:[EBP-4] 구문에서 SS(Stack Segment)를 같이 표시하는 이유는 일단 Windows에서 세그먼트 메모리 모델(Segment Memory Model)을 사용하기 때문에 해당 메모리가 어떤 세그먼트에 소속되어 있는지 표시해주는 것이다. 실제로는 32비트 Windows OS 에서 SS(Stack Segment), DS(Data Segment), ES(Extra data Segment)의 값은 모두 0이다. 따라서 이런 식으로 세그먼트를 붙여주는 것에 큰 의미는 없다. EBP와 ESP는 스택을 가리키는 레지스터들이기 때문에 SS 레지스터를 붙여준 것이다. 참고로 'DWORD PTR'과 'SS:'등의 문자열은 OllyDbg 옵션에서 안보이게 할 수 있다.

Disasm 옵션

나는 이뮤니티 디버거를 쓴다. Option Dialog를 실행해 준다. (단축키 [Alt+O])

보통 이렇게 선택이 되어있는 데 해제를 해준다면 

요로코롬 세그먼트 표시와 메모리 크기 표시가 변하게 된다.

Analysis1 옵션

이 부분을 체크 해 준다면 EBP로 표시되던 함수의 로컬 변수와 파라미터가 [LOCAL.1], [ARG.1] 형식으로 표시된다.
이 옵션은 매우 뛰어난 가독성을 제공하므로 디버깅에 큰 도움이 된다.

이 옵션은 디버거에서 직접 함수의 스택 프레임을 분석하여 로컬 변수의 개수, 파라미터의 개수 등을 화면에 표시해주는 것이다. 간혹 틀리게 표시할 때도 있지만 직관적인 표시로 디버깅에 도움이 많이 된다. (나중에 꿀팁으로 따로 이런것들을 모아놓으면 디버깅할때 참 편리 할 것 같다.)



'Reversing > 리버싱_핵심원리' 카테고리의 다른 글

9장 Process Explorer - 최고의 작업 관리자  (0) 2019.08.14
8장 abex` crackme #2(미완)  (0) 2019.08.14
6장 abex' crackme #1 분석  (0) 2019.07.25
5장 스택  (0) 2019.07.25
4장 IA-32 Register 기본 설명  (0) 2019.07.25