Share via


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 리스트 정보