개요
리버싱을 공부하면서 자신이 만든 프로그램을 직접 디버깅해보고 싶단 의욕이 생기는 일은 당연하다. 하지만 처음 리버싱을 공부하는 입장이 아니라면 보통 Abex's CrackMe부터 다양한 문제를 통해 먼저 접해본 경험이 많을 것이다. 이러한 프로그램들은 대부분 쉽게 리버싱을 학습하도록 메인 함수 부분이 바로 나타나거나 찾기 쉽도록 되어 있다. 따라서 직접 간단한 파일을 컴파일하여 디버거로 열어본다면 복잡해 보이는 엔진 코드로 인해 당황하게 된다. 필자 또한 리버싱을 접한지 얼마 안 되었을 때, 매우 당황했던 것을 기억한다.
우선 필자의 컴파일 환경은 WIndows10 x64, Visual Studio 2013이다. 실습을 위해 C언어로 대부분의 사람들은 모두 접해보았을 "Hello World!"를 출력하는 문구를 만들었다. 사용된 코드는 다음과 같다.
#include <stdio.h>
int main()
{
printf("Hello World!\n");
}
이후 빌드를 한 후 exe 파일의 형태로 존재하는 것을 확인할 수 있다. 바로 이 EXE 파일이 이번 실습의 대상이다. 이제 OllyDBG를 통해 해당 파일을 열어보자.
디버깅
열자마자 너무나 많은 JMP 명령어가 존재하고 있다. 하지만 겁먹지 말자, mainCRTStartup이라 친절하게 나와있듯이 우리는 바로 첫 줄에 해당하는 부분으로 이동해 확인해주면 된다. OllyDBG를 통해 JMP 명령어를 실행해보자.
해당 부분으로 이동하면 PUSH EBP로 시작하여 RETN으로 끝나는 지점을 확인할 수 있다. 우선 맨 위의 두 줄은 흔히 스택 프레임을 구성하는 부분으로, 스택 프레임이란 해당 함수가 가지는 공간이라고 볼 수 있다. 스택에 현재 EBP(Base Pointer)를 넣어주므로 현재 위치로 다시 되돌아 올 수 있도록 한다. EBP에는 현재 스택의 최하점을 가리키고 있는 것으로 이를 기억하기 위해 PUSH EBP 명령을 해주는 것이다. 다음으로 MOV 명령은 방금 넣은 EBP에 이제 새로운 주소 공간을 위한 값(ESP)을 넣어주는 것이다. 이렇게 ESP는 보통 수시로 값이 변하기 때문에 EBP가 기억 지점 같은 역할을 하는 것이다.
이렇게 스택 프레임을 구성한 후 CALL 명령을 통해 두 번의 호출이 이루어지는 것을 볼 수 있다. 첫 번째 호출 부분의 경우 Step Into를 통해 자세히 확인해보면 다른 함수를 호출하는 부분은 존재하지 않다. 따라서 우리는 해당 부분은 넘어가 주면 된다. 이제 OllyDBG에서도 친절히 _tmainCRTStartup이라 되어 있는 부분으로 들어가 보자.
위 사진으로 나타난 부분이 다가 아니며 많은 부분이 CALL을 통해 새로운 함수들을 호출한다. 이러한 호출은 컴파일된 프로그램이 기본적인 구성을 확인하기 위한 작업으로 이상이 있다면 프로그램이 정상적으로 실행되지 않고 종료된다. 메인 함수까지 약 7개의 함수 호출이 더 존재하기 때문에 이는 아래의 그림과 같이 시각화하였다.
최초 Jmp를 통해 mainCRPStartup에 진입한 뒤, 두 개의 CALL 명령어 중 _tmainCRTStartup을 호출한다. 그리고 바로 이 _tmainCRTStartup에는 NTCurretnTab, _amsg_exit 등의 함수들을 호출하며 CrtSetCheckCount를 호출한 뒤 우리가 찾던 Main() 함수가 존재하였다. 해당 부분을 확인하면 다음과 그림과 같다.
최초 C언어에 비해 매우 복잡한 모습을 하고 있다. 이에 대해 간략히 말하자면 보안에 대하여 위협이 지금처럼 심하지 않을 당시엔 매우 간단하게 컴파일이 되어 가시적이었다. 하지만 지금은 수많은 공격 기법이 존재하므로 이러한 공격 기법을 방지하고자 이에 대한 요소까지 같이 포함되기 때문에 ESP를 체크하는 등이 추가된 것이다.
이렇게 우리는 메인 함수로 올 수 있었다. 버전이나 컴파일러에 따라 상이하므로, 최대한 많이 찾아보며 어느 부분에서 메인 함수를 찾아야 할지 익숙해지는 것이 좋다.
'Reversing > Theory' 카테고리의 다른 글
CPU 레지스터 (0) | 2016.03.26 |
---|---|
C기본 문법 어셈블리 변환 (5) | 2016.03.20 |
ClamAV & PEiD to Yara Rules (1) | 2016.03.11 |
Yara 규칙 제작 & Python (1) | 2016.03.07 |
Yara를 사용해보자 (0) | 2016.03.06 |