본문 바로가기
🖥️ IT/AI·기술

디컴파일과 디스어셈블의 차이|실행 파일에서 코드를 분석하는 원리

by 김물사 2026. 10. 19.

 

우리가 사용하는 프로그램은 대부분 개발자가 작성한 소스코드를 그대로 실행하는 것이 아니에요.
컴퓨터가 처리할 수 있는 형태로 변환된 뒤 실행되는 경우가 많습니다.

 

그렇다면 원본 소스코드가 없는 프로그램은 내부에서 어떤 작업을 하는지 알아낼 수 없을까요?
이럴 때 등장하는 기술이 디컴파일과 디스어셈블입니다.

 

디스어셈블은 기계어를 어셈블리 명령어로 해석하는 기술이고 디컴파일은 분석 대상 코드를 사람이 이해하기 쉬운 고급 언어 형태로 재구성하는 기술이에요.

 

프로그램은 왜 원래 코드와 다른 모습으로 저장될까?

 

개발자는 C나 C++ 같은 프로그래밍 언어로 프로그램을 작성할 수 있어요.
하지만 컴퓨터의 프로세서가 이런 소스코드를 그대로 실행하는 것은 아닙니다.

 

일반적인 네이티브 프로그램은 컴파일이라는 과정을 거쳐 기계어 명령을 포함한 실행 파일로 만들어집니다.
기계어는 프로세서가 실행할 수 있는 명령을 숫자로 표현한 형태예요.

 

이 과정에서 사람이 작성한 변수 이름이나 주석 같은 정보는 실행에 필요하지 않다면 사라질 수 있습니다.
컴파일러의 최적화로 명령어 구조 자체가 달라지기도 하죠.

 

 

가령 개발자가 두 숫자를 더하는 코드를 작성했다고 생각해볼게요.
컴파일된 프로그램에는 원래 작성한 문장 대신 계산을 수행하기 위한 기계어 명령이 들어갈 수 있습니다.

 

코드가 변환되었다고 해서 프로그램의 동작까지 사라지는 것은 아니에요.
디컴파일과 디스어셈블은 이렇게 남아 있는 명령과 구조를 분석하는 데 사용됩니다.

 

🔍 디스어셈블은 컴퓨터의 명령어를 읽는 방법

 

디스어셈블(Disassembly)은 기계어를 어셈블리 언어로 변환해 보여주는 과정입니다.
어셈블리 언어는 프로세서 명령을 사람이 읽을 수 있는 기호와 문자로 표현한 저수준 언어예요.

 

예를 들어 x86 계열 프로세서에서는 데이터를 이동시키는 MOV나 덧셈을 수행하는 ADD 같은 명령어를 볼 수 있습니다.
실제 명령어 구성은 프로세서 종류에 따라 달라져요.

 

디스어셈블 결과를 살펴보면 프로그램이 어떤 명령을 실행하는지 비교적 세밀하게 분석할 수 있습니다.
조건에 따라 실행 위치가 바뀌는 흐름이나 특정 함수를 호출하는 과정도 추적할 수 있죠.

 

다만 어셈블리 언어는 일반적인 프로그래밍 언어보다 읽기 어렵습니다.
명령어가 많이 나열되어 있다고 해서 프로그램의 전체 기능을 곧바로 이해할 수 있는 것은 아니에요.

 

디컴파일은 코드를 다시 이해하기 쉬운 형태로 바꿔요

 

디컴파일(Decompilation)은 분석 대상 프로그램의 명령과 구조를 바탕으로 고급 프로그래밍 언어와 비슷한 코드를 만들어내는 기술입니다.

 

고급 언어는 C처럼 사람이 읽고 작성하기 편하도록 설계된 프로그래밍 언어를 말해요.
디컴파일 결과에서는 함수 호출이나 반복문 또는 조건문 같은 구조를 더 쉽게 파악할 수 있습니다.

 

 

예를 들어 숫자가 특정 값보다 큰지 검사하는 프로그램이 있다고 가정해볼게요.
디스어셈블 결과에서는 값을 비교하고 다른 위치로 이동하는 명령이 나타날 수 있습니다.

 

디컴파일 결과에서는 이러한 동작이 if 조건문처럼 표현될 수 있어요.
덕분에 개별 명령어를 하나씩 해석하지 않아도 전체 흐름을 이해하기가 상대적으로 쉬워집니다.

 

두 기술은 무엇이 다를까?

 

두 기술 모두 프로그램 내부를 분석할 때 사용하지만 보여주는 결과와 분석하는 관점에는 차이가 있습니다.

 

구분디스어셈블디컴파일
주요 목적 기계어 명령 해석 상위 수준 코드 재구성
결과 형태 어셈블리 명령어 고급 언어 형태의 코드
읽기 난이도 상대적으로 높음 상대적으로 낮음
분석 관점 세부 명령과 실행 흐름 함수와 프로그램의 논리
원본 복원 원본 소스코드 복원 아님 원본과 동일함을 보장하지 않음

 

어느 기술이 무조건 더 뛰어나다고 보기는 어렵습니다.
프로그램의 전체적인 처리 과정을 이해하려면 디컴파일 결과가 유용할 수 있고 세부적인 명령을 확인하려면 디스어셈블 결과가 필요할 수 있어요.

 

실제 분석에서는 두 결과를 함께 살펴보기도 합니다.
디컴파일된 코드만으로 판단하기 어려운 부분을 어셈블리 명령과 비교해 확인하는 방식이죠.

 

원래 소스코드를 완벽하게 되살릴 수 있을까?

 

디컴파일을 처음 접하면 실행 파일을 분석해서 개발자가 작성했던 소스코드를 그대로 복원할 수 있다고 생각하기 쉬워요.
하지만 실제로는 그렇지 않습니다.

 

컴파일 과정에서 사라진 주석이나 변수 이름은 일반적으로 자동 복원할 수 없어요.
서로 다른 소스코드가 비슷하거나 같은 기계어로 변환되는 경우도 있기 때문입니다.

 

디컴파일 도구가 임의로 붙인 변수 이름이나 추정한 자료형이 실제 개발자의 의도와 다를 수도 있습니다.
복원된 코드가 문법적으로 그럴듯해 보여도 분석 결과를 무조건 정확하다고 믿어서는 안 됩니다.

 

특히 코드 최적화나 난독화가 적용되어 있다면 원래의 프로그램 구조를 이해하기가 더 어려워질 수 있어요.
난독화는 프로그램을 분석하기 어렵도록 코드의 표현이나 구조를 복잡하게 만드는 기법입니다.

 

실제 프로그램 분석에서는 어떻게 사용될까?

 

디컴파일과 디스어셈블은 리버스 엔지니어링(역공학)에서 활용하는 대표적인 기술입니다.
역공학은 완성된 프로그램이나 제품을 분석해 내부 구조와 동작 원리를 이해하는 접근 방법이에요.

 

예를 들어 오래된 데스크톱 프로그램의 유지보수가 필요한데 소스코드가 남아 있지 않은 상황을 생각할 수 있습니다.
적절한 권한이 있다면 실행 파일을 분석해 일부 처리 방식이나 오류가 발생할 만한 위치를 조사할 수 있죠.

 

보안 분야에서도 활용됩니다.
악성 프로그램이 어떤 명령을 수행하는지 분석하거나 소프트웨어의 취약할 가능성이 있는 동작을 조사하는 데 도움이 될 수 있어요.

 

 

대표적인 분석 도구로는 Ghidra가 있습니다.
Ghidra는 디스어셈블과 디컴파일 기능을 모두 제공하는 소프트웨어 역공학 도구예요.

 

다만 모든 실행 파일을 같은 방식으로 분석할 수 있는 것은 아닙니다.
프로그램이 만들어진 언어와 실행 환경 그리고 파일 형식에 따라 사용할 수 있는 분석 방법과 얻을 수 있는 정보가 달라집니다.

 

다른 사람의 소프트웨어를 분석할 때는 라이선스와 관련 법률도 고려해야 해요.
기술적으로 분석이 가능하다는 사실이 모든 분석이나 코드 활용을 허용한다는 뜻은 아닙니다.

 

코드를 읽는 것과 프로그램을 이해하는 것은 달라요

 

디스어셈블은 컴퓨터가 실행하는 명령을 살펴보는 데 초점이 있고 디컴파일은 그 명령이 어떤 논리로 구성되어 있는지 이해하기 쉽게 표현하는 데 초점이 있습니다.

 

두 기술을 함께 활용하면 소스코드가 없는 프로그램도 일정 부분 분석할 수 있어요.
하지만 분석 도구가 만들어낸 결과는 원본 자체가 아니라 해석하고 재구성한 정보라는 점을 기억할 필요가 있습니다.

 

리버스 엔지니어링을 이해할 때도 이 차이가 좋은 출발점이 됩니다.
프로그램을 어떻게 만들었는지보다 이미 만들어진 프로그램이 실제로 어떻게 동작하는지 살펴보는 것이 핵심이니까요.

반응형
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.