역어셈블러 또는 디스어셈블러(disassembler)는 기계어어셈블리어로 변환하는 컴퓨터 프로그램이다. 역어셈블러는 어셈블리어가 아닌 고급 프로그래밍 언어를 대상으로 하는 역컴파일러와는 구분한다. 역어셈블러의 출력물인 디스어셈블리(disassembly)는 어셈블러로의 입력에 맞추는 것보다 사람이 읽기 쉽도록 형식을 정하는 경우가 있는데 이것이 바로 리버스 엔지니어링 도구의 역할이다.

어셈블리어 소스 코드는 보통 상수와 프로그래머의 주석을 허용한다. 이것들은 기계어로 변환되는 과정에서 어셈블러에 의해 제거된다. 그렇기 때문에 역어셈블리는 원본 소스 코드보다는 사람이 해석하기 어려워 진다. 몇몇 역어셈블러들은 ELF 파일 형식의 오브젝트 파일에 존재하는 기호 디버깅(Symbolic Debugging) 정보를 사용한다. IDA Pro는 사용자에게 값이나 코드의 영역을 위한 연상 기호를 사용할 수 있게 함으로써 사용자의 이해를 역어셈블 과정에 적용할 수 있게 한다.

역어셈블리는 정확한 과학이 아니다. CISC 플랫폼에서는 가변적인 명령어들이나 자체 수정 코드의 존재로 인해서 한 프로그램이 여러 타당한 역어셈블리로 만들어질 수 있는 것이다.

역어셈블리의 문제점들

편집

어셈블되었을 때 정확히 같은 바이너리 코드를 생성하는 역어셈블러를 만드는 것은 가능하지만 여기에는 보통 차이점이 있다. 이것은 어셈블러의 표현도에 대한 요구를 제기한다. 예를 들면, x86 어셈블러는 "MOV AX,BX"같은 간단한 바이너리를 임의적으로 선택한다. 만약 원본 코드가 다른 선택을 사용한다면 원본 코드는 당연히 다시 만들어질 수 없다. 하지만 정확히 똑같은 역어셈블리가 만들어졌을 때에도 프로그램이 수정을 요구한다면 문제는 남아있게 된다. 예를 들면 특정한 위치로 점프하는 같은 기계어 점프문이 생성될 수 있다. 역어셈블러는 어떤 것이 의도되었는지 알 수 없다. 그리고 원본 바이너리로 다시 만들어질 수 있는 문법을 생성할 것이다. 그러나 만약 프로그래머가 점프문 사이에 명령을 추가하게 되었을 때, 이 점프가 상대적인지 절대적인지를 결정해야 한다.

역어셈블러의 예

편집

역어셈블러는 독자적이거나 상호적일 수 있다. 독자적인 역어셈블러는 실행되었을 때 검사된 어셈블리어를 생성한다. 상호적인 역어셈블러는 사용자가 즉시 바꿀 수 있는 효과를 보여주는데, 예를 들자면 역어셈블러가 처음에 프로그램의 실제 코드 섹션을 모르고 데이터로 여겼다가 만약 사용자가 코드로 명시한다면 역어셈블 된 결과 코드가 즉각적으로 보여지게 한다. 이로써 같은 실행 기간 동안 사용자에게 더 많은 검사를 할 수 있게 한다.

대부분의 상호적인 디버거는 디버깅되는 프로그램의 기본적인 역어셈블리를 포함한다. 종종 같은 역어셈블리 툴이 디버거와 함께 독자적인 역어셈블러로 배포되는 경우도 있다. 예를 들면 objdump (GNU 바이너리 유틸리티의 한 부분인)는 GNU 디버거와 관련된 것이다.

  • IDA 프로
  • OllyDbg
  • Radare2
  • IBM OLIVER, SIMON에는 어셈블러, 코볼, PL/I을 위한 역어셈블러가 포함되어 있다.

역어셈블러와 에뮬레이터

편집

동적인 역어셈블러는 에뮬레이터하이퍼바이저의 결과물에 통합될 수 있다.

같이 보기

편집

외부 링크

편집