본문 바로가기

고등학교 동아리 (리버싱), (잠정 무기한 폐지)

<리버싱 공부> 첫 번째 : 리버싱이란?

오늘부터 리버싱 공부하는 거 정리도 하고, 동아리 친구들도 보라고 끄적끄적 시작
아래 사진은 영어시간에 그린 블로그 배경사진ㅋㅋㅋㅋㅋ

-해킹이란?

일단 먼저 '해킹'이라는 단어의 어원은 MIT에서부터 시작된다. 컴퓨터나 게임 등을 밑바닥까지 파고들며 그 시스템에 대한 완벽한 이해나 주도권을 가지려는 문화를 가리키려고 쓰던 말인데, 대중매체에서 정보보안을 뚫어내는 자극적인 이미지가 퍼지면서 현재의 보안 해킹의 이미지로 굳혀졌다.

오픈소스 프로그램은 소스 코드 수정이 자유롭고, 사용 소프트웨어일지라도 프로그램 사용 계약 내용을 준수하면서 프로그램을 개조한다면 불법은 아니다. 하지만 계약에서 벗어난 행위 (예를 들면 사람들에게 불법적으로 공유를 한다던가 불법 키를 만들어 배포한다던가), 피해를 줄 목적으로 임의로 조작된 프로그램을 배포하는 등의 행위는 범죄이다.

해킹의 세부분야로는 아래와 같다.

  • 시스템 해킹 : 대부분 포너블(Pwnable)이라고 부른다. 시스템의 취약점을 공격해 시스템을 장악하는 기술로 컴퓨터 구조에 대한 깊은 이해가 필요하다.
  • 리버스 엔지니어링 : 리버싱이라고 한다. 프로그램을 어셈블리어 레벨까지 분석해 프로그램의 구조를 알아내고 심지어는 역으로 만들어내기까지 하는 분야이다. 컴퓨터 바이러스를 분석하는 등 해킹을 막기 위해 필요한 기술
  • 웹 해킹 : 웹사이트를 해킹한다. HTML이나 자바스크립트 등으로 웹사이트를 디자인하는 프런트엔드와 Python이나 C언어 등으로 웹과 서버나 프레임워크를 연결하는 백엔드 모두를 하는 풀 스택 프로그래머가 되어야 한다.
  • 포렌식 : 하드디스크 등에서 삭제된 데이터들을 복구해내는 기술이다.
  • 네트워크 해킹 : 네트워크 내의 취약점을 공격하는 기술이다.
  • 암호학 : 암호에 대해 연구하는 학문으로 해킹에서도 매우 중요한 내용이다.

(출처 : 나무위키ㅋㅋㅋ)

-리버싱이란?

일단 오늘부터는 리버싱에 대해서 공부할 것이다. 위에서도 얘기했지만 리버싱에 대해서 조금 더 자세하게 설명하자면,
리버스 엔지니어링(Reverse Engineering, RE: 역공학)이란 물건이나 기계장치 혹은 시스템 등의 구조, 기능, 동작 등을 분석하여 그 원리를 이해하며 단점을 보완하고 새로운 아이디어를 추가하는 일련의 작업이라고 할 수 있다. 내가 앞으로 서술할 것은 정확히 말하면 리버스 '코드' 엔지니어링(Reverse Code Engineering, RCE)이다. 이는 소프트웨어 분야의 리버스 엔지니어링이라고 생각하면 된다. 나는 '리버싱' 또는 '분석'이란 말을 섞어서 얘기하겠다.

실행 파일의 분석을 통해 동작원리를 알아내는 방법은 정적 분석(Static Analysis)과 동적 분석(Dynamic Analysis)으로 크게 두 가지로 나뉜다.

  • 정적 분석 : 프로그램을 실행시키지 않고 분석하는 방법이다. 쉽게 말해 파일의 겉모습을 관찰하는 것인데, 파일의 종류(EXE, DLL, DOC, ZIP 등), 크기, PE 파일의 정보, Import/Export API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 등의 다양한 내용을 확인하는 것이다. 또한 디스 어셈블러(Disassembler)를 이용해서 내부 코드와 그 구조를 확인하는 것도 정적 분석의 범주에 들어갈 수 있다. 정적 분석을 하는 이유는 다음에 얘기할 동적 분석을 할 때 좋은 참고 자료로 활용되기 때문이다.
  • 동적 분석 : 프로그램을 실행시켜서 입출력과 내부 코드 흐름과 메모리 상태 등을 자세히 살피면서 분석하는 방법이다. 파일, 레지스트리(Registry), 네트워크 등을 관찰하면서 프로그램의 행위를 분석한다. 환경에 맞는 디버거(Debugger)를 이용하여 프로그램 내부 구조와 단계별 동작 원리를 분석할 수 있다.

-Source Code, Hex Code, Assembly Code

일단 내가 뒤에 설명할 코드가 컴파일되는 과정을 이해하려면 소스코드, 헥스 코드, 어셈블리 코드에 대한 용어 이해가 필요하다.

  • Source Code : 프로그래밍 언어로 쓰여진 텍스트 파일이다.
  • Hex Code : 생성된 실행 파일은 컴퓨터가 이해할 수 있는 2진수(Binary) 형식으로 되어있다. 그러나 아무리 전문가여도 0과 1로 구성된 바이너리 파일을 직접 보고 의미를 해석하는 것은 불가능에 가깝다. 따라서 2진수를 16진수(Hex) 형식으로 변환시키곤 한다.
  • Assembly Code : 헥스 코드는 사람에게 직관적인 형태는 아니다. 따라서 좀 더 사람이 이해하기 쉬운 명령어 단위로 표현한 어셈블리(Assembly) 코드의 형태로 디버거를 이용해 볼 수 있다.

-코드가 컴파일되는 과정

원본 소스코드는 사람이 알아보기 쉽도록 각종 주석이나 매크로 등을 포함하고 있다. 이와 같은 정보는 실제 코드가 아니라 참조를 위해 붙여둔 정보이므로, 컴파일러는 이를 모두 미리 처리해서 다음 단계에서 변환할 준비를 마친다. 이렇게 준비된 '중간 언어(Intermediate Language)'를 컴파일러가 분석하고 최적화하여 어셈블리 코드로 만들어 준다. 어셈블리 코드와 바이너리 코드가 1:1 대응이 가능하므로, 최종적으로는 Source Code -> Intermediate Language -> Assembly Code -> Binary Code의 단계로 소스코드가 컴파일된다.

바이너리를 분석해서 어떤 방식으로 동작하는지, 나아가 어떤 소스 코드를 바탕으로 만들어졌는지를 분석하려면 컴파일러가 수행하는 과정을 역으로 진행해야 한다. 주어진 바이너리를 1:1 대응이 되는 어셈블리 코드로 변환하고, 어셈블리 코드를 분석하면 대상 바이너리가 어떤 식으로 동작하는지 알 수 있게 된다. 이렇게 바이너리 코드를 어셈블리 코드로 변환하는 과정을 디스어셈블(Disassemble)이라고 한다. Binary Code -> Assembly Code의 과정을 거친다. (이는 위에도 얘기했듯이 정적 분석의 범주에 들어간다.)

오늘은 여기까지 리버싱을 공부하기 전 알아야 할 사항들에 대해서 정리해보았다. 다음 시간에는 어셈블리 코드에 대해서 알아보도록 하자!