출처: https://dreamhack.io/learn/3/19#2
다시 볼때 보기 쉽게 밑줄 긋고 나같은 초보자를 위해 참고자료를 붙여넣을 것이다.
모든 내용은 전적으로 저 출처에서 나왔다.
Reverse Engineering
리버스 엔지니어링(Reverse Engineering)은 이미 만들어진 시스템이나 장치에 대한 해체나 분석을 거쳐 그 대상 물체의 구조와 기능, 디자인 등을 알아내는 일련의 과정을 말합니다. 따라서 비단 소프트웨어 뿐만 아니라 기계공학, 전자공학은 물론 생물학 등에서도 폭넓게 쓰입니다.
간단히 정리하면 '완성품의 설계도 없이 구조와 동작 과정을 알아내는' 모든 단계를 말합니다. 자료나 책에 따라 '역공학'이라고 지칭하기도 하지만, 이 강의 자료에서는 편의상 '리버스 엔지니어링'을 짧게 줄여 널리 통용하는 말인 '리버싱'으로 용어를 통일하겠습니다.
‘Software’ Reverse Engineering
리버싱이 산업의 전 분야에 걸쳐 적용될 수 있지만, 이 강의 자료는 소프트웨어를 대상으로 한 리버싱에 대해 공부하는 것을 목적으로 합니다.
즉 소스 코드가 없는 상태에서 컴파일된 대상 소프트웨어의 구조를 여러가지 방법으로 분석하고, 메모리 덤프를 비롯한 바이너리 분석 결과를 토대로 동작 원리와 내부 구조를 파악한 다음, 이를 바탕으로 원래의 소스가 어떻게 작성된 것인지 알아내는 과정에 대해 공부합니다.
리버싱 엔지니어링: 만들어진 것을 보고 어떻게 소스가 구성되었는지 구조등을 파악하는것
Good Cases
판매된 지 너무 오래되어 제작사가 이미 개발을 중단한 프로그램에 대한 지원이 필요할 때
->오래전에 발매된 게임을 다시 하고 싶어하는 게이머들에게도 리버싱은 아주 유용해서, 1996년에 발매된 디아블로가 리버싱을 거쳐 모딩된 버전이 공개된 바 있습니다.
각종 프로그램의 보안성을 평가하거나 악성코드를 분석하는 경우에서도 리버싱이 널리 쓰입니다. 이 경우 모두 소스 코드가 없는 상태에서 진행되므로 분석가가 실행 흐름을 리버싱을 통해 대상 프로그램이 얼마나 안전하게 설계되었는지, 혹은 분석 대상 악성코드가 어떤 방식으로 동작하고 피해를 입히는지 알아내게 됩니다.
Bad Cases
상용 프로그램을 구입하지 않고 공짜로 이용하기 위해 쓰는 키젠 프로그램이나 시리얼 넘버 생성기, 정품 크랙 등의 불법 프로그램도 리버싱을 통해 만들어집니다. 유료로 판매되는 프로그램들이 어떤 방식으로 정품 인증을 하는지를 리버싱을 통해 알아낼 수 있기 때문입니다.
각종 프로그램을 분석해서 게임핵을 만드는 경우
Disclaimer
앞에서 알아본 것 처럼 리버싱은 학습 및 연구용으로도 많이 이용되는 기술일 뿐만 아니라 각종 악성코드나 불법 프로그램의 분석 및 대응 수단으로도 효과적인 기술입니다. 그러나 소스 코드를 비롯한 전체적인 작동 원리를 알아낼 수 있다는 점에서, 각종 상용 프로그램의 지적 재산권을 침해할 수도 있는 양날의 검이기도 합니다.
테스팅이나 연구, 학습 등을 목적으로 한 리버싱의 경우 저작권을 침해하지 않는 범위 내에서 제한적으로는 위법하지 않습니다. 그러나 재배포, 무단 이용 등 저작권을 침해하는 리버싱은 법적인 문제로 이어질 수 있다는 점을 미리 명시해 두고 다음 단계로 이어서 진행하겠습니다.
Static Analysis vs Dynamic Analysis
리버싱을 통해 대상 소프트웨어의 동작 원리를 알아내기 위해서는 크게 두 가지의 방법이 쓰입니다.
프로그램을 실행시키지 않고 분석하는 정적 분석 방법 (Static Analysis) 과 프로그램을 실행시켜서 입출력과 내부 동작 단계를 살피며 분석하는 동적 분석 방법 (Dynamic Analysis) 이 이 두 가지에 해당됩니다.
정적 분석을 위해서는 실행 파일을 구성하는 모든 요소, 대상 실행 파일이 실제로 동작할 CPU 아키텍처에 해당하는 어셈블리 코드를 이해하는 것이 필요합니다.
또한 동적 분석을 하기 위해서는 실행 단계별로 자세한 동작 과정을 살펴봐야 하므로, 환경에 맞는 디버거를 이용해 단계별로 분석하는 기술을 익혀야 합니다.
4. 코드가 컴파일되는 과정
Source Code → Binary Code
사람이 이해할 수 있는 소스 코드를 컴퓨터가 이해할 수 있는 형태인 프로그램(이하 바이너리)로 바꾸려면 컴파일을 거쳐야 합니다.
이러한 과정에 사용되는 프로그램을 '컴파일러’라고 부릅니다. 모든 프로그래밍 언어가 컴파일러를 통해서 실행 가능한 바이너리가 되는 것은 아니지만, 대개는 단독적으로 실행 가능한 바이너리가 되기 위해서 컴파일 과정을 거칩니다.
컴파일러가 소스 코드를 바이너리로 변환하기 위해서는 몇 가지 단계를 거칩니다.
컴파일러: 소스 코드 -> 바이너리
Source Code → 중간언어 → Binary Code
먼저 원본 소스 코드는 사람이 알아보기 쉽도록 각종 주석이나 매크로 등을 포함하고 있습니다. 또는 참조할 헤더 파일을 포함하고 있기도 합니다. 이와 같은 정보는 실제로는 코드가 아니라 참조를 위해 붙여둔 정보이므로, 컴파일러는 이를 모두 미리 처리해서 다음 단계에서 변환할 준비를 마칩니다. -> 실행시킬 필요없는 것은 삭제=결과물:중간 언어
이렇게 준비된 '중간 언어’를 컴파일러가 분석하고 최적화하여 어셈블리 코드로 만들어 줍니다.
어셈블리 코드는 컴퓨터가 이해할 수 있는 기계 코드를 사람이 알아보기 쉽게 명령어(Instruction) 단위로 표현한 것입니다. 즉 어셈블리 코드와 기계 코드는 1:1 대응이 가능하므로, 최종적으로 어셈블리 코드가 기계 코드로 번역되는 과정을(어셈블, Assemble) 거쳐 실행 가능한 바이너리가 완성됩니다.
Source Code ← ??? ← Binary Code
바이너리를 분석해서 어떤 방식으로 동작하는지, 나아가 어떤 소스 코드를 바탕으로 만들어졌는지를 알아내려면 분석가는 컴파일러가 수행하는 과정을 역으로 진행해야 합니다.
따라서 주어진 바이너리를 -> 어셈블리 코드로 변환하고, 변환된 어셈블리 코드를 분석하면 대상 바이너리가 어떤 식으로 동작하는지 알 수 있게 됩니다. 이렇게 바이너리 코드를 어셈블리 코드로 변환하는 과정을 Disassemble(디스어셈블) 이라고 합니다.
'리버싱’으로 통용되는 소프트웨어 리버스 엔지니어링, 특히 정적 분석 방법에 해당되는 방법은 디스어셈블을 거쳐 나온 어셈블리 코드를 분석하여 소프트웨어의 동작 구조를 알아내는 과정을 가리킵니다.
'보안공부 > 배운내용정리' 카테고리의 다른 글
[dreamhack-ReverseEngineering] 2. x64 기초 (0) | 2021.09.03 |
---|---|
dreamhack06.NoSql (0) | 2021.07.16 |
dreamhack05. Sql injection (0) | 2021.07.08 |
칼리리눅스 설치 (0) | 2021.05.23 |
dreamhack 04.Client-side Advanced (0) | 2021.05.21 |