순수하게 공부 목적으로 블로그에 글을 작성합니다.
리버스 엔지니어링에서는 소프트웨어를 분석하기 위해 사용하는 분석 방법들을 크게 정적 분석(Static Analysis) 과 동적 분석(Dynamic Analysis)으로 구분합니다.
정적 분석은 외적인 관찰만을 통해 정보를 알아내는 것을 의미합니다.
동적 분석은 실행을 통해 동작을 분석하는 것을 의미합니다.
1. 정적 분석 (Static Analysis)
프로그램을 실행시키지 않고 분석하는 방법입니다.
- 장점
프로그램의 전체구조를 파악하기 쉽습니다. 정적 분석 도구들은 프로그램의 여러 정보를 살펴볼 수 있도록 도움을 주는데, 프로그램이 어떤 함수로 구성됐고 함수들은 서로 어떤 호출 관계를 갖는지, 어떤 API를 사용하고 어떤 문자열을 포함하는지 등을 종합적으로 살펴볼 수 있습니다. 분석자는 이 정보들을 바탕으로 프로그램을 큰 관점에서 이해할 수 있습니다.
분석 환경의 제약에서도 비교적 자유롭습니다. 정적 분석은 프로그램을 실행하지 않아도 되므로 분석을 지원하는 적절한 도구만 갖춘다면 시도할 수 있습니다.
바이러스와 같은 악성 프로그램의 위협으로부터 안전합니다. 바이러스를 동적 분석할 경우, 바이러스를 실제로 실행해야 하므로 자신의 컴퓨터가 감염될 우려가 있습니다. 하지만, 정적 분석 (Static Analysis) 같은 경우는 프로그램을 실행하지 않고 분석하므로 이런 걱정을 안해도 됩니다.
- 단점
난독화(Obfuscation)가 적용되면 분석이 매우 어려워집니다. 최근에는 많은 개발자가 자신의 소프트웨어를 리버스 엔지니어링으로부터 보호하기 위해 난독화 기법을 적용합니다. 난독화가 적용되면 프로그램의 코드가 심하게 변형되어 이를 읽고, 실행 흐름을 파악하기가 어려워집니다.
난독화에 대해 더 알아보도록 하겠습니다.
난독화는 프로그램의 코드를 읽기 어렵게 만드는 기술입니다.
난독화의 대상에 따라서 소스코드 난독화와 바이너리 난독화로 구분이 됩니다.
소스코드 난독화는 C/C++/JAVA 등의 프로그램 소스코드를 알아보기 힘들게 만드는 기술입니다.
바이너리 난독화는 컴파일 후 생성된 바이너리를 Reverse engineering을 통해 분석하기 어렵게 변조하는 기술입니다.
다양한 동적 요소를 고려하기 어렵습니다. 프로그램은 실행중에 영향을 주고 받는 여러 함수로 구성이 됩니다. A라는 함수가 B라는 함수에 들어가는 인자를 경정할 수도 있고, A와 B가 서로 같은 전역변수를 공유할 수도 있습니다.
2. 동적 분석 (Dynamic Analysis)
프로그램을 실행시키면서 분석하는 방법입니다.
- 장점
코드를 자세히 분석해보지 않고도 프로그램의 개략적인 동작을 파악할 수 있습니다.
- 단점
분석 환경을 구축하기 어려울 수 있다는 것입니다. 동적 분석은 프로그램을 실행하면서 분석하는 것이므로, 프로그램을 실행하지 못하면 동적 분석을 진행을 할 수 없습니다. 그래서 다른 환경의 프로그램을 동적 분석할 때에는 가상 머신을 구축하거나 프로그램을 실행할 수 있는 장치를 구매해야 합니다. 이 과정이 대상에 따라서는 매우 번거롭고 어려울 수 있습니다.
정적 분석에서 소개된 "난독화" 처럼 동적 분석에 대해서도 이를 어렵게 하는 대표적인 기법으로, 디버깅을 방해하는 안티 디버깅(Anti Debugging)이 있습니다.
ex) 자신이 디버깅 당하고 있는지 검사하고, 디버깅 중이면 프로그램을 강제로 종료시키는 방법이 있습니다.
if (is_debugging()) // 디버깅인지 확인
exit(-1); // 프로그램 종료
Func();