디컴파일러
더 많은 작업
디컴파일러(Decompiler, 역컴파일러)는 기계어나 바이트코드로 된 실행 파일을 C·자바 같은 고급 언어 형태의 소스 코드로 되살려 보여 주는 프로그램이다. 이 작업을 디컴파일(역컴파일)이라 한다.
컴파일러가 사람이 쓴 고급 언어(하이레벨 언어)를 기계어(로우레벨 언어)로 번역한다면, 디컴파일러는 그 반대 방향으로 로우레벨 코드를 하이레벨 언어로 옮긴다. 원시 코드가 없는 프로그램이 무엇을 하는지 알아내는 역공학에서 디스어셈블러와 함께 가장 많이 쓰는 도구이고, 프로그램을 실행하지 않고 코드를 읽으므로 정적 분석 도구에 속한다.
컴파일하면서 변수 이름·주석·자료형·원래의 제어 구조 같은 정보가 상당 부분 사라지므로, 디컴파일한 결과는 원래 소스와 똑같지 않다. 디컴파일러는 디스어셈블한 명령어에서 함수 경계, 반복문·조건문 구조, 지역 변수와 자료형을 추론해 사람이 읽을 수 있는 고급 언어 코드를 만들어 낸다. 이름은 var_8, sub_401000 처럼 기계적으로 붙는다.
| 대상 | 되살리기 | 대표 도구 |
|---|---|---|
| 자바·안드로이드 바이트코드, .NET 중간 언어 | 클래스·메서드 이름과 자료형 정보가 파일에 남아 있어 원래 소스에 가깝게 쉽게 되살아난다 | JD-GUI, jadx, dex2jar, ILSpy, dnSpy |
| 네이티브 기계어(C·C++ 로 만든 x86·ARM 실행 파일) | 이름·자료형 정보가 거의 없어 C 비슷한 의사 코드(pseudo code)로 나온다 | Ghidra, IDA(Hex-Rays), Binary Ninja |
안드로이드 앱이 디컴파일로 쉽게 분석되기 때문에 난독화로 디컴파일 결과를 읽기 어렵게 만드는 것이 앱 보호의 기본이다.
문제에서 자주 나란히 나오는 도구들이다. 로우레벨에서 하이레벨로 가는 것은 디컴파일러 하나뿐이다.
| 도구 | 하는 일 | 변환 방향 |
|---|---|---|
| 디컴파일러 | 기계어·바이트코드를 고급 언어 소스 형태로 되살린다 | 로우레벨 → 하이레벨 |
| 디스어셈블러 | 기계어를 어셈블리 명령어로 되돌린다 | 기계어 → 어셈블리어(여전히 로우레벨) |
| 어셈블러 | 어셈블리어를 기계어로 번역한다 | 로우레벨 → 더 낮은 로우레벨(역공학 도구가 아니다) |
| 컴파일러 | 고급 언어를 기계어로 번역한다 | 하이레벨 → 로우레벨 |
| 디버거 | 프로그램을 실행하면서 한 명령씩 멈추고 레지스터·메모리 값을 본다. 코드를 다른 언어로 바꾸지 않는다 | 변환 없음(동적 분석) |
| 패커 | 실행 파일을 압축·암호화해 감싼다. 분석을 막는 쪽에서 쓴다 | 변환 없음 |
디컴파일은 저작권법의 프로그램코드역분석에 해당한다. 정당한 권한으로 프로그램을 쓰는 사람이 다른 프로그램과의 호환에 필요한 정보를 얻을 수 없을 때, 그 부분에 한해 허락 없이 할 수 있다(「저작권법」 제101조의4). 얻은 정보를 호환 외의 목적에 쓰거나 비슷한 프로그램을 만드는 데 쓰면 안 된다 → 리버스 엔지니어링