IT 그리고 정보보안/Knowledge base

리버싱(Reversing) 그리고 올리디버거(Ollydbg)

plummmm 2021. 4. 17. 10:51
반응형

Reverse Engineering (역공학) 말그대로 프로그램을 뒤집어 까는 것이다.

리버싱 하는 방법에는 2가지가 있다.

 

먼저 정적 분석

파일을 실행하지 않고 있는 그대로의 모습으로 분석하는 것이다.

파일 종류, 크기, 헤더, API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 

등의 다양한 내용을 확인하는 것이다.

디스어셈블러를 이용해 내부 코드와 구조를 확인하는 것도 여기에 속한다.

 

다음 동적 분석

파일을 직접 실행 시켜서 분석하는 것이다.

디버깅을 통하여 흐름과 메모리 상태 등을 살펴보는 방법.

파일, 레지스트리, 네트워크 등을 관찰하고 디버거를 이용하여 프로그램 내부 구조를 분석하는 것이다.

 

이 두가지 방법을 적절히 혼용하여 사용하면 된다.

 

이 외에 기초적인 단어들에 대해 설명을 좀 드림.

 

소스 코드 : 말그대로 프로그래밍 소스 코드.

헥사 코드 : 프로그램들이 모두 바이너리 형식으로 이루어져 있는 것은 알 것임. 근데 0과 1로만 된 바이너리를

                아무리 고수라도 금방금방 분석하기란 쉽지 않은 법.. 그래서 보기 쉽게 16진수로 변환한 코드이다.

 

어셈블리 코드 : 헥사 코드를 보고도 솔직히 뭔말인지 알기는 힘들다. 그래서 한 단계 더 고급인 어셈블리 코드가 있다.

                      헥사 코드를 디스어셈블 시키면 어셈블리 코드가 나온다. 리버싱에선 주로 이녀석을 분석한다.

 

패치 : 프로그램의 파일 이나 실행 중인 프로세스 메모리의 내용을 변경하는 작업을 패치라고 한다.

         그걸 악용하는 것이 크랙이다. 패치는 게임을 좀 해봤다면 많이 들어봤을 단어라 생각된다.

 

그럼 가장 기본이 되는 디버거를 활용한 동적분석에 대해 알아보자.

동적분석의 대표적인 툴인 올리디버거부터 보자

 

ollydbg 기초

c언어나 여타 고급 언어로 소스 코딩을 하고 나서 컴파일을 하면 오브젝트 파일이 생성되고

오브젝트 파일에서 실행파일이 링크된다. (.exe) 우린 보통 이 실행파일 (*.exe)을 리버싱 하게 된다. 

 

알다시피 모든 컴퓨터 프로그램들은 기계어로 이루어져 있다. ?? 기계가 알아먹어야 돌아가니까

이건 사람이 보기엔 너무 멀미가 난다.

그래서 우리는 Debugger (디버거)라는 툴을 사용한다. 

이 디버거에 탑재된 Disassembler(디스어셈블러) 모듈이 기계어를 어셈블리 어로 번역해서 보여준다.

 

대표적으로 Ollydbg, IDA Pro, Immunity Debugger 등이 있다.

이번 포스팅에서는 올리디버거의 사용법을 한번 알아보겠다.

무료인데 대단한 녀석이다. 플러그 인도 강력하고..

 

구하는건 검색하면 1분 안에 받음 기본 인터페이스를 한번 살펴보자.

* Code windows : 디스어셈블 코드를 보여주는 창. 

* Register windows : 레지스터에 저장된 값을 실시간으로 보여주는 창. 수정 가능

* Dump windows : 프로세스에서 원하는 메모리 주소 위치를 헥사값, 아스키/유니코드 값으로 보여줌. 수정 가능

* Stack windows : ESP(스택 포인터) 가 가르키는 스택 메모리를 실시간으로 보여줌. 수정 가능

 

그럼 Hello world를 일단 Ollydbg로 실행하여 본다.

 

 

딱 실행하면 코드윈도우에 이렇게 뜬다.

여기 켜자마자 딱 보이는 코드를 EP code 라고 한다. Entry Point 코드

 

Entry Point는 윈도우 실행파일의 시작점을 의미한다.

프로그램을 처음 딱 켰을 때 가장 먼저 실행되는 코드를 말함.

 

맨 위에 주소값 004011A0에서 딱 시작하는 것 같아 보인다. (실행 시작 주소)

이 부분을 자세히 보자.

 

004011A0 : 프로세스의 가상 메모리 주소 값이다.

E8 67150000 : 명령어 이다. CPU 명령어.

CALL HelloWor. 0040270C : OP code를 보기 쉽게 어셈블리어로 변환해 놓은 것이다.

 

일단 그럼 잠시 올리디버거에서 자주 쓰는 기능 단축키를 알아보자.

* Restart (Ctrl + F2) : 처음부터 다시 디버깅 시작

* Step into (F7) : 하나의 OP코드 실행. (Call 만나면 내부로 딸려 들어간다.)

* Step over (F8) : Step into와 같지만 call 만나도 따라 들어가지 않고 함수만 실행한다.

* Execute till Return (Ctrl + F9) : 함수 코드 내에서 리턴까지 실행한다. (함수 탈출 할 때 씀)

 

어셈블리어에 대한 정리를 간략하게 해둔 포스팅이 있으니

보고 왔다고 가정하고 하고 간단한 분석을 진행하겠다.

Hello world의 메인함수를 한번 찾아보자.

 

CALL 명령이 나왔으니 일단 무슨 함수를 호출하는 것이다.

0040270C 함수 안으로 한번 들어가보자. 위에 가르쳐준 F7 눌르면됨.

Step into로 들어오면 004027C 함수 내부 코드이다.

가장 오른쪽에 있는 글씨들이 주석이다. 

빨간 글씨로 되어있는 것들은 API 함수이다.

 

근데 우리가 아까 실행한 Hello world 프로그램에는 생전 처음보는 API 함수가 나온다..

그럼 이건 우리가 찾고 있는 main 함수가 아니다.

 

여기는 Visual C++ 자체에서 프로그램 실행을 위해 추가싴틴 stub code 라는 것이다.

실제 우리가 돌리는 프로그램에 대한 코드가 아니라는 말.

 

그라먼 이 함수를 일단 빠져나가야지.

 

004027C 함수코드 밑으로 쭉쭉 내려오다보면 004027A1가 보이는데.. 함수 리턴 하는 곳이다

여기서 이제 OP코드를 실행하면 함수를 빠져나와

아까 들어갔던 함수 다음 주소로 가게된다.

 

그럼 이제 저 004011A5 의 JMP 명령도 실행해보자.

 

JMP문으로 분기하였다.

여기서 부터 다시 F7을 눌러가며 메인함수를 찾아보자.

 

00401056에서 한번 CALL 명령이 나온다. 들어가면 아래와 같다.

 

이녀석이 메인일까?? 아니다.

왜냐면 MessageBox() API 함수를 호출하는 코드가 없기 때문에. 

일단 Return 까지 날아가서(ctrl + F9) 탈출하자.

 

그렇게 쭉쭉 분석하다보면 아래와 같은 코드가 나온다.

 

GetCommandLine\ 이라는 녀석을 CALL하는 명령이 나오는데..

이 명령어는 Win32 API를 호출하는 코드이다.

방금 한것 처럼 계속 메인함수를 찾아보자.

 

내려가다보면 이녀석이 나온다.

일단은 들어가서 보자. 

 

MessageBox\ 가 보인다. 제대로 들어왔나보다. 여기가 메인함수이다.

 

이제 그럼 Ollydbg의 추가적인 명령어들을 한번 알아보자.

* Go to [ctrl + G] : 원하는 주소로 이동한다.

* Execute till Cursor [F4] : 커서 위치 까지 실행. 디버깅하고 싶은 주소까지 실행

* Comment [ ; ] : 코멘트 추가

* User-defined comment : 오른쪽 마우스로.. 코멘트 찾기

* Set/Rest BreakPoint [F2] : 브레이크포인트 설정

* Run [F9] : 브레이크포인트가 걸려있는 곳까지 실행 

* Show the current EIP [ * ] : 현재 EIP 위치를 보여준다.

* Show the previous Cursor [ - ] : 직전 커서 위치를 다시 보여준다.

* Preview CALL/JMP address [Enter] : 커서가 CALL/JMP 위치에 있다면 해당 주소를 따라가서 보여줌.

                                                     코드를 실행하지 않고 함수의 내용을 알아볼 때 좋음.

* Assemble [ space bar ] : 코드 작성

* All intermodular calls [마우스 오른쪽 Search for all intermodular calls] : 코드에서 호출되는 모든 API 함수 보기

* All referenced text strings [ 마우스 오른쪽 Search for all referenced text strings] : 코드에서 참조되는 문자열 보기 

 

ollydbg 활용하기

1. 베이스캠프 설정하기

디버깅 할 때 ctrl + F2로 계속 다시 시작을 하면 상당히 불편하다. EIP값이 초기화 되기 때문에.

베이스 캠프 개념으로 무언가를 설정해둔다면 다시 실행한다해도 바로 거기까지 갈 수 있다.

몇가지 방법이 있는데..

 

1) Goto 명령 : 직접 주소를 치고 들어가는 것이다. 가고싶은 해당하는 주소를 외워야 한다. 적어놓든지.

2) Break Point 설정 : BP를 설정해두면 현재 EIP에서 BP가 걸린 곳까지만 실행된다. 

3) 주석 : [ ; ] 단축키를 이용해 코멘트를 달아놓으면 User-defined comment 기능으로 찾아갈 수 있다.

4) 레이블 : [ : ] 단축키로 레이블을 지정하여 그쪽으로 찾아갈 수 있다. 레이블이란 주소에 이름을 지어주는 것이다.

 

 

2. 원하는 코드 빠르게 찾기.

앞서 했던 방식으로 메인 함수를 찾다간 멘탈이 골로갈 수도 있다.

메인함수 같이 자신이 리버싱할 때 원하는 코드를 쉽게 찾는 방법을 한번 알아보자.

 

1) 코드 실행

- F8 Step over를 이용하여 계속 코드를 실행 시키다보면 어느 순간 프로그램이 실행되는 함수 부분이 있을 것이다.

  앞서 했던 메인 함수 찾기에서는 MessageBox가 뜨면서 Hello world 가 찍히는 코드인데, 실행하다 보면

  메세지박스가 딱 하고 뜰 때가 있다. 그 때의 함수가 메인함수 일 것이다.

 

2) 문자열 검색 방법

- Search for → All referenced text strings 를 들어가면 프로그램 코드에서 참조되는 문자열 목록이 쫙 나온다.

 

저렇게 문자열이 PUSH 되는 걸 보고 자신이 접근하고자 하는 코드에 관련된 문자열을 확인하고 

더블클릭하면 바로 접근할 수있다.

 

3) API 검색(1) - 호출 코드에 Break Point

Search for → All intermodular calls 에 들어간다.

  문자열과 마찬가지로 사용된 API 함수들도 목록을 뽑아서 확인할 수 있다.

 

맨위에 MessageBox() 호출코드가 있다. 더블클릭하면 그쪽으로 감..

어떤 API가 쓰였을지 예상할 수 있다면 아주 쉽게 원하는 코드를 찾아낼 수 있다.

 

4) API 검색(2) - API 코드에 직접 BP

- 앞에 3번 처럼 모든 실행 파일에서 API함수 목록을 뽑아낼 수 있는 것은 아니다.

  파일을 패킹하거나 안티디버깅이 걸려있으면 파일 구조가 아예 바껴버리므로..

  

  이런 경우에 메모리에 로딩된 DLL에 직접 BP를 걸어본다. 

  Search for → Name in all modules 메뉴를 실행하고 messagebox를 타이핑해서 검색해보자.

더블클릭하면 MessageBoxW 함수가 나타난다.

 

반응형

'IT 그리고 정보보안 > Knowledge base' 카테고리의 다른 글

메모리 스택(Stack)영역  (0) 2021.04.17
x86 메모리 구조  (0) 2021.04.17
어셈블리 - REP 명령어  (0) 2021.04.17
어셈블리어 - CALL / JMP / RET  (0) 2021.04.17
어셈블리어 - CMP  (0) 2021.04.17