본문 바로가기
Miscellaneous

리버스 엔지니어링이란?

1103동103호·2019년 6월 11일·조회 3,737

1. 개념

리버스 엔지니어링(Reverse Engineering)은 특정 기계나 프로그램을 분석하고 동작을 관찰하여 제조 방법, 동작 원리, 설계 구조 등을 파악하는 방법이다.

소프트웨어 공학에서는 주로 실행 파일이나 바이트코드를 분석해 프로그램의 내부 동작을 이해하는 일을 뜻한다. 대표적으로 역어셈블한 코드를 해독하거나, 디버거를 통해 실행 흐름과 메모리 상태를 추적하는 방식이 있다.

흔히 역공학(逆工學)이라고 부른다.

* 역어셈블: 기계어 코드를 사람이 읽을 수 있는 어셈블리 코드 형태로 변환하는 작업

* 디컴파일: 컴파일된 바이너리나 바이트코드를 원래 소스 코드와 유사한 고수준 언어 형태로 복원하는 작업


2. 취지

소프트웨어 프로그래머라면 프로세서가 기계어를 해석하고 실행하는 것이 프로그램의 기본 동작 방식이라는 것을 알고 있다. 하지만 실제로 그 기계어를 역어셈블하고 동작을 따라가는 행위는 일반적인 프로그래머에게 항상 필요한 능력은 아니다.

그럼에도 역공학 지식은 보안 취약점 분석, 악성코드 분석, 장애 원인 추적, 호환성 확인, 오래된 프로그램의 동작 이해 같은 상황에서 도움이 된다. 예를 들어 소스 코드가 없는 프로그램의 파일 포맷 처리 방식이나 네트워크 통신 흐름을 확인해야 할 때 유용하다.

다만 상용 소프트웨어나 서비스의 분석은 라이선스, 저작권, 이용 약관, 관련 법률의 제한을 받을 수 있다. 학습이나 분석을 진행할 때는 권한이 있는 대상인지 먼저 확인하는 것이 좋다.


3. 언어별 역공학

3-1. 자바

자바는 클래스 파일에 바이트코드와 메타데이터가 포함되어 있어, 네이티브 바이너리에 비해 디컴파일하여 소스에 가까운 형태를 얻기 쉬운 편이다.

가장 널리 사용되는 도구 중 하나는 JD-GUI이다. (https://github.com/java-decompiler/jd-gui/releases)

다만 디컴파일 결과가 원본 소스와 완전히 같지는 않을 수 있다. 변수명, 주석, 코드 포맷, 일부 제어 흐름은 컴파일 과정에서 사라지거나 바뀔 수 있으므로, 결과를 그대로 신뢰하기보다는 실제 동작과 함께 확인하는 것이 좋다.

3-2. 네이티브 바이너리

C, C++처럼 네이티브 코드로 컴파일되는 언어는 실행 파일에 원본 소스의 정보가 거의 남지 않는 경우가 많다. 이때는 디컴파일러와 디버거를 함께 사용해 함수 호출 관계, 문자열, 메모리 접근, 분기 조건 등을 차근차근 확인한다.

분석할 때는 먼저 파일 형식, 아키텍처, 포함된 문자열, 외부 라이브러리 호출을 확인하고, 이후 관심 있는 함수부터 좁혀 가는 방식이 효율적이다.


4. Ghidra

다운로드: https://ghidra-sre.org/

Ghidra는 실행 파일 분석, 디스어셈블, 디컴파일, 함수 그래프 확인 등을 지원하는 역공학 도구이다. 다양한 아키텍처를 지원하며, 바이너리의 구조를 살펴보고 의심되는 함수의 동작을 추적하는 데 사용할 수 있다.

간단한 테스트는 직접 만든 작은 프로그램을 대상으로 진행하는 것이 안전하다. 예를 들어 문자열을 출력하거나 간단한 조건문을 포함한 프로그램을 컴파일한 뒤, Ghidra에서 열어 문자열 참조와 함수 호출 흐름이 어떻게 보이는지 확인하면 역공학 도구의 기본 사용 흐름을 익히기 좋다.

관련 글

댓글 0

로그인 후 댓글을 남길 수 있습니다.

아직 댓글이 없습니다.