SlideShare a Scribd company logo
PE File Format 
발표자 : 임채상
프로그램 : 계산기(calc.exe) 
분석도구 : PEview.exe 
◆ PE 구조의 정의 
- PE는 Portable Executable의 약자로서 윈도우즈(Win32)의 기본 파일 구조이다. 
- 해당 파일은 Win32 환경 어디에서도 실행 가능하다. 
- 윈도우즈 파일 중 EXE, DLL, SYS파일이 PE구조를 가지고 있다. 
- 파일이 실행되기 위해서는 많은 정보가 필요하다. 
→ 파일의 아이콘 
→ 프로그램의 시작위치 
→ 호출하는 함수의 정보 등 
- 프로그램과 관련된 많은 정보가 PE 구조에 저장되어 있고 Win32 운영체제는 해당 정보를 읽어 
프로그램을 실행 시킨다. 
◆ PE파일 종류 
-실행 파일 계열 : exe, scr(Screen Saver) 
-라이브러리 계열 : dll, OCX(Active X) 
-드라이브 계열 : SYS 
-오브젝트 파일 계열 : OBJ
◆ PE 구조의 헤더파일 
1. IMAGE_DOS_HEADER 
- 도스와의 호환성을 위해 존재하는 부분 
- 도스 헤더 안에는 여러 가지 정보가 들어 있지만 이 정보 중 첫 번째와 마지막 항목 2가지를 
제외하고는 윈도우즈환경에서 프로그램을 실행하는데 사용되지 않는다. 
- 첫 번째 항목 도스헤더를 나타내는 'MZ'이다. 
PE구조는 도스 헤더로 시작되기 때문에 PE구조를 가지고 있는 파일은 모두 'MZ'로 시작된다. 
- 두 번째 항목 도스헤더의 마지막에 위치한 정보로 다음 헤더인 IMAGE_NT_HEADERS의 옵셋정보 이다. 
이 정보를 이용하여 NT_HEADER의 위치를 찾아 갈 수 있다
2. MS-DOS Stub Program 
- 항목에는 해당 프로그램을 도스 운영체제에서 실행하면 "This program cannot be run in DOS mode"라는 
메시지를 띄우고 종료하도록 하는 프로그램 코드가 삽입된다 (없어도 파일 실행에는 문제가 없다.) 
- 코드와 데이터의 혼합으로 이루어져 있으며, 크기가 일정하지 않다
3. IMAGE_NT_HEADERS 
- 프로그램이 윈도우즈 시스템에서 동작하기 위한 많은 정보를 포함하고 있다. 
1) IMAGE_NT_HEADERS 구성 
- Signature, IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER로 구성되어 있다. 
2) File Header의 시작점 확인 
- IMAGE_DOS_HEADER의 offset to New EXE Header 확인 
tip, 윈도우즈 실행파일을 판단하는 가장 기본적인 방법 
-> 해당 파일의 바이너리 정보에서 'MZ'로 시작하고 'PE'문자열이 있는지 확인
3-1. Signature 
- PE헤더의 시작을 의미하는 'PE'문자열로 시작한다 
3-2. IMAGE_FILE_HEADER 
- 파일의 전반적인 정보를 가진다 
- 해당 파일의 타깃이 되는 시스템의 정보, 섹션의 개수, 생성 날짜, 
IMAGE_OPTIONAL_HEADER의 크기, 해당 파일의 특징 가짐 
> Machine : 타깃 시스템의 타입 
> NumberOfSections : 섹션의 개수 
> TimeDateStamp : 파일이 생성된 시간과 날짜 
> PointerToSymbolTable : 심볼 테이블의 파일 오프셋 
> NumberOfSymbols : 심볼 테이블의 엔트리 개수 
> SizeOfOptionalHeader : optionalheader의 크기 
> Characteristics : 파일 속성관련 플래그
3-3. IMAGE_OPTIONAL_HEADER 
- 프로그램 실행과 관련된 다양한 정보를 저장한다. 
1) 기본구조
2) 파일 오프셋, RVA, VA 
PE구조에서 특정 위치를 나타낼 때 파일 오프셋, RVA, VA 3가지 값을 사용한다. 
- 파일 오프셋 : 기본적으로 바이너리 파일에서의 값은 파일 오프셋을 사용한다. 
- RVA : 가상메모리와 관련된 위치값을 사용하기 위해서는 RVA를 사용한다. 
- VA : 가상메모리에 완전히 로드된 상태의 위치값을 나타내기 위해서는 VA를 사용한다. 
◇ 파일 오프셋(File Offset) 
* 파일의 위치값을 말한다 
* 파일의 첫 부분을 0으로 시작해 한 바이트(byte)단위로 1씩 증가 
* 파일 오프셋의 마지막 값은 파일사이즈 - 1 이다. 
파일 오프셋의 시작이 0부터이기 때문에 파일 사이즈 - 1 과 같음 
* 파일 오프셋을 사용하는 경우는 파일내의 위치를 나타내기 위해서 사용되며 
PEview 메뉴 중 File Offset 항목을 클릭하면 파일 오프셋형태로 PE구조의 위치정보가 표현됨 
◇ RVA (Relative Virtual Address) 
* 가상 메모리에서 상대주소 값을 말한다 
* RVA는 가상 메모리에 로드된 상태에서 상대 위치를 나타내기 위해 사용하는 값 
* RVA가 가상 메모리에 로드 된 정확한 주소 값을 나타내지는 않다 
* RVA는 해당 프로그램이 메모리에 로드 된 시작 지점부터의 오프셋을 표현하기 위해 사용 
* 가상 메모리에 로드된 시작 위치부터 RVA값 만큼 떨어진 곳에 가면 해당 데이터를 찾을 수 있다. 
* 해당 프로그램이 가상 메모리의 특정 공간에 로드 됐을 때 고정된 값을 사용하면 해당 값을 
모두 수정해주어야 하는 번거로움이 있다 
* RVA값을 사용하면 가상 메모리 어디에 로드 되어도 상관없이 프로그램이 로드 된 주소 
(프로그램의 메모리 시작 주소) + RVA로 해당 데이터가 있는 위치를 정학히 찾아갈 수 있다 
* 파일 오프셋과 RVA의 차이 
- 파일 오프셋 : 파일 상태의 시작 위치에서 오프셋만큼 떨어진 곳에서 원하는 데이터 찾을 수 있다 
- RVA : 해당 파일이 메모리에 로드된 시작 위치부터 RVA값 만큼 떨어진 곳에서 원하는 데이터를 찾을 수 있다 
* 해당 파일이 메모리에 로드 될 때는 파일 형태 그대로 로드되지 않기 때문에 메모리 상태에서는 
파일 오프셋 값을 사용해서는 원하는 데이터에 접근할 수 없고 RVA값을 통해서만 접근한다 
◇ VA (Virtual Address) 
* 가상 메모리에서 데이터의 주소 값을 말한다. 
* VA는 가상 메모리에서 데이터의 주소값을 나타낸다는 것은 RVA와 같다 
* 차이점은 가상 메모리의 고정된 주소값을 나타낸다는 점이다 
* 해당 프로그램이 지정된 가상 메모리 공간에 로드된 상태의 메모리 전체 주소값을 나타낸다
3) 옵션 
*Magic : 파일의 상태를 확인 할 수 있는 정수값. 
32비트 PE파일 0x10B, 64비트 PE파일 0x20B, 롱 파일 0x107로 표현된다. 
* SizeOfCode : 파일 내의 섹션 사이즈의 합 
* AddressOfEntryPoint : 프로그램의 시작위치로 RVA로 표현된다. 
로더는 해당 프로그램을 가상 메모리에 로드하고 프로세스를 동작하기 위해 해당 위치의 명령어를 수행한다. 
악성코드의 경우 악성코드를 수행하기 위해 해당 항목의 값을 자신의 명령어 위치로 변경한다. 
* BaseOfCode : 메모리에 로드된 코드섹션의 시작 위치, RVA로 표시 
* BaseOfData : 메모리 상태에서 데이터 섹션의 시작 위치, RVA로 표시 
* ImageBase : 해당 프로그램이 메모리에 로드되기 원하는 위치. 
exe 파일은 0x00400000, dll파일은 0x1000000이 일반적인 위치이다. 
Exe의 경우 가상 메모리상에 하나의 프로세스만 존재하기 때문에 지정된 위치로 로드되는 경우가 많다. 
하지만 dll의 경우에는 하나의 exe프로그램에 여러 개의 dll이 같이 메모리에 로드되기 때문에 
지정된 위치에 로드되지 않는 경우가 많이 발생한다. 
ImageBase의 지정된 위치로 프로그램이 로드되면 ImageBase + RVA로 VA를 구할 수 있다. 
* SectionAlignment : 가상 메모리로 로드되는 섹션의 크기 단위. FileAlignment보다는 같거나 커야 한다. 
메모리에 로드된 섹션의 크기는 반드시 SectionAlignment의 배수가 되어야 한다. 
ex> 섹션의 코드 크기가 0x900이고 SectionAlignment의 값은 0x1000이면 섹션의 크기는 0x1000이 된다. 
* FileAlignment : 파일 상태에서 섹션 크기 단위. 
512와 64K 사이의 2의 n승에 해당 하는 값이어야 한다. 
파일 단위의 섹션의 크기는 FileAlignment의 배수가 되어야 한다. 
파일의 경우도 섹션의 실제 크기가 0x201이더라도 FileAlignment의 값이 
0x200이면 0x400의 크기를 갖는다. 
* SizeOfImage : 메모리 상태에서 이미지의 크기 
* SizeOfHeaders : FileAlignment에 맞춰진 전체 헤더의 크기 
* CheckSum : 파일의 체크섬 값으로 모든 드라이버 파일 및 부팅 시에 로드되는 일부 DLL 파일은 
체크섬 값이 항목의 값과 같아야 로드된다. 특정 프로그램에서라도 체크섬 값을 확인해 
해당 파일의 변조 유무를 판단하기도 한다. 
* Subsystem : 프로그램이 동작하기 위한 subsystem을 나타내는 항목으로 해당 항목을 통해 파일이 
드라이버 파일인지 구분할 수 있다. 
IMAGE_SUBSYSTEM_NATIVE(1)값을 가질 경우 드라이버 파일이다. 
* NumberOfRvaAndSize : IMAGE_DATA_DIRECTORY의 개수를 나타낸다. 
=> 파일 오프셋과 RVA, VA는 프로그램의 특정 위치를 지정하기 위해 사용되지만, 
파일 상태에서는 파일 오프셋을 사용하고, 가상 메모리상의 상대적 위치를 알기 위해서는 RVA, 
가상 메모리의 절대 주소는 VA를 사용 한다.
4. IMAGE_DATA_DIRECTORY의 상위 2개 : EXPORT Table / IMPORT Table 
* EXPORT Table 
- DLL파일과 같이 해당 파일 내부의 함수를 외부의 프로그램에 제공할 목적으로 제작한 함수의 리스트 
- 외부에 제공하는 함수가 없을 경우 0값이 된다. 
* IMPORT Table 
- 해당 프로그램에서 사용할 DLL파일과 함수의 리스트 
- 외부에서 제공하는 함수를 사용하지 않을 경우 0이 되지만 윈도우즈 시스템 파일을 제외한 
프로그램은 외부 함수를 쓰기 때문에 0이 되는 경우는 없다.
5. IMAGE_SECTION_HEADER.(text,data,rsrc,reloc) 
- 파일의 여러 구성요소는 각각 구분되어 저장되는데 이러한 구분 단위를 섹션이라 한다. 
- 각각의 섹션은 위치 및 사이즈가 달라서 이러한 정보를 저장하기 위해 IMAGE_SECTION_HEADER를 사용한다. 
1) text 
2) data
3) rsrc 
4) reloc
* Name 
- 8바이트 아스키 문자열로 각 섹션의 이름이다. 섹션명의 지정된 규칙은 없다. 
- 사용자가 원하는 이름으로 편집해도 프로그램 동작에는 아무런 영향을 주지 않는다. 
- 일반적인 컴파일러를 통해 작성된 프로그램은 다음과 같은 섹션명을 사용한다. 
> ".text" 코드 섹션 
> ".data" 초기화된 데이터 세션 
(초기화된 데이터란 전역 변수와 정적변수와 같이 컴파일 단계에서 초기화되는 데이터를 의미한다.) 
> ".rsrc" 프로그램의 리소스 관련 세션 
* VirtualSize 
- 가상 메모리에 로드된 상태에서의 섹션의 크기 
* VirtualAddress 
- 섹션의 첫 바이트의 RVA (시작점을 의미한다) 
* SizeOfRawData 
- 파일 상태에서의 섹션 크기 
* PointerToRawData Charateristics 
- 파일 상태에서 섹션의 첫 바이트의 파일 오프셋 
- 섹션의 특징을 나타내는 플래그 
> IMAGE_SCN_CNT_CODE(0x00000020) : 섹션에 실행 가능한 코드가 포함된다. 
> IMAGE_SCN_MEM_SHARED(0x10000000) : 메모리에서 공유 가능 
> IMAGE_SCN_MEM_EXECUTE(0x20000000) : 실행 가능한 섹션 
> 코드가 들어 있는 섹션은 해당 플래그를 가진다. 바이러스 코드가 삽입된 섹션은 해당 플래그를 
추가해서 자신의 코드가 실행되도록 한다. 
> IMAGE_SCN_MEM_READ(0x40000000) : 섹션을 읽을 수 있는 플래그로 섹션 내에 저장된 데이터를 
읽어서 사용한다 
> IMAGE_SCN_MEM_WRITE(0x80000000) : 섹션에 쓰기가 가능한 플래그로 해당 플래그를 가진 섹션은 
메모리 상에서 데이터 쓰기가 가능하다.
6. BOUND IMPORT Directory Table(IDT) 
* IDT는 프로그램이 사용하는 DLL에 관한 정보를 저장한다 
* 1개의 IDT는 1개의 DLL에 관한 정보를 저장한다 
* IDT의 구조에는 임포트할 DLL의 이름(Name RVA)과 해당 DLL에서 사용할 함수의 
목록(Import Name Table RVA)이 나타나 있다 
* 목록을 사용해 운영체제의 로더는 해당 프로그램을 가상 메모리에 로드 할 때 필요한 
DLL의 리스트를 찾아서 연결한다 
* 메모리에 로드되지 않은 경우에는 해당 DLL을 메모리에 로드한다 
* 그 후 프로그램은 해당 함수를 호출해서 사용한다
7. BOUND IMPORT DLL Names 
- Import Name Table에는 각각의 DLL에서 임포트하는 함수의 목록이 나타난다. 
- 임포트된 함수를 호출하기 위해서는 함수의 이름을 사용하는 방법과 ordinal number 를 사용하는 방법이 있다. 
- DLL의 함수는 각 함수마다 이름과 ordinal number를 가진다. 
하지만 특정 윈도우즈 함수는 함수이름은 공개되어 있지 않고 ordinal number만 공개된 경우가 있다. 
이러한 경우 ordinal number를 사용해서 해당 함수를 호출한다. 
* Hint/Name RVA → 해당 함수의 이름을 통해 해당 함수를 호출 
* Ordinal → 함수의 번호만 있을 경우는 해당 번호로 함수를 호출

More Related Content

Similar to Pe+file+format

안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명
Peter YoungSik Yun
 
System+os study 1
System+os study 1System+os study 1
System+os study 1
Jinkyoung Kim
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
ssuser3fb17c
 
Java_01 기초
Java_01 기초Java_01 기초
Java_01 기초
Hong Hyo Sang
 
Java 기초
Java 기초Java 기초
Java 기초
Hyosang Hong
 
10 동기및비동기장치io
10 동기및비동기장치io10 동기및비동기장치io
10 동기및비동기장치io
ssuser3fb17c
 
Windosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptxWindosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptx
HolyTak
 
멀티티어 애플리케이션 개발과 배포
멀티티어 애플리케이션 개발과 배포멀티티어 애플리케이션 개발과 배포
멀티티어 애플리케이션 개발과 배포
Devgear
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
Seungyong Lee
 
Project anarchy로 3d 게임 만들기 part_2_vforge피하기
Project anarchy로 3d 게임 만들기 part_2_vforge피하기Project anarchy로 3d 게임 만들기 part_2_vforge피하기
Project anarchy로 3d 게임 만들기 part_2_vforge피하기
Dong Chan Shin
 
Exynos4210 beginnerrev10
Exynos4210 beginnerrev10Exynos4210 beginnerrev10
Exynos4210 beginnerrev10mimul
 
Chapter 17
Chapter 17Chapter 17
Chapter 17nacheon
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
NAVER Engineering
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드중선 곽
 
(160820) #fitalk fileless malware forensics
(160820) #fitalk    fileless malware forensics(160820) #fitalk    fileless malware forensics
(160820) #fitalk fileless malware forensics
INSIGHT FORENSIC
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
jieun kim
 
프로그래밍 언어 기초(델파이,C++)
프로그래밍 언어 기초(델파이,C++)프로그래밍 언어 기초(델파이,C++)
프로그래밍 언어 기초(델파이,C++)
Devgear
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1
Jinkyoung Kim
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드
중선 곽
 
PE File Format and Packer - Inc0gnito 2016
PE File Format and Packer - Inc0gnito 2016PE File Format and Packer - Inc0gnito 2016
PE File Format and Packer - Inc0gnito 2016
Hajin Jang
 

Similar to Pe+file+format (20)

안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명
 
System+os study 1
System+os study 1System+os study 1
System+os study 1
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
Java_01 기초
Java_01 기초Java_01 기초
Java_01 기초
 
Java 기초
Java 기초Java 기초
Java 기초
 
10 동기및비동기장치io
10 동기및비동기장치io10 동기및비동기장치io
10 동기및비동기장치io
 
Windosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptxWindosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptx
 
멀티티어 애플리케이션 개발과 배포
멀티티어 애플리케이션 개발과 배포멀티티어 애플리케이션 개발과 배포
멀티티어 애플리케이션 개발과 배포
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
 
Project anarchy로 3d 게임 만들기 part_2_vforge피하기
Project anarchy로 3d 게임 만들기 part_2_vforge피하기Project anarchy로 3d 게임 만들기 part_2_vforge피하기
Project anarchy로 3d 게임 만들기 part_2_vforge피하기
 
Exynos4210 beginnerrev10
Exynos4210 beginnerrev10Exynos4210 beginnerrev10
Exynos4210 beginnerrev10
 
Chapter 17
Chapter 17Chapter 17
Chapter 17
 
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
[16]Obfuscation 101 : 난독화, 프로가드, R8, 트랜스포머 API
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드
 
(160820) #fitalk fileless malware forensics
(160820) #fitalk    fileless malware forensics(160820) #fitalk    fileless malware forensics
(160820) #fitalk fileless malware forensics
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
 
프로그래밍 언어 기초(델파이,C++)
프로그래밍 언어 기초(델파이,C++)프로그래밍 언어 기초(델파이,C++)
프로그래밍 언어 기초(델파이,C++)
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드
 
PE File Format and Packer - Inc0gnito 2016
PE File Format and Packer - Inc0gnito 2016PE File Format and Packer - Inc0gnito 2016
PE File Format and Packer - Inc0gnito 2016
 

Pe+file+format

  • 1. PE File Format 발표자 : 임채상
  • 2. 프로그램 : 계산기(calc.exe) 분석도구 : PEview.exe ◆ PE 구조의 정의 - PE는 Portable Executable의 약자로서 윈도우즈(Win32)의 기본 파일 구조이다. - 해당 파일은 Win32 환경 어디에서도 실행 가능하다. - 윈도우즈 파일 중 EXE, DLL, SYS파일이 PE구조를 가지고 있다. - 파일이 실행되기 위해서는 많은 정보가 필요하다. → 파일의 아이콘 → 프로그램의 시작위치 → 호출하는 함수의 정보 등 - 프로그램과 관련된 많은 정보가 PE 구조에 저장되어 있고 Win32 운영체제는 해당 정보를 읽어 프로그램을 실행 시킨다. ◆ PE파일 종류 -실행 파일 계열 : exe, scr(Screen Saver) -라이브러리 계열 : dll, OCX(Active X) -드라이브 계열 : SYS -오브젝트 파일 계열 : OBJ
  • 3. ◆ PE 구조의 헤더파일 1. IMAGE_DOS_HEADER - 도스와의 호환성을 위해 존재하는 부분 - 도스 헤더 안에는 여러 가지 정보가 들어 있지만 이 정보 중 첫 번째와 마지막 항목 2가지를 제외하고는 윈도우즈환경에서 프로그램을 실행하는데 사용되지 않는다. - 첫 번째 항목 도스헤더를 나타내는 'MZ'이다. PE구조는 도스 헤더로 시작되기 때문에 PE구조를 가지고 있는 파일은 모두 'MZ'로 시작된다. - 두 번째 항목 도스헤더의 마지막에 위치한 정보로 다음 헤더인 IMAGE_NT_HEADERS의 옵셋정보 이다. 이 정보를 이용하여 NT_HEADER의 위치를 찾아 갈 수 있다
  • 4. 2. MS-DOS Stub Program - 항목에는 해당 프로그램을 도스 운영체제에서 실행하면 "This program cannot be run in DOS mode"라는 메시지를 띄우고 종료하도록 하는 프로그램 코드가 삽입된다 (없어도 파일 실행에는 문제가 없다.) - 코드와 데이터의 혼합으로 이루어져 있으며, 크기가 일정하지 않다
  • 5. 3. IMAGE_NT_HEADERS - 프로그램이 윈도우즈 시스템에서 동작하기 위한 많은 정보를 포함하고 있다. 1) IMAGE_NT_HEADERS 구성 - Signature, IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER로 구성되어 있다. 2) File Header의 시작점 확인 - IMAGE_DOS_HEADER의 offset to New EXE Header 확인 tip, 윈도우즈 실행파일을 판단하는 가장 기본적인 방법 -> 해당 파일의 바이너리 정보에서 'MZ'로 시작하고 'PE'문자열이 있는지 확인
  • 6. 3-1. Signature - PE헤더의 시작을 의미하는 'PE'문자열로 시작한다 3-2. IMAGE_FILE_HEADER - 파일의 전반적인 정보를 가진다 - 해당 파일의 타깃이 되는 시스템의 정보, 섹션의 개수, 생성 날짜, IMAGE_OPTIONAL_HEADER의 크기, 해당 파일의 특징 가짐 > Machine : 타깃 시스템의 타입 > NumberOfSections : 섹션의 개수 > TimeDateStamp : 파일이 생성된 시간과 날짜 > PointerToSymbolTable : 심볼 테이블의 파일 오프셋 > NumberOfSymbols : 심볼 테이블의 엔트리 개수 > SizeOfOptionalHeader : optionalheader의 크기 > Characteristics : 파일 속성관련 플래그
  • 7. 3-3. IMAGE_OPTIONAL_HEADER - 프로그램 실행과 관련된 다양한 정보를 저장한다. 1) 기본구조
  • 8. 2) 파일 오프셋, RVA, VA PE구조에서 특정 위치를 나타낼 때 파일 오프셋, RVA, VA 3가지 값을 사용한다. - 파일 오프셋 : 기본적으로 바이너리 파일에서의 값은 파일 오프셋을 사용한다. - RVA : 가상메모리와 관련된 위치값을 사용하기 위해서는 RVA를 사용한다. - VA : 가상메모리에 완전히 로드된 상태의 위치값을 나타내기 위해서는 VA를 사용한다. ◇ 파일 오프셋(File Offset) * 파일의 위치값을 말한다 * 파일의 첫 부분을 0으로 시작해 한 바이트(byte)단위로 1씩 증가 * 파일 오프셋의 마지막 값은 파일사이즈 - 1 이다. 파일 오프셋의 시작이 0부터이기 때문에 파일 사이즈 - 1 과 같음 * 파일 오프셋을 사용하는 경우는 파일내의 위치를 나타내기 위해서 사용되며 PEview 메뉴 중 File Offset 항목을 클릭하면 파일 오프셋형태로 PE구조의 위치정보가 표현됨 ◇ RVA (Relative Virtual Address) * 가상 메모리에서 상대주소 값을 말한다 * RVA는 가상 메모리에 로드된 상태에서 상대 위치를 나타내기 위해 사용하는 값 * RVA가 가상 메모리에 로드 된 정확한 주소 값을 나타내지는 않다 * RVA는 해당 프로그램이 메모리에 로드 된 시작 지점부터의 오프셋을 표현하기 위해 사용 * 가상 메모리에 로드된 시작 위치부터 RVA값 만큼 떨어진 곳에 가면 해당 데이터를 찾을 수 있다. * 해당 프로그램이 가상 메모리의 특정 공간에 로드 됐을 때 고정된 값을 사용하면 해당 값을 모두 수정해주어야 하는 번거로움이 있다 * RVA값을 사용하면 가상 메모리 어디에 로드 되어도 상관없이 프로그램이 로드 된 주소 (프로그램의 메모리 시작 주소) + RVA로 해당 데이터가 있는 위치를 정학히 찾아갈 수 있다 * 파일 오프셋과 RVA의 차이 - 파일 오프셋 : 파일 상태의 시작 위치에서 오프셋만큼 떨어진 곳에서 원하는 데이터 찾을 수 있다 - RVA : 해당 파일이 메모리에 로드된 시작 위치부터 RVA값 만큼 떨어진 곳에서 원하는 데이터를 찾을 수 있다 * 해당 파일이 메모리에 로드 될 때는 파일 형태 그대로 로드되지 않기 때문에 메모리 상태에서는 파일 오프셋 값을 사용해서는 원하는 데이터에 접근할 수 없고 RVA값을 통해서만 접근한다 ◇ VA (Virtual Address) * 가상 메모리에서 데이터의 주소 값을 말한다. * VA는 가상 메모리에서 데이터의 주소값을 나타낸다는 것은 RVA와 같다 * 차이점은 가상 메모리의 고정된 주소값을 나타낸다는 점이다 * 해당 프로그램이 지정된 가상 메모리 공간에 로드된 상태의 메모리 전체 주소값을 나타낸다
  • 9. 3) 옵션 *Magic : 파일의 상태를 확인 할 수 있는 정수값. 32비트 PE파일 0x10B, 64비트 PE파일 0x20B, 롱 파일 0x107로 표현된다. * SizeOfCode : 파일 내의 섹션 사이즈의 합 * AddressOfEntryPoint : 프로그램의 시작위치로 RVA로 표현된다. 로더는 해당 프로그램을 가상 메모리에 로드하고 프로세스를 동작하기 위해 해당 위치의 명령어를 수행한다. 악성코드의 경우 악성코드를 수행하기 위해 해당 항목의 값을 자신의 명령어 위치로 변경한다. * BaseOfCode : 메모리에 로드된 코드섹션의 시작 위치, RVA로 표시 * BaseOfData : 메모리 상태에서 데이터 섹션의 시작 위치, RVA로 표시 * ImageBase : 해당 프로그램이 메모리에 로드되기 원하는 위치. exe 파일은 0x00400000, dll파일은 0x1000000이 일반적인 위치이다. Exe의 경우 가상 메모리상에 하나의 프로세스만 존재하기 때문에 지정된 위치로 로드되는 경우가 많다. 하지만 dll의 경우에는 하나의 exe프로그램에 여러 개의 dll이 같이 메모리에 로드되기 때문에 지정된 위치에 로드되지 않는 경우가 많이 발생한다. ImageBase의 지정된 위치로 프로그램이 로드되면 ImageBase + RVA로 VA를 구할 수 있다. * SectionAlignment : 가상 메모리로 로드되는 섹션의 크기 단위. FileAlignment보다는 같거나 커야 한다. 메모리에 로드된 섹션의 크기는 반드시 SectionAlignment의 배수가 되어야 한다. ex> 섹션의 코드 크기가 0x900이고 SectionAlignment의 값은 0x1000이면 섹션의 크기는 0x1000이 된다. * FileAlignment : 파일 상태에서 섹션 크기 단위. 512와 64K 사이의 2의 n승에 해당 하는 값이어야 한다. 파일 단위의 섹션의 크기는 FileAlignment의 배수가 되어야 한다. 파일의 경우도 섹션의 실제 크기가 0x201이더라도 FileAlignment의 값이 0x200이면 0x400의 크기를 갖는다. * SizeOfImage : 메모리 상태에서 이미지의 크기 * SizeOfHeaders : FileAlignment에 맞춰진 전체 헤더의 크기 * CheckSum : 파일의 체크섬 값으로 모든 드라이버 파일 및 부팅 시에 로드되는 일부 DLL 파일은 체크섬 값이 항목의 값과 같아야 로드된다. 특정 프로그램에서라도 체크섬 값을 확인해 해당 파일의 변조 유무를 판단하기도 한다. * Subsystem : 프로그램이 동작하기 위한 subsystem을 나타내는 항목으로 해당 항목을 통해 파일이 드라이버 파일인지 구분할 수 있다. IMAGE_SUBSYSTEM_NATIVE(1)값을 가질 경우 드라이버 파일이다. * NumberOfRvaAndSize : IMAGE_DATA_DIRECTORY의 개수를 나타낸다. => 파일 오프셋과 RVA, VA는 프로그램의 특정 위치를 지정하기 위해 사용되지만, 파일 상태에서는 파일 오프셋을 사용하고, 가상 메모리상의 상대적 위치를 알기 위해서는 RVA, 가상 메모리의 절대 주소는 VA를 사용 한다.
  • 10. 4. IMAGE_DATA_DIRECTORY의 상위 2개 : EXPORT Table / IMPORT Table * EXPORT Table - DLL파일과 같이 해당 파일 내부의 함수를 외부의 프로그램에 제공할 목적으로 제작한 함수의 리스트 - 외부에 제공하는 함수가 없을 경우 0값이 된다. * IMPORT Table - 해당 프로그램에서 사용할 DLL파일과 함수의 리스트 - 외부에서 제공하는 함수를 사용하지 않을 경우 0이 되지만 윈도우즈 시스템 파일을 제외한 프로그램은 외부 함수를 쓰기 때문에 0이 되는 경우는 없다.
  • 11. 5. IMAGE_SECTION_HEADER.(text,data,rsrc,reloc) - 파일의 여러 구성요소는 각각 구분되어 저장되는데 이러한 구분 단위를 섹션이라 한다. - 각각의 섹션은 위치 및 사이즈가 달라서 이러한 정보를 저장하기 위해 IMAGE_SECTION_HEADER를 사용한다. 1) text 2) data
  • 12. 3) rsrc 4) reloc
  • 13. * Name - 8바이트 아스키 문자열로 각 섹션의 이름이다. 섹션명의 지정된 규칙은 없다. - 사용자가 원하는 이름으로 편집해도 프로그램 동작에는 아무런 영향을 주지 않는다. - 일반적인 컴파일러를 통해 작성된 프로그램은 다음과 같은 섹션명을 사용한다. > ".text" 코드 섹션 > ".data" 초기화된 데이터 세션 (초기화된 데이터란 전역 변수와 정적변수와 같이 컴파일 단계에서 초기화되는 데이터를 의미한다.) > ".rsrc" 프로그램의 리소스 관련 세션 * VirtualSize - 가상 메모리에 로드된 상태에서의 섹션의 크기 * VirtualAddress - 섹션의 첫 바이트의 RVA (시작점을 의미한다) * SizeOfRawData - 파일 상태에서의 섹션 크기 * PointerToRawData Charateristics - 파일 상태에서 섹션의 첫 바이트의 파일 오프셋 - 섹션의 특징을 나타내는 플래그 > IMAGE_SCN_CNT_CODE(0x00000020) : 섹션에 실행 가능한 코드가 포함된다. > IMAGE_SCN_MEM_SHARED(0x10000000) : 메모리에서 공유 가능 > IMAGE_SCN_MEM_EXECUTE(0x20000000) : 실행 가능한 섹션 > 코드가 들어 있는 섹션은 해당 플래그를 가진다. 바이러스 코드가 삽입된 섹션은 해당 플래그를 추가해서 자신의 코드가 실행되도록 한다. > IMAGE_SCN_MEM_READ(0x40000000) : 섹션을 읽을 수 있는 플래그로 섹션 내에 저장된 데이터를 읽어서 사용한다 > IMAGE_SCN_MEM_WRITE(0x80000000) : 섹션에 쓰기가 가능한 플래그로 해당 플래그를 가진 섹션은 메모리 상에서 데이터 쓰기가 가능하다.
  • 14. 6. BOUND IMPORT Directory Table(IDT) * IDT는 프로그램이 사용하는 DLL에 관한 정보를 저장한다 * 1개의 IDT는 1개의 DLL에 관한 정보를 저장한다 * IDT의 구조에는 임포트할 DLL의 이름(Name RVA)과 해당 DLL에서 사용할 함수의 목록(Import Name Table RVA)이 나타나 있다 * 목록을 사용해 운영체제의 로더는 해당 프로그램을 가상 메모리에 로드 할 때 필요한 DLL의 리스트를 찾아서 연결한다 * 메모리에 로드되지 않은 경우에는 해당 DLL을 메모리에 로드한다 * 그 후 프로그램은 해당 함수를 호출해서 사용한다
  • 15. 7. BOUND IMPORT DLL Names - Import Name Table에는 각각의 DLL에서 임포트하는 함수의 목록이 나타난다. - 임포트된 함수를 호출하기 위해서는 함수의 이름을 사용하는 방법과 ordinal number 를 사용하는 방법이 있다. - DLL의 함수는 각 함수마다 이름과 ordinal number를 가진다. 하지만 특정 윈도우즈 함수는 함수이름은 공개되어 있지 않고 ordinal number만 공개된 경우가 있다. 이러한 경우 ordinal number를 사용해서 해당 함수를 호출한다. * Hint/Name RVA → 해당 함수의 이름을 통해 해당 함수를 호출 * Ordinal → 함수의 번호만 있을 경우는 해당 번호로 함수를 호출