본문 바로가기

Security/reversing

What is Reversing?

Reversing

이미 만들어지 시스템이나 장치에 대한 해체나 분석을 거쳐 그 대상 물체의 구조와 기능, 디자인 등을 알아내는 과정

→완성품의 설계도 없이 구조와 동작 과정을 알아내는 모든 단계

 

  • 소스코드가 없는 상태에서 컴파일된 대상 소프트웨어의 구조를 여러가지 방법으로 분석.
  • 메모리 덤프를 비롯한 바이너리 분석 결과를 토대로 동작 원리와 내부 구조 파악.

이를 바탕으로 소스코드가 어떻게 작성된 것인지 알아냄.


리버싱이 필요할 때

  • 제작사가 개발을 중단한 오래된 프로그램에 대한 지원이 필요할 때 (더 이상 소스코드를 보관하지 않거나 유실된 경우가 많기 때문에 포팅 등의 지원을 위해서 쓰이기도 함.)
  • 프로그램의 보안성을 평가하거나 악성코드 분석하는 경우 (실행 흐름을 통해 대상 프로그램의 보안성 평가, 악성코드가 어떤 방식으로 동작하고 피해를 입히는지 알아냄.)

 

리버싱으로 소프트웨어 동작 원리를 알아내는 두 가지 방법

Static Analysis(정적 분석 방법) : 프로그램을 실행 시키지 않음

→ 실행 파일을 구성하는 모든 요소, 대상 실행 파일이 실제로 동작할 CPU 아키텍처에 해당하는 어셈블리코드 이해.

 

Dynamic Analysis (동적 분석 방법) : 프로그램을 실행 기켜 입출력과 내부 동작 단계를 살피며 분석

→ 환경에 맞는 디버거를 이용해 단계별로 분석하는 기술을 익혀야 함.

 


코드가 컴파일되는 과정

< Source Code → Binary Code > : Compile

소스 코드를 바이너리 코드로 바꾸려면 컴파일 과정을 거쳐야 함. 

이러한 과정에서 사용되는 프로그램을 "컴파일러"

대개는 단독적으로 실행 가능한 바이너리가 되기 위해서 컴파일 과정을 거침.

 

  • Compile(컴파일) : 소스 코드를 바이너리 코드로 바꾸는 과정

 

컴파일러가 소스 코드를 바이너리로 변환하기 위해서는 몇 가지 단계를 거침.


< Source Code → ???? Binary Code >

원본 소스 코드 각종 주석이나 매크로, 참조할 헤더 파일 등을 포함.

이와 같은 정보는 참조를 위해 붙여둔 정보이므로 컴파일러는 이를 모두 미리 처리해서 다음 단계에서 변환됨.

 

 "중간 언어"를 컴파일러가 분석하고 최적화하여 어셈블리 코드로 만들어줌

어셈블리 코드와 기계 코드는 1 : 1 대응이 가능하므로, 어셈블(Assemble)을 거쳐 실행 가능한 바이너리가 완성됨.

 

  • 어셈블리 코드 : 컴퓨터가 이해할 수 있는 기계 코드를 사람이 알아보기 쉽게 명령어(Instruction) 단위로 표현한 것
  • Assemble(어셈블) : 대응이 가능 어셈블리 코드가 기계 코드로 번역되는 과정 

 

 


< Source Code ← ??? ← Binary Code >

바이너리를 분석해서 어떤 방식으로 동작하는지, 나아가 어떤 소스 코드를 바탕으로 만들어졌는지를 알아내려면 컴파일러가 수행하는 과정을 역으로 진행해야 함.

 

따라서 주어진 바이너리를 어셈블리 코드로 변환하고, 변환된 어셈블리 코드를 분석하면 대상 바이너리가 어떤 식을 동작하는지 알 수 있게 됨.

 

  • Disassemble(디스어셈블) : 바이너리 코드를 어셈블리 코드로 변환하는 과정

 


리버싱, 특히 
정적 분석 방법에 해당되는 방법은 디스어셈블을 거쳐 나온 어셈블리 코드를 분석하여 소프트웨어의 동작 구조를 알아내는 과정을 가리킴.