PEVIEWER로 살펴보는 notepad.exe
PE(Portable Executable) format이란 Win32, Win9x, W2K, WinNT 등 Windows 계열 플랫폼에서 실행파일을 위해 설계된 파일 포맷입니다. 이는 UNIX의 COFF(Common Object File Format)에서 파생된 것으로 실행 코드외에도 리소스, relocation 데이터, 디버깅 정보, DLL import와 export에 관련된 테이블 정보 등을 포함할 수 있습니다. EXE나 DLL 외에도 드라이버 파일, ActiveX 콘트롤 등 모든 실행 파일은 PE format을 따라야 합니다. 프로세스의 가상 메모리 공간에 이러한 PE format file은 memory mapped file 기술을 이용해서 메모리로 로드되어 바로 실행될 수 있는 형태로 구성되어 있습니다.
Windows 운영체제는 실행파일에 따라서 어떠한 환경의 subsystem에서 실행되어야 하는지 판단하고 해당 플랫폼에서 실행될 수 있도록 환경을 구성해줍니다. 예를 들어 Windows 64bit 환경에서도 WOW64 기술을 이용해서 기존 x86 기반의 32bit 어플리케이션도 실행될 수 있으며, MSDOS 응용프로그램도 VDM(Virtual DOS Machine) 위에서 실행될 수 있습니다. 뿐만 아니라 POSIX 프로그램도 Windows 운영체제에서 실행될 수 있습니다. 이는 프로그램이 실행되는 시점에 Windows가 해당 응용프로그램의 PE format에 기록된 정보를 읽어서 어떠한 환경에서 실행되도록 빌드된 응용 프로그램인지 판단하고 이와 적절한 subsystem과 실행 환경을 만들어주기 때문입니다.
이처럼 실행 파일의 실행에 필요한 정보를 파일 내부에 직접 가지고 있으므로 이동이 가능하고(portable) 또한 실행이 가능(executable)합니다.
PE format의 내부 구조에 대해서는 다음에 기회가 있으면 보다 자세히 다루도록 하고, 오늘은 PE 파일의 내부 구조를 분석해서 보여주는 툴을 통해서 어떠한 정보가 포함되어 있는지 대략 살펴보도록 하겠습니다. PE format을 보여주는 많은 툴 중에서 freeware로 사용할 수 있는 PE Viewer v1.0을 이용해서 Windows 운영체제에 기본으로 탑재된 notepad.exe 실행파일을 살펴보도록 하겠습니다.
PE Viewer v1.0
https://www.softpedia.com/get/Programming/Other-Programming-Files/PE-Viewer.shtml
--------------------------- 이하 PEVIEWER의 Misc 탭의 내용 ---------------------------------
File: C:\WINDOWS\NOTEPAD.EXE Size 10E00 (69120 bytes 67 KB) <-- 실행파일의 크기
PE base is E0
--->Following is IMAGE_FILE_HEADER
Offset : 00000004 Machine : 014C Intel i386 // 파일이 샐행될 CPU 플랫폼
Offset : 00000006 NumberOfSections : 3 // 섹션의 개수
Offset : 00000008 TimeDateStamp : 41107CC3 // 파일이 생성된 시간과 날짜
Offset : 0000000C PointerToSymbolTable : 00000000 // 디버깅시 사용되는 심볼 테이블의 위치
Offset : 00000010 NumberOfSymbols : 00000000 // 디버깅시 사용되는 심볼의 개수
Offset : 00000014 SizeOfOptionalHeader : 00E0 // OptionalHeader의 크기
Offset : 00000016 Characteristics : 010F No relocation. Executable. Line number stripped. Local symbols stripped. 32 bits word machine. // exe인지 dll인지 식별하는데 사용되는 플래그
--->Following is IMAGE_OPTIONAL_HEADER
Offset : 00000018 Magic : 010B
Offset : 0000001A LinkerVersion : 7.10 // Liker 버전
Offset : 0000001C SizeOfCode : 00007800
Offset : 00000020 SizeOfInitializedData : 0000A600
Offset : 00000024 SizeOfUninitializedData : 00000000
Offset : 00000028 AddressOfEntryPoint (RVA) : 0000739D // PE 파일에서 처음 실행될 명령의 RVA 주소
Offset : 0000002C BaseOfCode (RVA) : 00001000
Offset : 00000030 BaseOfData (RVA) : 00009000
Offset : 00000034 ImageBase (RVA) : 01000000 // PE 파일 로딩시 선호되는 시작 주소
Offset : 00000038 SectionAlignment : 00001000 // 각 섹션은 4096의 배수가 되는 곳에서 시작되어야 함
Offset : 0000003C FileAlignment : 00000200
Offset : 00000040 OperatingSystemVersion : 5.1
Offset : 00000044 ImageVersion : 5.1
Offset : 00000048 SubsystemVersion : 4.0
Offset : 0000004C Reserved1 : 00000000
Offset : 00000050 SizeOfImage : 00014000 // 메모리에 로딩될 PE 이미지의 전체 크기
Offset : 00000054 SizeOfHeaders : 00000400 // PE Header의 크기
Offset : 00000058 CheckSum : 00014F7F (Correct checksum is 00014F7F)
Offset : 0000005C Subsystem : 0002 WINDOWS_GUI (Graphics)
Offset : 0000005E DllCharacteristics : 8000
Offset : 00000060 SizeOfStackReserve : 00040000
Offset : 00000064 SizeOfStackCommit : 00011000
Offset : 00000068 SizeOfHeapReserve : 00100000
Offset : 0000006C SizeOfHeapCommit : 00001000
Offset : 00000070 LoaderFlags : 00000000
Offset : 00000074 NumberOfRvaAndSizes : 00000010
~~~~IMAGE_DATA_DIRECTORY~~~~
Offset : 00000078 01 RVA : 00000000 Size : 00000000 Name : Export
Offset : 00000080 02 RVA : 00007604 Size : 000000C8 Name : Import
Offset : 00000088 03 RVA : 0000B000 Size : 00008958 Name : Resource
Offset : 00000090 04 RVA : 00000000 Size : 00000000 Name : Exception
Offset : 00000098 05 RVA : 00000000 Size : 00000000 Name : Security
Offset : 000000A0 06 RVA : 00000000 Size : 00000000 Name : BaseRelocate
Offset : 000000A8 07 RVA : 00001350 Size : 0000001C Name : Debug
Offset : 000000B0 08 RVA : 00000000 Size : 00000000 Name : Architecture
Offset : 000000B8 09 RVA : 00000000 Size : 00000000 Name : GlobalPtr
Offset : 000000C0 10 RVA : 00000000 Size : 00000000 Name : TLS
Offset : 000000C8 11 RVA : 000018A8 Size : 00000040 Name : LoadConfig
Offset : 000000D0 12 RVA : 00000250 Size : 000000D0 Name : Bound
Offset : 000000D8 13 RVA : 00001000 Size : 00000348 Name : ImportAddress
Offset : 000000E0 14 RVA : 00000000 Size : 00000000 Name : DelayLoadImport
Offset : 000000E8 15 RVA : 00000000 Size : 00000000 Name : COM
Offset : 000000F0 16 RVA : 00000000 Size : 00000000 Name : Reserved
--->Following is Section Table
Section 1
Offset : 000000F8 Name : .text // 실행 코드가 위치한 섹션
Offset : 00000100 VirtualSize : 00007748 VirtualAddress : 00001000
Offset : 00000108 SizeOfRawData : 00007800 PointerToRawData : 00000400
Offset : 00000110 PointerToRelocations : 00000000 PointerToLinenumbers : 00000000
Offset : 00000118 NumberOfRelocations : 00000000 NumberOfLinenumbers : 00000000
Offset : 0000011C Characteristics : 60000020
Section 2
Offset : 00000120 Name : .data // 데이터 섹션
Offset : 00000128 VirtualSize : 00001BA8 VirtualAddress : 00009000
Offset : 00000130 SizeOfRawData : 00000800 PointerToRawData : 00007C00
Offset : 00000138 PointerToRelocations : 00000000 PointerToLinenumbers : 00000000
Offset : 00000140 NumberOfRelocations : 00000000 NumberOfLinenumbers : 00000000
Offset : 00000144 Characteristics : C0000040
Section 3
Offset : 00000148 Name : .rsrc // 리소스 섹션
Offset : 00000150 VirtualSize : 00008958 VirtualAddress : 0000B000
Offset : 00000158 SizeOfRawData : 00008A00 PointerToRawData : 00008400
Offset : 00000160 PointerToRelocations : 00000000 PointerToLinenumbers : 00000000
Offset : 00000168 NumberOfRelocations : 00000000 NumberOfLinenumbers : 00000000
Offset : 0000016C Characteristics : 40000040
Physical image size is 00010E00
--->Following is import table // import table (동적으로 로딩해야 하는 DLL 및 API 리스트)
Offset : 00006924 Characteristics : 00007990
Offset : 00006928 TimeDateStamp : FFFFFFFF
Offset : 0000692C ForwarderChain : FFFFFFFF
Offset : 00006930 Name RVA: 00007AAC Name : comdlg32.dll
Offset : 00006934 FirstThunk : 000012C4
Ordinal : 000F Name : PageSetupDlgW
Ordinal : 0006 Name : FindTextW
Ordinal : 0012 Name : PrintDlgExW
Ordinal : 0003 Name : ChooseFontW
Ordinal : 0008 Name : GetFileTitleW
Ordinal : 000A Name : GetOpenFileNameW
Ordinal : 0015 Name : ReplaceTextW
Ordinal : 0004 Name : CommDlgExtendedError
Ordinal : 000C Name : GetSaveFileNameW
Offset : 00006938 Characteristics : 00007840
Offset : 0000693C TimeDateStamp : FFFFFFFF
Offset : 00006940 ForwarderChain : FFFFFFFF
Offset : 00006944 Name RVA: 00007AFA Name : SHELL32.dll
Offset : 00006948 FirstThunk : 00001174
Ordinal : 001F Name : DragFinish
Ordinal : 0023 Name : DragQueryFileW
Ordinal : 001E Name : DragAcceptFiles
Ordinal : 0103 Name : ShellAboutW
Offset : 0000694C Characteristics : 00007980
Offset : 00006950 TimeDateStamp : FFFFFFFF
Offset : 00006954 ForwarderChain : FFFFFFFF
Offset : 00006958 Name RVA: 00007B3A Name : WINSPOOL.DRV
Offset : 0000695C FirstThunk : 000012B4
Ordinal : 0078 Name : GetPrinterDriverW
Ordinal : 001B Name : ClosePrinter
Ordinal : 007E Name : OpenPrinterW
Offset : 00006960 Characteristics : 000076EC
Offset : 00006964 TimeDateStamp : FFFFFFFF
Offset : 00006968 ForwarderChain : FFFFFFFF
Offset : 0000696C Name RVA: 00007B5E Name : COMCTL32.dll
Offset : 00006970 FirstThunk : 00001020
Ordinal : 0008 Name : CreateStatusWindowW
Offset : 00006974 Characteristics : 000079B8
Offset : 00006978 TimeDateStamp : FFFFFFFF
Offset : 0000697C ForwarderChain : FFFFFFFF
Offset : 00006980 Name RVA: 00007C76 Name : msvcrt.dll
Offset : 00006984 FirstThunk : 000012EC
Ordinal : 004E Name : _XcptFilter
Ordinal : 00F6 Name : _exit
Ordinal : 00C5 Name : _c_exit
Ordinal : 0317 Name : time
Ordinal : 02D4 Name : localtime
Ordinal : 00C8 Name : _cexit
Ordinal : 02C6 Name : iswctype
Ordinal : 00ED Name : _except_handler3
Ordinal : 0274 Name : _wtol
Ordinal : 032F Name : wcsncmp
Ordinal : 01E4 Name : _snwprintf
Ordinal : 0290 Name : exit
Ordinal : 00A8 Name : _acmdln
Ordinal : 006D Name : __getmainargs
Ordinal : 013B Name : _initterm
Ordinal : 009A Name : __setusermatherr
Ordinal : 00B6 Name : _adjust_fdiv
Ordinal : 0080 Name : __p__commode
Ordinal : 0085 Name : __p__fmode
Ordinal : 0098 Name : __set_app_type
Ordinal : 00D6 Name : _controlfp
Ordinal : 0330 Name : wcsncpy
Offset : 00006988 Characteristics : 000076CC
Offset : 0000698C TimeDateStamp : FFFFFFFF
Offset : 00006990 ForwarderChain : FFFFFFFF
Offset : 00006994 Name RVA: 00007D08 Name : ADVAPI32.dll
Offset : 00006998 FirstThunk : 00001000
Ordinal : 01EE Name : RegQueryValueExW
Ordinal : 01CA Name : RegCloseKey
Ordinal : 01D0 Name : RegCreateKeyW
Ordinal : 0139 Name : IsTextUnicode
Ordinal : 01ED Name : RegQueryValueExA
Ordinal : 01E3 Name : RegOpenKeyExA
Ordinal : 01FB Name : RegSetValueExW
Offset : 0000699C Characteristics : 00007758
Offset : 000069A0 TimeDateStamp : FFFFFFFF
Offset : 000069A4 ForwarderChain : FFFFFFFF
Offset : 000069A8 Name RVA: 000080EC Name : KERNEL32.dll
Offset : 000069AC FirstThunk : 0000108C
Ordinal : 013E Name : GetCurrentThreadId
Ordinal : 01D1 Name : GetTickCount
Ordinal : 0291 Name : QueryPerformanceCounter
Ordinal : 016A Name : GetLocalTime
Ordinal : 01D5 Name : GetUserDefaultLCID
Ordinal : 0140 Name : GetDateFormatW
Ordinal : 01D3 Name : GetTimeFormatW
Ordinal : 01F5 Name : GlobalLock
Ordinal : 01FC Name : GlobalUnlock
Ordinal : 015A Name : GetFileInformationByHandle
Ordinal : 0051 Name : CreateFileMappingW
Ordinal : 01BD Name : GetSystemTimeAsFileTime
Ordinal : 0346 Name : TerminateProcess
Ordinal : 013B Name : GetCurrentProcess
Ordinal : 0332 Name : SetUnhandledExceptionFilter
Ordinal : 0241 Name : LoadLibraryA
Ordinal : 0175 Name : GetModuleHandleA
Ordinal : 01AC Name : GetStartupInfoA
Ordinal : 01F1 Name : GlobalFree
Ordinal : 016C Name : GetLocaleInfoW
Ordinal : 024B Name : LocalFree
Ordinal : 0247 Name : LocalAlloc
Ordinal : 03B4 Name : lstrlenW
Ordinal : 0251 Name : LocalUnlock
Ordinal : 0038 Name : CompareStringW
Ordinal : 024D Name : LocalLock
Ordinal : 00EA Name : FoldStringW
Ordinal : 0031 Name : CloseHandle
Ordinal : 03AE Name : lstrcpyW
Ordinal : 02A3 Name : ReadFile
Ordinal : 0052 Name : CreateFileW
Ordinal : 03AB Name : lstrcmpiW
Ordinal : 013C Name : GetCurrentProcessId
Ordinal : 0197 Name : GetProcAddress
Ordinal : 010A Name : GetCommandLineW
Ordinal : 03A5 Name : lstrcatW
Ordinal : 00CC Name : FindClose
Ordinal : 00D3 Name : FindFirstFileW
Ordinal : 0159 Name : GetFileAttributesW
Ordinal : 03A8 Name : lstrcmpW
Ordinal : 0263 Name : MulDiv
Ordinal : 03B1 Name : lstrcpynW
Ordinal : 0250 Name : LocalSize
Ordinal : 0168 Name : GetLastError
Ordinal : 038B Name : WriteFile
Ordinal : 0313 Name : SetLastError
Ordinal : 037E Name : WideCharToMultiByte
Ordinal : 024E Name : LocalReAlloc
Ordinal : 00EC Name : FormatMessageW
Ordinal : 01D7 Name : GetUserDefaultUILanguage
Ordinal : 02FD Name : SetEndOfFile
Ordinal : 0082 Name : DeleteFileW
Ordinal : 00F6 Name : GetACP
Ordinal : 035A Name : UnmapViewOfFile
Ordinal : 0264 Name : MultiByteToWideChar
Ordinal : 0257 Name : MapViewOfFile
Ordinal : 0357 Name : UnhandledExceptionFilter
Offset : 000069B0 Characteristics : 000076F4
Offset : 000069B4 TimeDateStamp : FFFFFFFF
Offset : 000069B8 ForwarderChain : FFFFFFFF
Offset : 000069BC Name RVA: 0000825E Name : GDI32.dll
Offset : 000069C0 FirstThunk : 00001028
Ordinal : 0098 Name : EndPage
Ordinal : 0000 Name : AbortDoc
Ordinal : 0096 Name : EndDoc
Ordinal : 008C Name : DeleteDC
Ordinal : 0248 Name : StartPage
Ordinal : 01B5 Name : GetTextExtentPoint32W
Ordinal : 002F Name : CreateDCW
Ordinal : 0210 Name : SetAbortProc
Ordinal : 01BB Name : GetTextFaceW
Ordinal : 024F Name : TextOutW
Ordinal : 0246 Name : StartDocW
Ordinal : 00CE Name : EnumFontsW
Ordinal : 01A5 Name : GetStockObject
Ordinal : 0197 Name : GetObjectW
Ordinal : 016B Name : GetDeviceCaps
Ordinal : 003D Name : CreateFontIndirectW
Ordinal : 008F Name : DeleteObject
Ordinal : 01BD Name : GetTextMetricsW
Ordinal : 0216 Name : SetBkMode
Ordinal : 01CB Name : LPtoDP
Ordinal : 0242 Name : SetWindowExtEx
Ordinal : 023E Name : SetViewportExtEx
Ordinal : 022B Name : SetMapMode
Ordinal : 020E Name : SelectObject
Offset : 000069C4 Characteristics : 00007854
Offset : 000069C8 TimeDateStamp : FFFFFFFF
Offset : 000069CC ForwarderChain : FFFFFFFF
Offset : 000069D0 Name RVA: 0000873C Name : USER32.dll
Offset : 000069D4 FirstThunk : 00001188
Ordinal : 00FF Name : GetClientRect
Ordinal : 024D Name : SetCursor
Ordinal : 022A Name : ReleaseDC
Ordinal : 010C Name : GetDC
Ordinal : 009F Name : DialogBoxParamW
Ordinal : 0243 Name : SetActiveWindow
Ordinal : 0122 Name : GetKeyboardLayout
Ordinal : 008F Name : DefWindowProcW
Ordinal : 0099 Name : DestroyWindow
Ordinal : 01DB Name : MessageBeep
Ordinal : 0292 Name : ShowWindow
Ordinal : 0117 Name : GetForegroundWindow
Ordinal : 01A6 Name : IsIconic
Ordinal : 0173 Name : GetWindowPlacement
Ordinal : 0037 Name : CharUpperW
Ordinal : 01C9 Name : LoadStringW
Ordinal : 01B4 Name : LoadAcceleratorsW
Ordinal : 015C Name : GetSystemMenu
Ordinal : 0218 Name : RegisterClassExW
Ordinal : 01BE Name : LoadImageW
Ordinal : 01BA Name : LoadCursorW
Ordinal : 0282 Name : SetWindowPlacement
Ordinal : 0061 Name : CreateWindowExW
Ordinal : 010E Name : GetDesktopWindow
Ordinal : 0116 Name : GetFocus
Ordinal : 01BC Name : LoadIconW
Ordinal : 0287 Name : SetWindowTextW
Ordinal : 0201 Name : PostQuitMessage
Ordinal : 0228 Name : RegisterWindowMessageW
Ordinal : 02BB Name : UpdateWindow
Ordinal : 026F Name : SetScrollPos
Ordinal : 0029 Name : CharLowerW
Ordinal : 01FE Name : PeekMessageW
Ordinal : 00C4 Name : EnableWindow
Ordinal : 00BE Name : DrawTextExW
Ordinal : 0056 Name : CreateDialogParamW
Ordinal : 017A Name : GetWindowTextW
Ordinal : 015D Name : GetSystemMetrics
Ordinal : 01E9 Name : MoveWindow
Ordinal : 0193 Name : InvalidateRect
Ordinal : 02D3 Name : WinHelpW
Ordinal : 0110 Name : GetDlgCtrlID
Ordinal : 003C Name : ChildWindowFromPoint
Ordinal : 0231 Name : ScreenToClient
Ordinal : 010B Name : GetCursorPos
Ordinal : 0237 Name : SendDlgItemMessageW
Ordinal : 0240 Name : SendMessageW
Ordinal : 002C Name : CharNextW
Ordinal : 0039 Name : CheckMenuItem
Ordinal : 0042 Name : CloseClipboard
Ordinal : 019F Name : IsClipboardFormatAvailable
Ordinal : 01F3 Name : OpenClipboard
Ordinal : 0137 Name : GetMenuState
Ordinal : 00C2 Name : EnableMenuItem
Ordinal : 0159 Name : GetSubMenu
Ordinal : 012C Name : GetMenu
Ordinal : 01E3 Name : MessageBoxW
Ordinal : 0281 Name : SetWindowLongW
Ordinal : 016F Name : GetWindowLongW
Ordinal : 0111 Name : GetDlgItem
Ordinal : 0256 Name : SetFocus
Ordinal : 0254 Name : SetDlgItemTextW
Ordinal : 02D9 Name : wsprintfW
Ordinal : 0114 Name : GetDlgItemTextW
Ordinal : 00C6 Name : EndDialog
Ordinal : 0145 Name : GetParent
Ordinal : 02AC Name : UnhookWinEvent
Ordinal : 00A2 Name : DispatchMessageW
Ordinal : 02AA Name : TranslateMessage
Ordinal : 02A8 Name : TranslateAcceleratorW
Ordinal : 01A2 Name : IsDialogMessageW
Ordinal : 0200 Name : PostMessageW
Ordinal : 013E Name : GetMessageW
Ordinal : 027E Name : SetWinEventHook
There is no Export table // Export table. 외부로 export 하는 API 리스트 정보