이 글은 Zynamics 블로그의 Ten years of innovation in reverse engineering을 번역한 글입니다.
바르셀로나에서 열렸던 블랙햇 유럽 컨퍼런스에서 돌아오면서 토마스와 저는 최근 10년 동안 바이너리 코드 리버스 엔지니어링 분야에서 있었던 가장 중요한 변화들이 어떤 것이었는지 이야기를 나누었습니다. 2000년에는 W32Dasm과 터보 디버거가 좋은 리버스 엔지니어링 도구로 취급되었었죠. 그 시절에는 프로그램이 실행되면서 어디로 점프하는지 로그를 남기는 트레이서를 직접 작성할 수 있었다면 최고가 될 수 있었습니다.
아무튼 2000년 이후 리버스 엔지니어로 일했던 사람들이 만들어낸 커다란 트렌드와 기술 변화로는 아래와 같은 것들이 있었습니다.
어셈블리 코드의 플로우 그래프 시각화
2001년 6월 IDA Pro 4.17 버전에서 처음으로 소개된 기능입니다. 이 기능은 디스어셈블 된 어셈블리 코드를 그래프로 볼 수 있도록 해주면서 리버스 엔지니어들의 작업을 매우 쉽게 만들어줬습니다. 요점만 말하면, 플로우 그래프 시각화는 저수준 코드 분석에 들어가는 시간과 노력을 줄이면서 한 단계 높은 추상화 수준에서 코드를 이해할 수 있도록 만들어줬습니다. 이렇게 그래프로 보기 전에는 리버스 엔지니어링 하면서 직접 루프나 if-else와 같은 컨트롤 플로우 구조를 그려야만 했었죠. 플로우 그래프 시각화를 이용하면 별도의 작업 없이 바로 컨트롤 플로우가 어떻게 되어있는지 볼 수 있습니다.
IDA에서 이 기능이 지원되면서 다른 도구(BinNavi 등)들도 인터랙티브 플로우 그래프라는 아이디어를 구현하기 시작했습니다. 2006년 3월 나온 IDA Pro 5.0 그래프 엔진도 인터랙티브 그래프를 제공하기 시작했구요.
파이썬을 스크립트 언어로 사용
2000년대로 돌아가보면 많은 리버스 엔지니어링 도구들은 상당히 원시적이었고 확장성이라고는 찾아보기 어려웠습니다. 디스어셈블러 중에서는 그나마 IDA Pro 4의 조악한 IDC 구현이 나은 수준이었고, 디버거 쪽은 그야말로 절망이었죠. 이런 상황은 파이썬과 SWIG가 대중적인 인기를 얻게 되면서 반전됩니다. 이 기술은 누구나 쉽게 자신의 프로그램이 파이썬 기반 API를 노출하고 파이썬 인터프리터에서 이를 사용할 수 있도록 했습니다. 제가 기억하는 가장 큰 진보는 파이썬으로 IDA API를 사용할 수 있도록 IDA Pro에서 사용할 수 있는 IDAPython 플러그인이 나온 것입니다. 그 후에 Pedram Amini의 PyDbg나 Ero Carrera의 pefile 프로그램이 나오면서 리버스 엔지니어링 분야에서 파이썬 언어가 주류로 자리잡게 되지요.
지금은 파이썬이 리버스 엔지니어링 분야의 표준 스크립팅 언어나 마찬가지가 되었고, IDA Pro에서 이뮤니티 디버거나 BinNavi에 이르기까지 다들 파이썬 스크립팅을 지원하고 있습니다.
동적 코드 조작 도구 (Dynamic Instrumentation)
이 기술 자체는 정말 새로운 것이라 말할 수는 없지만, DynamoRIO나 Pin 같은 도구들은 확실히 새로운 물건이라 말할 수 있습니다. 이 프레임워크들을 이용하면 명령어 스트림을 모니터링하고 조작하는 강력한 동적 분석 도구를 만들어낼 수 있습니다. 여러분이 이런 도구를 한 번도 사용해 본 적이 없다면, 이 도구를 인스트럭션이 실행될 때마다 C/C++ 프로그램에서 콜백을 받을 수 있도록 만들어주는 도구로 상상하시면 됩니다. 이를 이용하면 적은 오버헤드만으로 대상 프로그램의 모든 면을 완전히 제어할 수 있습니다.
여러분이 연구하는데 사용할 새로운 리버스 엔지니어링 도구를 찾고 있다면 동적 코드 조작이 필요할 겁니다. 정적 분석의 복잡도에 비하면 실제 동작하는 프로그램을 추적하는 것이 훨씬 쉽습니다. 게다가 아직까지 이런 기술이 그렇게 널리 이용되고 있지도 않습니다.
바이너리 디핑 (Diffing)
오래 전 몇몇 똑똑한 사람들이 이런 훌륭한 아이디어를 내놓았죠. 만약 같은 파일의 패치 전 버전과 패치 후 버전을 비교할 수 있다면, 패치로 인해 변경된 부분을 알아내고 패치된 취약점이 무엇인지 쉽고 빠르게 알아낼 수 있습니다. 이게 가능하려면 파일의 서로 다른 버전을 비교할 수 있는 도구가 필요했고, BinDiff 같은 도구가 근래 널리 사용되고 있습니다.
하지만 파일 비교라는 아이디어는 널리 알려진 것이기 때문에 공짜로 사용할 수 있는 도구들도 몇 년 새 많이 늘었습니다. 근본적으로 이 도구들은 모두 같은 방식으로 동작합니다. 두 개의 입력 파일이 디스어셈블 되고 나면, 파일 A의 함수를 파일 B의 함수와 비교하고, 매칭된 함수들 간에 어떤 변경이 있었는지 찾아내서 사용자에게 보여줍니다.
BinDiff 스타일의 도구는 이제 많은 리버스 엔지니어들의 기본 도구가 되었습니다. 취약점 연구자부터 맬웨어 분석가에 이르기까지 안 쓰이는 분야를 찾기가 어렵죠. 2000년 이래 이처럼 극적으로 성장한 기술을 찾기가 어렵습니다.
SoftICE 시대의 종말
되돌아보면 예전에는 SoftICE가 리버스 엔지니어링 분야에서 사용되는 디버거로는 단연 독보적이었습니다. SoftICE는 뉴햄프셔에 소재했던 NuMega라는 회사에서 작성한 디버거였죠. 이 디버거를 사용하면 복잡한 설정 없이도 유저랜드 프로그램 뿐 아니라 커널에 위치한 프로그램까지 디버깅할 수 있었습니다. 이후 Numega는 Compuware에 인수되고 SoftICE는 2006년 4월에 단종되었습니다.
지금은 새로운 디버거들이 SoftICE의 자리를 대체했습니다. 마이크로소프트의 WinDbg는 SoftICE 만큼 멋있지는 않지만 강력한 기능을 자랑하기 때문에 요새 많이 사용되고 있습니다.
헥스레이(Hex-Rays) 디버거의 등장
2000년대 디컴파일러는 아주 욕 나오는 물건이었습니다. 지금은 Hex-Rays가 있습니다. 2007년에 IDA Pro 팀에서 처음으로 디컴파일러를 내놓았는데, 이게 정말 실용적으로 쓸만했습니다. 이 디컴파일러는 개선에 개선을 거듭해서 지금은 ARM 디컴파일까지 지원합니다.
아직 Hex-Rays가 그렇게 많이 사용되는 것 같진 않지만 이 제품은 계속 주시할만한 물건입니다.
공동 리버스 엔지니어링
옛날에는 같은 프로그램에서 나온 산출물이라도 각각 만들어진 두 개의 데이터베이스에 들어있는 리버스 엔지니어링 결과물을 교환하는게 굉장히 어려운 일이었습니다. 최근에 이런 상황은 거의 마지못해 바뀌고 있습니다. 오늘날의 소프트웨어는 10년 전에 비하면 훨씬 더 복잡하기 때문에 여러 리버스 엔지니어링 팀이 공동으로 같은 프로젝트에 매달려야 되는 경우가 늘어났기 때문이지요.
지금은 그렇지 않더라도 공동 작업이 가능하게 해주는 도구들은 이미 시장에 나와있고, 앞으로 점점 더 널리 사용되게 될 것입니다. Chris Eagle이 만든 IDA Pro용 CollabREate이나 우리가 만든 BinCrowd를 이용하면 동료들과 결과물을 공유할 수 있습니다.
학문적 접근
최근 몇 년 간 주요 대학들의 연구 주제는 바이너리 코드 리버스 엔지니어링과 관련이 있었습니다. 그 중에서도 버클리 대학과 카네기 멜론 대학에서 좋은 결과들을 많이 내놨습니다. 업계의 리버서들도 이러한 학계의 접근 방식들을 주목하고 있습니다. 아직까지는 학계의 연구 결과가 업계에서 널리 받아들여지고 있지는 않지만, 리버스 엔지니어링에 정형화된 접근 방식을 적용하려는 시도가 계속 늘어나고 있습니다. 정형화된 리버스 엔지니어링에 대한 정보를 많이 제공하고 있는 Reverse Engineering Reddit의 인기가 이러한 경향을 말하고 있습니다.
국민의례와 자주자주송이 눈에 젤 먼저 들어오는군요;;
-_-;;