OllyDBG

Ollydbg 화면구성

PE 파일 동작한다는 것은 메모리에 올라간 PE 데이터 중에서 .text 섹션에 기록되어 있는 기계어 코드가 실행되는 것이다.

 

1. Disassemble 영역

- 어셈블리 코드를 실행 또는 중지할 수 있도록 한다.

- 왼쪽부터 차례로 Address(명령어가 실행될 주소), 기계어 코드, 어셈블리 코드(기계어를 어셈블리어로 바꿔놓음)로 구성된다.

 

2. 레지스터

- 레지스터는 CPU 내부에 존재하는 다목적 저장 공간

- 이러한 레지스터 값을 표시해주는 곳

 

3. Memory Dump

- Address 주소, Hex dump, 각 Hex에 따른 ASCII코드로 해석된 창을 보여준다.

- 프로세스 동작과정에서 읽고 쓰는 값들을 확인 및 수정이 가능

 

4. Stack

- Stack 영역은 임시 저장 공간

- 스택 주소, 스택 값, comment 순으로 표시된 창

- 함수 호출 시 필요한 인자 정보를 전달

 

 

어셈블리어

:: 기계어와 일대일 대응이 되는 컴퓨터 프로그래밍의 저급 언어

기계어를 어셈블리어로 번역하는 작업은 디버거가 알아서 해주기 때문에 기계어를 알아야 하는 경우는 잘 없다.

 

명령어 설명
PUSHAD 8개의 범용 레지스터 값을 Stack에 저장
POPAD PUSHAD 명령에 의해서 Stack에 저장된 값을 다시 레지스터에 입력
PUSH A A값을 Stack에 넣음
POP 레지스터 Stack에서 값을 꺼내서 레지스터에 넣음
INC A A값을 1 증가
DEC A A값을 1 감소

 

명령어 설명
ADD A B A와 B를 더해서 그 결과를 A에 저장
SUB A B A에서 B를 빼고 그 결과를 A에 저장
IML A B A와 B를 곱한 후 그 결과를 A에 저장
LEA A B A를 B로 만듬(레지스터에서 주로 사용)
MOV A B B를 A로 복사
XCHG A B A와 B를 바꿈
TEST A B A와 B를 AND 연산
(연산 결과 값이 a에 저장되지 않지만 ZF 플래그 설정에 영향을 줌)
(연산 결과가 0이면 ZF가 1이 되고 연산 결과가 0이 아니면 ZF는 0이 된다)
AND A B A와 B를 AND 연산
(연산 결과 값이 a에 저장되고 ZF 플래그 설정에 영향을 줌)
(연산 결과가 0이면 ZF가 1이 되고 연산 결과가 0이 아니면 ZF는 0이 된다)
CMP A B 비교 구문. A와 B가 같은지 판단
(같을 경우 ZE는 1이 되고 다를 경우 ZE는 0이 된다.)

 

명령어 설명
JMP                         Address 해당 주소로 무조건 이동
JZ(Zump if Zero)         Address 연산 결과가 0이면(ZE=1)이동하고,
아니면(ZF=0) 다음 명령을 실행
ZE(Zump if Equal)        Address 연산 결과가 0이면(ZE=1)이동하고,
아니면(ZF=0) 다음 명령을 실행
JNZ(Zump if not Zero)  Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행
JNE(Zump if not Equal) Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행

 

명령어 설명
MOVE         DWORD PTR DS:[Address],  EAX Address부터 4Byte 값을 EAX로 복사
CALL          DWORD PTR DS:[Address] Address부터 4Byte 주소 값을 호출

DWORD ; 크기 값 (BYTE : 1byte, WORD : 2byte, DWORD: 4byte)

PTR ; 기준

 

 

주요 단축키

단축키 정보 설명
F2 BreakPoint를 설치하고 해제
F7 하나의 명령어 실행,
Call 명령어 실행 시 해당 함수 내부로 들어감
F8 하나의 명령어 실행,
Call 명령어 실행 시 해당 함수 내부로 들어가지 않음
F9 실행(Execute)
Ctrl + F2 디버깅을 처음부터 다시 시작(재실행)
Ctrl + F9 해당 함수 내에서 RETN 명령어까지 실행
Ctrl + G
원하는 주소로 이동
Alt + M Memory Map 확인

 

'Study > Reversing' 카테고리의 다른 글

Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23

IAT & EAT 이해

# Sample 01.exe는 Beep() API를 사용

# Beep() 기능은 kernel32.dll에서 제공

# Sample 01.exe는 Beep() API 주소를 어떻게 알아낼까?

 

Sample 01.exe를 실행하면 PE 로더가 이것과 kernel32.dll을 함께 올린다.

이 올리는 과정에서 PE 로더는 kernel32.dll의 EAT로 가서, Beep() API의 실제 호출 주소를 알아온다. 

그리고 나서 이것(주소)을 Sample 01.exe의 IAT에 기록한다.

그러면 Sample 01.exe는 필요할 때마다 자신의 IAT를 참고하여 함수를 호출하는 것이다.

 


그림1 kernel32.dll_Beep_API RVA : 0x00083081

 

그림 2 kernel32.dll_Image Base : 0x76030000

0x00083081 + 0x76030000 = 0x760B3081 (Beep 호출 주소)

 

그림3 Sample 01.exe의 Import Address Table 영역

 

그림4 Beep() API 호출 코드에서 바로 확인 가능

 

Beep() API를 호출할 때 직접 호출하지 않고 0x00405000 주소에 있는 4Byte 값을 가져와서 호출한다.

0x00405000 주소는 Sample 01.exe의 Import Address Table(IAT) 영역이다.

해당 주소로 이동해보면 Sample 01.exe가 사용하는 API들의 호출 주소가 기록되어 있다.

 

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23
리버싱의 이해  (0) 2021.01.22

PE 헤더

:: 작은 구조체들이 모여서 만들어진 데이터 덩어리

:: 크게 DOS Header와 DOS Stub, NT Header, Section Header로 구성

 

 

PE 헤더 (출처 위키백과)

 

 

DOS Header DOS Header는 DOS와 호환성을 위해 만들었다. 파일의 처음에 위치하고 0x40의 크기를 갖는다.
DOS Stub 해당 파일이 MS-DOS에서 실행될 경우, 화면에 출력될 메시지와 코드가 기록되어 있다. 
DOS Stub은 옵션이기 때문에 파일 실행에 영향이 없다. 크기가 일정하지 않고 없어도 되는 영역이다.
NT Header 파일 실행에 필요한 중요 정보들을 담고 있다. 0xF8의 크기를 갖는다.
Section Header  각 섹션의 속성 정보를 담고 있다.

 

ⓐ DOS Header

- DOS Signature : 실행 파일이라는 표식. 2Byte이고 "MZ(0x5A4D)" 값을 가진다.

- NT Header Offset : NT 헤더의 시작 지점에 대한 정보를 담는다. 4Byte.

 

ⓑ NT Header 

- PE Signature : 올바른 PE 파일인지 확인하는 용도로 사용된다. 4Byte이고 "0x50450000"값을 가진다.

- FILE HEADER : 파일의 Physical 정보를 담고 있는 구조체이다.

Machine에서 UPU -> CPU (오타)

- OPTIONAL HEADER : 파일의 Losical 정보를 담고 있는 구조체이다.

 

ⓒ Section Header

- VirtualSize : 메모리에서 섹션이 차지하는 크기이다.

- RVA(VirtualAddress) : 메모리에서 섹션의 시작 주소이다.

- SizeOfRawData :  파일에서 섹션이 차지하는 크기이다.

- OffsetToRawData : 파일에서 섹션의 시작 주소이다.

- Characteristics :  섹션의 속성 정보를 담고 있다.

 

VA (Virtual Address, 가상주소) & RVA (Relative Virtual Address, 상대주소)

:: 특정 값의 위치 정보를 표현할 때

파일에서의 위치(Offset), 메모리에서의 위치(VA), 메모리에서의 상대 위치(RVA)를 사용한다.

여기서 RVA는 파일 데이터가 메모리에 올라간 시작 지점으로부터 떨어져 있는 상대 위치이다.

VA = Image Base + RVA

(Image Base는 OPTIONAL HEADER에 있다.

실행파일이 메모리에 올라간 위치로, 파일 데이터가 메모리에 올라갈 때 기준이 되는 주소 값을 가진다. 기본적으로 EXE는 0x004000000, DLL은 0x10000000 값을 가진다.)

 

ⓓ IAT(Import Address Table)와 EAT(Export Address Table)

Windows 운영체제에서 EXE가 동작할 때 DLL이라는 비서를 두고 활용하게끔 만들어져 있다. 이것을 가능하게 하는 것이 IAT와 EAT 메커니즘이다. 

- IAT : DLL이 제공하는 함수들 중 사용하는 것들에 대한 정보를 기술해놓은 테이블

(ex; EXE를 로드하는 과정에서 필요한 함수 호출 주소 정보를 획득하여 EXE의 IAT에 기록, EXE는 동작 과정에서 필요할 때마다 IAT를 참고하여 함수를 호출)

- EAT : DLL 자신이 서비스하는 함수에 대한 정보를 기술해 놓은 테이블

 

 

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE File Format 이해  (0) 2021.01.23
리버싱의 이해  (0) 2021.01.22

PE File Format

:: Windows 운영체제에서 동작하는 실행 파일의 구성 방식

:: 실행 파일이 어떻게 구성되어야 하는지, 그 원칙을 정의해 놓은 것

:: Microsoft가 운영체제를 설계하는 과정에서 실행파일의 효율적이고 합리적인 구성을 고민하고 선택한 방식

:: 다양한 운영체제에서의 이식성을 보여준다는 뜻에서 이식이 가능한 실행형식(Portable Executable)이라는 이름이 붙음

 

PE 파일의 종류

ⓐ 실행 파일 계열 : EXE, SCR(Screen Saver)

ⓑ 라이브러리 계열 : DLL, OCX(Active X)

ⓒ 드라이브 계열 : SYS

ⓓ 오브젝트 파일 계열 : OBJ

 

PE 파일을 만들 떄, 일반적으로 Visual Studio와 같은 개발 도구를 사용한다.

(개발 도구 → 코드 작성 → 컴파일 → 실행 파일(exe)완성)

 

 

실행 파일을 만드는 과정은 어떻게 될까?

1. 코드와 데이터를 분리 (실행 코드 : .text 섹션에 기록 // 데이터 : .data 섹션에 기록)

2. 코드 → 기계어로 변환

3. 문자열 데이터 아스키 값으로 변환

4. 명령코드와 아스키 값을 담기 위한 생성 (PE File Format)

5. PE 헤더 작성 (PE헤더 : 파일 실행에 필요한 정보가 기록되어 있는 영역)

   --- 사용자가 작성한 값이 아니라, 코드를 컴파일하는 과정에서 컴파일러가 알아서 작성함

   --- 컴파일러가 PE 파일에 Header를 기록하는 이유 ? PE 파일을 만드는 것은 컴파일러지만, 실행 주체는 운영체제

                                                                       따라서 운영체제 입장에서 PE 파일을 실행하기 위해 필요한 정보를 담아줘야 함

6. 명령코드 채움 (.text 섹션 : 파일이 동작하는 데 필요한 코드가 기록되어 있는 영역)

7. 데이터 채움 (.data 섹션 : 파일이 실행될 때 필요한 부가적인 정보가 기록되어 있는 영역)

8. 실행 파일 완성!

 

 

 

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24
리버싱의 이해  (0) 2021.01.22

리버싱

:: 소프트웨어 공학의 한 분야로, 이미 만들어진 시스템을 역으로 추적하여

처음의 문서나 설계기법 등의 자료를 얻어내는 일

 

즉, 사람이 인식하기 어려운 기계어를 재번역하고, 재번역된 코드를 읽어서 기능과 역할을 알아낸다고 보면 된다.

 

 

소스코드

 

Visual Studio 와 같은 개발 툴을 이용해서 코드를 작성하고 컴파일을 하면 실행 파일이 만들어진다.

TEST.exe 파일 확인

 

실행파일이 만들어졌다는 것은 우리가 작성한 코드가 기계어로 변환되었음을 의미한다.

 

기계어로 번역된 main()코드의 일부

 

그리고 이 기계어를 CPU가 읽어서 문자열을 출력시킨다.

TEST.exe 파일 실행

------------------------------------------------------------------------------------------------------------------------------

 

이제 실행 파일을 리버싱해보자

앞서 언급했듯이 실행 파일에는 기계어로 번역된 main() 함수 코드가 있다.

하지만 우리는 기계어를 읽을 수 없다.

 

따라서 리버싱 작업은 보통 WinDBG나 IDA, OllyDBG와 같은 디버깅(디컴파일러) 툴을 사용해서 이루어진다.

이러한 툴들은 사람이 인식하기 어려운 기계어를 재번역하는 데 일차적인 목적이 있다.

 

OllyDBG.exe와 같은 툴로 TEST.exe 파일을 확인하면 

기계어에서 어셈블리어로 재번역된 main()함수 코드를 확인할 수 있다.

 

TEST.exe 메인코드

 

리버싱은 한 마디로, "디버거에서 재번역해 준 어셈블리 코드를 잘 읽고, 기능과 역할을 도출하는 것"이다.

 

------------------------------------------------------------------------------------------------------------------------------

 

리버싱(분석) 방법

 

ⓐ 정적 분석(Static Analysis)

:: 파일을 실행하지 않고 파일의 겉모습을 관찰하여 분석하는 방법

  -- 파일의 종류, 크기, 헤더 정보(PE), Import/Export API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털인증서 등의 다양한 내용을 확인할 수 있다.

  -- 디스어셈블러(ex; IDA)를 이용해 내부 코드와 구조를 확인할 수 있다.

 

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

 

ⓑ 동적 분석(Dynamic Analysis)

: 파일을 실행시켜 행위를 분석하고, 디버깅하여 코드 흐름과 메모리 상태를 살펴보는 방법

  -- 파일, 레지스트리, 네트워크 등을 관찰하면서 프로그램의 행위를 분석한다.

  -- 디버거(ex; OllyDBG)를 이용하여 프로그램 내부 구조와 동작 원리를 분석한다.

 

==> 실행 단계별로 자세한 동작 과정을 살펴봐야 하므로, 환경에 맞는 디버거를 이용해 단계별로 분석하는 기술을 익혀야함

'Study > Reversing' 카테고리의 다른 글

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23

+ Recent posts