-PE포맷은 프로그램 실행 파일의 제일 첫 부분에 존재한다.
DOS Header DOS Stub PE File Header Optional Header Section Table Sections |
IMAGE_DOS_HEADER | |
IMAGE_NT_HEADER | PE\0\0 |
IMAGE_FILE_HEADER | |
IMAGE_OPTIONAL_HEADER | |
IMAGE_SECTION_HEADER |
-도스 헤더 부분은 IMAGE_DOS_HEADER라는 구조체로 구성되어 있다.
typedef struct _IMAGE_DOS_HEADER{ WORD e_magic; //magic number WORD e_cblp; //Bytes on last page of file WORD e_cp; //Pages in file WORD e_crlc; //Relocations WORD e_cparhdr; //Size of header in paragraphs WORD e_minalloc; //Minimum extra paragraphs needed WORD e_maxalloc; //Maximum extra paragraphs needed WORD e_ss; //Initial (relative) SS value WORD e_sp; //Initial SP value WORD e_csum; //Checksum WORD e_ip; //Initial IP value WORD e_cs; //Initial (relative) CS value WORD e_lfarlc; //File address of relocation table WORD e_ovno; //Overlay number WORD e_res[4]; //Reserved words WORD e_oemid; //OEM identifier (for e_oeminfo) WORD e_oeminfo; //OEM information; e_oemid specific WORD e_res2[10]; //Reserved words LONG e_lfanew; //File address of new exe header }IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; |
e_magic
-DOS 헤더를 구별하는 식별자로 이 값을 체크하여 올바른 MZ 파일인지 확인한다. 모든 실행 파일은 파 일 가장 첫 부분에 MZ라는 2바이트의 아스키 코드값을 가지고 있는데 PE로더는 이 값을 체크하여 실행 파일을 메모리에 로드한다.
※e_magic 상수
명칭 | 값 | 설명 |
IMAGE_DOS_SIGNATURE | 0x5A4D | MZ |
IMAGE_OS2_SIGNATURE | 0x454E | NE |
IMAGE_OS2_SIGNATURE_LE | 0x454C | LE(도스) |
IMAGE_VXD_SIGNATURE | 0x454C | LE(장치) |
IMAGE_NT_SIGNATURE | 0x00004550 | PE00(NT계열) |
elanew
-PE 헤더가 있는 곳의 오프셋 값(RVA 값)이다.
※RVA(Relative Virtual Address) : 가상 메모리의 오프셋
typedef struct _IMAGE_NT_HEADERS{ DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; }IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; |
Signature
-이 파일이 올바른 PE 포맷으로 구성되어 있는지 확인하기 위한 일종의 플래그 값이다.
올바른 파일이라면 PE\0\0 값을 갖는다.
FileHeader
-IMAGE_FILE_HEADER의 구조체 멤버. 현재 파일이 exe인지 dll인지, 어느 플랫폼에서 실행되는지, 섹션 의 개수가 몇 개인지의 정보를 담고 있다.
OptionalHeader
-IMAGE_OPTIONAL_HEADER의 구조체 멤버.
typedef struct _IMAGE_FILE_HEADER{ WORD Machine; //호환되는 머신 WORD NumberOfSections; //섹션의 개수 DWORD TimeDateStamp; //오브젝트 생성일자 DWORD PointerToSymbolTable; //COFF 심볼 테이블 주소 DWORD NumberOfSymbols; //심볼 개수 WORD SizeOfOptionalHeader; //IMAGE_OPTIONAL_HEADER 크기 WORD Characteristics; //파일의 정보를 OR 연산하여 표현 }IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; |
Machine
-현재 파일이 어느 플랫폼(CPU)에서 실행되는지에 대한 정보를 가진다.
※Machine 상수
명칭 | 값 | 설명 |
IMAGE_FILE_MACHINE_UNKNOWN | 0 | 알 수 없음 |
IMAGE_FILE_MACHINE_I386 | 0x014C | x86 계열 |
IMAGE_FILE_MACHINE_R3000 | 0x0160 | MIPS Big Endian |
0x0162 | MIPS Little Endian | |
IMAGE_FILE_MACHINE_R4000 | 0x0166 | MIPS Little Endian |
IMAGE_FILE_MACHINE_R10000 | 0x0168 | MIPS Little Endian |
IMAGE_FILE_MACHINE_WCEMIPSV2 | 0x0169 | MIPS Little Endian WCE v2 |
IMAGE_FILE_MACHINE_ALPHA | 0x0184 | Alpha_AXP |
IMAGE_FILE_MACHINE_POWERPC | 0x01F0 | IBM PowerPC Little Endian |
IMAGE_FILE_MACHINE_SH3 | 0x01A2 | SH3 Little Endian |
IMAGE_FILE_MACHINE_SH3E | 0x01A4 | SH3E Little Endian |
IMAGE_FILE_MACHINE_SH4 | 0x01A6 | SH4 Little Endian |
IMAGE_FILE_MACHINE_ARM | 0x01C0 | ARM Little Endian |
IMAGE_FILE_MACHINE_THUMB | 0x01C2 | |
IMAGE_FILE_MACHINE_IA64 | 0x0200 | x64 계열 |
IMAGE_FILE_MACHINE_MIPS16 | 0x0266 | MIPS |
IMAGE_FILE_MACHINE_MIPSFPU | 0x0366 | MIPS |
IMAGE_FILE_MACHINE_MIPSFPU16 | 0x0466 | MIPS |
IMAGE_FILE_MACHINE_ALPHA64 | 0x0284 | ALPHA64 |
NumberOfSections
-섹션을 분석하기 위해 사용되는 값이다.
TimeDateStamp
-파일이 생성된 날짜이다.
SizeOfOptionalHeader
-IMAGE_FILE_HEADER 바로 다음에 위치한 IMAGE_OPTIONAL_HEADER 구조체 크기이다.
Characteristics
-현재 파일이 exe인지 dll 파일인지의 플래그를 가진다.
※Characteristics 상수
명칭 | 값 | 설명 |
IMAGE_FILE_RELOCS_STRIPPED | 0x0001 | Relocation info stripped from file |
IMAGE_FILE_EXCUTABLE_IMAGE | 0x0002 | File is executable |
IMAGE_FILE_LINE_NUMS_STRIPPED | 0x0004 | Line numbers stripped from file |
IMAGE_FILE_LOCAL_SYMS_STRIPPED | 0x0008 | Local symbols stripped from file |
IMAGE_FILE_AGGRESIVE_WS_TRIM | 0x0010 | Agressively trim working set |
IMAGE_FILE_LARGE_ADDRESS_AWARE | 0x0020 | App can handle >2gb addresses |
IMAGE_FILE_BYTES_REVERSED_L0 | 0x0080 | Bytes of machine word are reversed |
IMAGE_FILE_32BIT_MACHINE | 0x0100 | 32bit word machine |
IMAGE_FILE_DEBUG_STRIPPED | 0x0200 | Debugging info stripped from file in .DBG file |
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP | 0x0400 | If Image is on removable media, copy and run from the swap file. |
IMAGE_FILE_NET_RUN_FROM_SWAP | 0x0800 | If Image is on Net, copy and run from the swap file |
IMAGE_FILE_SYSTEM | 0x1000 | System File |
IMAGE_FILE_DLL | 0x2000 | File is a DLL |
IMAGE_FILE_UP_SYSTEM_ONLY | 0x4000 | File should only be run on a UP machine |
IMAGE_FILE_BYTES_REVERSED_HI | 0x8000 | Bytes of machine word are reversed |
typedef struct _IMAGE_OPTIONAL_HEADER{ //표준 구조체 필드 WORD Magic; BYTE MajorLinkerVersion; //컴파일러 버전 정보 BYTE MinorLinkerVersion; DWORD SizeOfCode; //코드 전체 크기 DWORD SizeOfInitializedData; //초기화되는 데이터 크기 DWORD SizeOfUninitializedData; //초기화되지 않는 데이터 크기 DWORD AddressOfEntryPoint; //실행 코드의 시작 위치 DWORD BaseOfCode; //코드의 시작 위치
DWORD ImageBase; //PE 파일이 매핑될 메모리 실제 시작 주소 DWORD SectionAlignment; //메모리상에 올려진 후의 섹션 배치간격 DWORD FileAlignment;
WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; WORD Win32VersionValue;
WORD SizeOfHeaders; WORD 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; |
SizeOfCode
-.text 섹션에 CPU가 실행하는 기계어 코드가 들어있는데 이 코드의 전체 크기이다.
SizeOfInitializedData
-프로그램 내에서 쓰이는 변수들이 저장되어 있는 섹션 영역들 중에서 데이터가 초기화 되어 있는 섹션영 역들의 집합이다.
SizeOfUninitializedData
-SizeOfInitializedData의 반대이다.
AddressOfEntryPoint
-메인 함수 시작 주소가 RVA로 저장되어 있다.
BaseOfCode
-코드영역의 시작주소가 RVA로 저장되어 있다.
BaseOfdata
-데이터영역의 시작주소가 RVA로 저장되어 있다.
ImageBase
-PE파일이 메모리에 매핑될 시작 주소로써, RVA의 기준에 되는 주소이다.
보통 exe 파일은 0x00400000의 값을 갖고 dll 파일은 0x10000000의 값을 갖는다.
SectionAlignment
-메모리상에 올려진 후의 섹션의 배치 간격이다.
※섹션 헤더에는 2가지 주소 정보가 있는데 VirualAddress 멤버는 PE 로더가 참조할 가상 주소 값이고 PointerToRawData 멤버는 메모리에 올려지지 않은 파일상의 주소이다.
FileAlignment
-파일상의 섹션 배치 간격이다.
SizeOfImage
-파일의 전체 크기이다.
SizeOfHeaders
-도스 헤더, 도스 스텁, PE 헤더, 섹션 헤더 모두를 더한 값이다.
SizeOfStackReserve
-프로그램에서 사용될 스택을 얼마만큼 예약할지의 바이트 기준 값이다.
SizeOfStackCommit
-프로그램에서 사용될 스택을 얼마만큼 commit할지의 바이트 기준 값이다.
SizeOfHeapReserve
-프로그램에서 사용될 힙을 얼마만큼 예약할지의 바이트 기준 값이다.
SizeOfHeapCommit
-프로그램에서 사용될 힙을 얼마만큼 commit할지의 바이트 기준 값이다.
DataDirectory
-Export table, Import table, Resource 영역, Exception 영역, 보안 영역, 디버그 영역등을 접근할 수 있는 주소를 가지고 있는 IMAGE_DATA_DIRECTORY 구조체 배열이다.
-이 배열에는 각 해당 영역으로 갈 수 있는 RVA 주소와 그 영역의 크기 정보를 담고 있다.
※IMAGE_DATA_DIRECTORY 구조체 배열 구성
명칭 | 값 |
IMAGE_DIRECTORY_ENTRY_EXPORT | 0 |
IMAGE_DIRECTORY_ENTRY_IMPORT | 1 |
IMAGE_DIRECTORY_ENTRY_RESOURSE | 2 |
IMAGE_DIRECTORY_ENTRY_EXCEPTION | 3 |
IMAGE_DIRECTORY_ENTRY_SECURITY | 4 |
IMAGE_DIRECTORY_ENTRY_BASERELOC | 5 |
IMAGE_DIRECTORY_ENTRY_DEBUG | 6 |
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT | 7 |
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE | 7 |
IMAGE_DIRECTORY_ENTRY_GLOBALPTR | 8 |
IMAGE_DIRECTORY_ENTRY_TLS | 9 |
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG | 10 |
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT | 11 |
IMAGE_DIRECTORY_ENTRY_IAT | 12 |
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT | 13 |
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR | 14 |
typedef struct _IMAGE_DATA_HEADER{ DWORD VirtualAddress; DWORD VirtualSize; }IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; |
-섹션 테이블이라고도 하며 PE 포맷의 옵셔널 헤더 바로 뒤에 구조체 배열 형식으로 위치해 있다.
-섹션의 개수만큼 섹션 헤더 배열이 있고 마지막에 null로 채워진 섹션 헤더 구조체가 위치한다.
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; |
Name
-섹션의 이름을 나타낸다. IMAGE_SIZEOF_SHORT_NAME은 8바이트 크기를 나타내는 상수이다.
-섹션의 이름으로 섹션의 성격을 파악해서는 안 되며, 섹션의 이름이 같다고 하여 항상 같은 속성을 지니 지 않기 때문에 속성을 파악하기 위해서는 Characteristics 멤버를 참조하여야 한다.
※일반적인 섹션 이름별 용도
이름 | 용도 |
.text | 실행되는 코드들 |
.data | 초기화된 전역 변수를 담고 있는 RW가능한 섹션 |
.rdata | 읽기 전용 데이터 섹션, 문자열 표현이나 c++/com 가장 함수 테이블 |
.bss | 초기화되지 않은 전역 변수들을 위한 섹션 |
.idata | 다른 DLL로부터 가져다 쓰는 함수들의 정보. IMAGE_IMPORT_DESCRIPTOR의 배열로 이루어져 있으며 하나당 DLL 한 개의 정보를 담고 있다. |
.edata | 다른 모듈이 이 파일을 사용할 때 사용하도록 해놓은 함수 리스트 |
PhysicalAddress/VirtualSize
-PE로더에 의해 이미지가 메모리에 올려진 후에 해당 섹션이 얼마만큼의 크기를 가지고 있게 되는지의 정보이다.
VirtualAddress
-PE로더에 의해 이미지가 메모리에 올려진 후에 해당 섹션이 어느 주소에 위치하는지의 RVA 주소 값이 다. 이 멤버는 항상 IMAGE_OPTIONAL_HEADER의 멤버인 SectionAlignment의 배수 값을 가진다.
SizeOfRawData
-Raw data 상에서 해당 세션에 대한 실제 사용된 크기 정보를 담고 있다.
PointerToRawData
-Raw data가 파일 상의 어느 주소에 위치해 있는지 나타내는 변수이다.
Characteristics
-섹션에 대한 속성 정보를 플래그로 가지고 있다. 해당 섹션의 속성 값을 알아내기 위해서 AND 연산을 이 용한다.
ex) if(SectionHeader.Characteristics & IMAGE_SCN_MEM_READ)
※Characteristics 상수
명칭 | 값 | 설명 |
IMAGE_SCN_CNT_CODE |
0x00000020 | 코드로 채워진 섹션 |
IMAGE_SCN_CNT_INITIALIZED_DATA |
0x00000040 | 데이터가 초기화된 섹션 |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |
0x00000080 |
데이터가 비초기화된 섹션 |
IMAGE_SCN_MEM_EXECUTE | 0x20000000 | 코드로서 실행될 수 있는 섹션 |
IMAGE_SCN_MEM_READ | 0x40000000 | 읽기 가능 영역 섹션 |
IMAGE_SCN_MEM_WRITE | 0x80000000 | 쓰기 가능 영역 섹션 |
반응형
'악성코드 분석 > 리버싱 팁' 카테고리의 다른 글
mov EDI,EDI (Hot Patching) (0) | 2010.12.21 |
---|---|
어셈블리 코드 해석 (0) | 2010.12.01 |