티스토리 뷰

Reversing/ETC

[Reversing] PE 파일 구조

정뚱띵 2019. 1. 30. 20:29
728x90
반응형

[Reversing] PE 파일 구조


정확하지 않을 수 있으며, 전체를 다루지 않았습니다.


  • 주요 구조

 IMAGE_DOS_HEADER 

 IMAGE_NT_HEADER

 IMAGE_FILE_HEADER

 IMAGE_OPTIONAL_HEADER

 IMAGE_SECTION_HEADER

 IMAGE_IMPORT_DESCRIPTOR

 IMAGE_EXPORT_DIRECTIORY

 IMAGE_IMPORT_BY_NAME

 IMAGE_THUNK_DATA32


                      peview로 바라본 PE 구조


typedef struct _IMAGE_DOS_HEADER
{
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;


WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

e_magic

PE 가장 첫 번째 값으로 MZ(마크 즈비코프스키) 헤더를 통해 MS-DOS 헤더의 시작을 알려줍니다.

(이 바이너리가 PE 파일인지 검사)


e_lfanew

IMAGE_NT_HEADER의 구조체 위치를 알려줍니다.


typedef struct _IMAGE_NT_HEADERS {



DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;


} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

Signature

PE\0\0

시그니처 값은 변경이 불가능하다.

(변경할 시 정상적인 실행X)


IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER

나머지는 두 개의 큰 구조체로 이루어져 있다.


  1. IMAGE_FILE_HEADER
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

* Machine
어떤 CPU에서 실행 가능한지 알려줍니다.
CPU별로 고유의 값을 갖고 있습니다

* NumberOfSections
이 파일이 가진 섹션의 개수를 알려줍니다.
(일반적으로 .text, .rdata, .data, .rsrc 4개 섹션이 존재)

TimeDateStamp
obj -> EXE 파일을 만든 시간을 알려줍니다.

* SizeOfOptionalHeader
IMAGE_OPTIONAL_HEADER32의 구조체 크기를 알려줍니다.
(PE를 로딩하기 위한 굉장히 중요한 구조체를 담고 있음)
* 운영체제마다 크기가 다를 수 있어 PE로더에서는 이 값을 먼저확인

* Characteristics
이 파일이 어떤 형식인지 알려줍니다.

  1. IMAGE_OPTIONAL_HEADER
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;


* Magic

32bit - 0x10B

64bit - 0x20B


MajorLinkerVersion, MinorLinkerVersion

사용한 컴파일러 버전을 알려줍니다.


SizeOfCode

코드 양의 전체 크기

 악성코드 : 이 값을 참고하여 자신의 코드를 복제할 위치 기준을 세웁니다.

 솔 루 션  : 코드 섹션의 무결성 검사?


* AddressOfEntryPoint

파일이 메모리에서 시작되는 지점을 알려줍니다.

Entry Point의 RVA 값을 가지고있습니다.


BaseOfCode

실행 코드 위치

 ImageBase와 BaseofCode를 더한 값부터 코드 시작을 알려줍니다.


* ImageBase

로드할 가상 메모리 주소를 알려줍니다.

EXE 파일의 값은 00400000h 이고 DLL 파일은 01000000h 값을 갖습니다.


PE 로 ImageBase AddressOfEntryPoint 값을 더하여 EIP 레지스터 값을 설정합니다.

그 주소가 프로그램이 시작되는 첫번째 주소라고 할 수 있습니다.


* SectionAlignment, FileAlignment

각 섹션을 정렬하기 정렬하기 위한 정렬 단위를 알려줍니다.

(기본값 0x1000)


* SizeOfImage

EXE/DLL이 메모리에 로딩됐을 때 전체크기를 알려줍니다.


* SizeOfHeaders

PE 헤더의 크기를 알려줍니다.

(기본값 0x1000)


IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]

Export, Import, Rsre 디렉터리와 IAT등의 가상 주소와 크기 정보 등을 알려줍니다.



PE 파일에서 섹션은 프로그램의 실제 내용을 담고 있는 블록입니다.
PE가 가상 주소 공간에 로드된 후 섹션 내용이 참고되어 실행이 됩니다.

  • 셕션의 종류

 섹션

이름 

설명 

 .txt

코드 섹션 

프로그램을 실행하기 위한 코드를 담는 섹션

CPU의 명령 포인터가 되는 IP 레지스터는 이 섹션 내에 존재하는 번지를 가진다. 

 .data

데이터 섹션 

초기화된 전역 변수들을 담고 있는 읽고 쓰기가 가능한 섹션

(가상 메모리에 매핑될 때 보통 .data 섹션)

 .rdata

읽기 전용 데이터 섹션 

문자열 상수나 C++ 가상 함수 테이블 등을 배치

코드 상 참조하는 읽기 전용 데이터들을 말한다. 

 .reloc

기준 재배치 섹션 

실행 파일에 대한 기준 재배치 정보를 담고 있는 섹션 

 .edata

export 섹션 

내보낼 함수에 대한 정보를 담고 있는 섹션 

 .idata

import 섹션 

가져올 dll과 그 함수 및 변수에 대한 정보를 담고 있는 섹션

(Import Address Table) 

 .didat

지연 로드 섹션 

Delay-Loading을 위한 섹션 

 .tls

TLS 섹션 

_declspec(thead) 지시어와 함께 선언되는 스레드 지역 저장소를 위한 섹션 

 .rsrc

리소스 섹션 

대화상자, 아이콘, 버전 정보등 PE 파일이  담고 있는 리소스 관련 데이터들이 존재

 .debug

디버깅 섹션 

디버깅 정보를 포함 



주로 각 섹션에 대한 이름, 시작 주소, 사이즈 등의 정보를 관리하는 구조체 입니다.

typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];


union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;





IMAGE_Section_Header에 대한 정보 


IMAGE_Section_Header 

- IAT 호출 구조


- Address Table

로드된 실제 함수 주소 목록


- Name Table

Import 함수 이름 주소 목록


- Hints/Names & DLL Names

로그하는 Import 함수 이름 목록


실행 파일 : EXE, SCR 

라이브러리 : DLL, OCX

드라이버 : SYS

오브젝트 파일 : OBJ




728x90
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
250x250