----------용어 설명----------------------------------------------------------
PE포멧 : 윈도우 OS가 파일을 실행시키기 위해서 Portable Executable 포멧(확장자 .exe 와 .dll)을 동적 라이브러리를 링킹하기 휘한 참조값과 API export and import tables, 리소스 데이터와 TLS 데이터를 캡슐화한 것으로 마이크로소프트에서 1993년 표준안을 디자인 했다.
MZ : PE를 만든 Mark Zbikowski의 이니셜로써 MS-DOS 헤더의 시작을 알리는 문자이다.
----------설명에 앞서 이해해야할 Little Endian and Big Endian------------------
Little Endian : 낮은 주소에 낮은 자릿수를 기록하고, 주소값이 증가할수록 높은 자릿수에 기록하는 방식. 산술 유닛에서 산술 연산의 순서가 낮은 자릿수에서 높은 쫃으로 가면서 처리되기 때문에 프로세서의 산술연산이 더 쉬워진다.
<인텔, X86 계열>
Big Endian : 정수로 정렬된 큰 수에 대한 비교를 메모리의 작은 주소부터 큰 주소 방향으로 읽으면서 바로 비교할 수 있어 더 빨리 처리 할 수 있으며, 모든 정수와 문자열을 같은 순서 방향으로 읽을 수 있다는 장점이 있다.
============================================================================
PE구조
도스에더 'IMAGE_DOS_HEADER' 라는 구조체로 구성되어 있다.
e_magic : DOS헤더를 구별하는 식별자.
e_lfanew : PE헤더가 있는 곳의 offset 값.
-----------------------------------------------------------------------------
참고 : Reverse Engineering 리버스엔지니어링 역분석 구조와 원리 _박병익 / 이강석
PE포멧 : 윈도우 OS가 파일을 실행시키기 위해서 Portable Executable 포멧(확장자 .exe 와 .dll)을 동적 라이브러리를 링킹하기 휘한 참조값과 API export and import tables, 리소스 데이터와 TLS 데이터를 캡슐화한 것으로 마이크로소프트에서 1993년 표준안을 디자인 했다.
MZ : PE를 만든 Mark Zbikowski의 이니셜로써 MS-DOS 헤더의 시작을 알리는 문자이다.
----------설명에 앞서 이해해야할 Little Endian and Big Endian------------------
Little Endian : 낮은 주소에 낮은 자릿수를 기록하고, 주소값이 증가할수록 높은 자릿수에 기록하는 방식. 산술 유닛에서 산술 연산의 순서가 낮은 자릿수에서 높은 쫃으로 가면서 처리되기 때문에 프로세서의 산술연산이 더 쉬워진다.
<인텔, X86 계열>
Big Endian : 정수로 정렬된 큰 수에 대한 비교를 메모리의 작은 주소부터 큰 주소 방향으로 읽으면서 바로 비교할 수 있어 더 빨리 처리 할 수 있으며, 모든 정수와 문자열을 같은 순서 방향으로 읽을 수 있다는 장점이 있다.
============================================================================
PE구조
DOS Header
DOS Stub
PE File Header
Optional Header
Section Table
Sections
DOS Stub
PE File Header
Optional Header
Section Table
Sections
CodeView Debug Information -옵션
COFF Symbols -옵션
COFF Line Numbers -옵션
.reloc ------|
.idata |
.edata |---Sections
.data |
.text ----- |
Section table
Data Directory
IMAGE_FILE_HEADER -도스헤더
PE\0\0
DOS 'MZ" HEADER
COFF Symbols -옵션
COFF Line Numbers -옵션
.reloc ------|
.idata |
.edata |---Sections
.data |
.text ----- |
Section table
Data Directory
IMAGE_FILE_HEADER -도스헤더
PE\0\0
DOS 'MZ" HEADER
도스에더 'IMAGE_DOS_HEADER' 라는 구조체로 구성되어 있다.
typedef struct _IMAGE_DOS_HEADER {
WORD e_magic;
WORD e_cblp;
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;
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 : DOS헤더를 구별하는 식별자.
e_lfanew : PE헤더가 있는 곳의 offset 값.
-----------------------------------------------------------------------------
typedef struct _IMAGE_NT_HEADERS{
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
typedef struct _IMAGE_FILE_HEADER{
WORD Machine;
WORD NumberOfSections;
DWORD TimeDataStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
WORD NumberOfSections;
DWORD TimeDataStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
Machine : 어느 플랫폼(CPU)에서 실행되는지에 대한 정보
NumberOfSections : 섹션을 분석하기 위해 사용되는 값. ->파일을 Hex 파일등으로 열어 하드 코딩시에 이 값을 변경시켜 섹션 수를 늘리고 코드를 추가할 수 있다.
TimeDataStemp : 파일이 생성된 날짜와 시간
SizeOfOptionalHeader : IMAGE_FILE_HEADER 바로 다음에 위치한 IMAGE_OPTIONAL_HEADER 구조체의 크기. 32비트 윈도우즈에서는 0xE0 이다.
Characteristics : 현재 파일이 exe 인지 dll파일인지 플래그를 가지고 있다.
NumberOfSections : 섹션을 분석하기 위해 사용되는 값. ->파일을 Hex 파일등으로 열어 하드 코딩시에 이 값을 변경시켜 섹션 수를 늘리고 코드를 추가할 수 있다.
TimeDataStemp : 파일이 생성된 날짜와 시간
SizeOfOptionalHeader : IMAGE_FILE_HEADER 바로 다음에 위치한 IMAGE_OPTIONAL_HEADER 구조체의 크기. 32비트 윈도우즈에서는 0xE0 이다.
Characteristics : 현재 파일이 exe 인지 dll파일인지 플래그를 가지고 있다.
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 SzieOfImage;
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_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY{
DWORD VirtualAddress;
DWORD VirtualSize;
DWORD VirtualSize;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
-----------------------------------------------------------------------------
섹션 헤더(섹션 테이블)
섹션 헤더(섹션 테이블)
typedef struct _IMAGE_DECTION_HEADER{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union{
union{
DWORD PhysicalAddress;
DWORD VirtualSize;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
참고 : Reverse Engineering 리버스엔지니어링 역분석 구조와 원리 _박병익 / 이강석