리버스 엔지니어링에서는 소프트웨어를 분석하기 위해 사용하는 분석 방법들을 크게 **정적 분석(Static Analysis)**과 **동적 분석(Dynamic Analysis)**으로 구분합니다. 정적 분석은 외적인 관찰만을 통해 정보를 알아내는 것을 의미하며, 동적 분석은 실행을 통해 동작을 분석하는 것을 의미합니다.
우리는 정적 분석과 동적 분석 중 한 방법만을 고수하는 것이 아니라 상황에 따라 적절한 방법을 선택해야 합니다. 어떤 상황에 어떤 방법을 선택할 것이냐가 리버싱 실력을 좌우하는 중요한 요소입니다.
이 코스에서는 소프트웨어 리버싱에서 정적 분석과 동적 분석에 대한 개념을 살펴보고, 간단한 예를 통해 이 둘의 차이를 직관적으로 보여줄 것입니다. 몇몇 도구들이 등장하지만, 이들을 직접 사용해보려면 여러 배경지식이 필요하므로, 자세한 실습은 관련된 배경지식을 전부 소개한 뒤 진행하겠습니다. 여기서는 정적 분석과 동적 분석의 차이에만 주목해주시기 바랍니다.
**정적 분석(Static Analysis)**은 프로그램을 실행시키지 않고 분석하는 방법입니다.
정적 분석을 사용하면 프로그램의 전체구조를 파악하기 쉽습니다. 정적 분석 도구들은 프로그램의 여러 정보를 살펴볼 수 있도록 도움을 주는데, 프로그램이 어떤 함수로 구성됐고 함수들은 서로 어떤 호출 관계를 갖는지, 어떤 API를 사용하고 어떤 문자열을 포함하는지 등을 종합적으로 살펴볼 수 있습니다. 분석자는 이 정보들을 바탕으로 프로그램을 큰 관점에서 이해할 수 있습니다.
또한, 분석 환경의 제약에서도 비교적 자유롭습니다. 안드로이드의 apk 파일은 별도의 소프트웨어를 사용하지 않는 한 윈도우 시스템에서 실행할 수 없습니다. 따라서 실행을 전제로 하는 동적 분석을 윈도우 환경에서 apk를 대상으로 하기는 다소 번거롭습니다. 하지만 정적 분석은 프로그램을 실행하지 않아도 되므로 분석을 지원하는 적절한 도구만 갖춘다면 시도할 수 있습니다.
마지막으로 바이러스와 같은 악성 프로그램의 위협으로부터 안전합니다. 만약 바이러스를 동적 분석할 경우, 바이러스를 실제로 실행해야 하므로 자신의 컴퓨터가 감염될 우려가 있습니다. 반면 정적 분석은 프로그램을 실행하지 않고 분석하므로 이런 걱정을 하지 않아도 됩니다.
정적 분석은 프로그램에 난독화(Obfuscation)가 적용되면 분석이 매우 어려워집니다. 최근에는 많은 개발자가 자신의 소프트웨어를 리버스 엔지니어링으로부터 보호하기 위해 난독화 기법을 적용합니다. 난독화가 적용되면 프로그램의 코드가 심하게 변형돼서 이를 읽고, 실행 흐름을 파악하기가 어려워집니다. 이를 해제(Deobfuscation)하기 위한 여러 연구가 진행되고 있지만, 여전히 많은 상용 난독화 서비스들을 무력화하는 방법은 알려지지 않았습니다.
그리고 정적 분석만으로는 다양한 동적 요소를 고려하기 어렵습니다. 프로그램은 실행중에 영향을 주고 받는 여러 함수로 구성됩니다. A라는 함수가 B라는 함수에 들어가는 인자를 결정할 수도 있고, A와 B가 서로 같은 전역변수를 공유할 수도 있습니다. 따라서 어떤 함수가 특정 시점에 정확히 어떤 인자와 어떤 전역 변수를 가지고 실행될지는 정적으로 알기 어렵습니다. 이런 문제는 프로그램의 실행 흐름이 복잡할수록 더욱 심각해집니다.
참고