一)win32下PE文件格式的文件有:*.exe;*.dll;*.scr;*.fon;*.drv;*.sys 二)pe文件基本结构
附加数据 |
其它节区 |
.reloc节区 |
.rsrc节区 |
.data节区 |
.text节区 |
节表 |
数据目录 |
选项头 |
文件头 |
PE标志 |
DOS stub |
DOS头 |
格式说明: 1)dos头: 0000 0000:4D 5A 0000 0010: 0000 0020: 0000 0030: 3C xx xx xx IMAGE_DOS_HEADER struc +00h e_magic: word ;dos标志MZ,常量表示IMAGE_DOS_SIGNATURE ... +3ch e_lfanew: dword;指向pe文件头 IMAGE_DOS_HEADER ends 2)dos stub 在dos执行的程序代码。方法是 3)pe文件头 定位:文件开始地址+IMAGE_DOS_HEADER.e_lfanew 数据结构: IMAGE_NT_HEADER struc +00h Signature: dword ;pe标志50 45 00 00,IMAGE_NT_SIGNATURE +04h FileHead: IMAGE_FILE_HEADER +18h OptionalHead: IMAGE_OPTIONAL_HEADER32 IMAGE_NT_HEADER ends 4)pe标志 0000 0D00: 50 45 00 00 +00h Signature: dword ;PE标志,常量表示IMAGE_NT_SIGNATURE 5)文件头 0000 0D00: 50 45 00 00 04 xx 06 xx 08 xx xx xx 0000 0D10: 14 xx 16 xx 数据结构: IMAGE_FILE_HEADER struc +04h Machine: word ;运行平台 +06h NumberOfSections: word ;节区数量 +08h TimeDateStamp: dword ;从1969年12月31日下午4点以来的秒数 ... +14h SizeOfOptionalHeader: word ;选项头大小 +16h Characteristics: word ;文件属性,exe为 dll为多少等 IMAGE_FILE_HEADER ends 6)选项头 0000 0D00: 50 45 00 00 04 xx 06 xx 08 xx xx xx 0000 0D10: 14 xx 16 xx 0000 0D20: 28 xx xx xx 0000 0D30: 34 xx xx xx 38 xx xx xx 3C xx xx xx 0000 0D40: 0000 0D50: 50 xx xx xx 54 xx xx xx 5C xx xx xx 0000 0D60: 0000 0D70: 78 xx xx xx xx xx xx xx 数据结构: IMAGE_OPTIONAL_HEADER32 struc +28h AddressOfEntryPoint: dword ;入口地址 +34h ImageBase: dword ;建议装载地址 +38h SectionAlignMent: dword ;内存对齐大小 +3ch FileAlignMent: dword ;文件对齐大小 +50h SizeOfImage dword ;文件装入到内存后的总尺寸,即内存对齐后的总大小 +54h SizeOfHeaders dword ;所有头 + 区块表的尺寸大小 +5ch SubSystem: wrod ;子系统 +78h DataDirectory: IMAGE_DATA_DIRECTORY ;数据目录 IMAGE_OPTIONAL_HEADER32 ends 界面子系统的取值和含义
取 值
|
Windows.inc中的预定义值
|
含 义
|
0
|
IMAGE_SUBSYSTEM_UNKNOWN
|
未知的子系统
|
1
|
IMAGE_SUBSYSTEM_NATIVE
|
不需要子系统(如驱动程序)
|
2
|
IMAGE_SUBSYSTEM_WINDOWS_GUI
|
Windows图形界面
|
3
|
IMAGE_SUBSYSTEM_WINDOWS_CUI
|
Windows控制台界面
|
5
|
IMAGE_SUBSYSTEM_OS2_CUI
|
OS2控制台界面
|
7
|
IMAGE_SUBSYSTEM_POSIX_CUI
|
POSIX控制台界面
|
8
|
IMAGE_SUBSYSTEM_NATIVE_WINDOWS
|
不需要子系统
|
9
|
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
|
Windows CE图形界面
|
7)数据目录 IMAGE_DATA_DIRECTORY struc VirtualAddress: dword ;RVA起始地址 VirtualSize: dword ;数据块大小 IMAGE_DATA_DIRECTORY ends 数据目录列表的含义
索 引
|
索引值在Windows.inc中的预定义值
|
对应的数据块
|
0
|
IMAGE_DIRECTORY_ENTRY_EXPORT
|
导出表
|
1
|
IMAGE_DIRECTORY_ENTRY_IMPORT
|
导入表
|
2
|
IMAGE_DIRECTORY_ENTRY_RESOURCE
|
资源
|
3
|
IMAGE_DIRECTORY_ENTRY_EXCEPTION
|
异常(具体资料不详)
|
4
|
IMAGE_DIRECTORY_ENTRY_SECURITY
|
安全(具体资料不详)
|
5
|
IMAGE_DIRECTORY_ENTRY_BASERELOC
|
重定位表
|
6
|
IMAGE_DIRECTORY_ENTRY_DEBUG
|
调试信息
|
7
|
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
|
版权信息
|
8
|
IMAGE_DIRECTORY_ENTRY_GLOBALPTR
|
具体资料不详
|
9
|
IMAGE_DIRECTORY_ENTRY_TLS
|
Thread Local Storage
|
10
|
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
|
具体资料不详
|
11
|
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
|
具体资料不详
|
12
|
IMAGE_DIRECTORY_ENTRY_IAT
|
导入函数地址表
|
13
|
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
|
具体资料不详
|
14
|
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
|
具体资料不详
|
15
|
未使用
|
|
8)节表 多个IMAGE_SECTION_HEADER组成节表。节表位置:紧接在PE头后面。 IMAGE_SECTION_HEADER struc +00h Name1: db ;节名,占8字节,以ASSII码表示,不一定以0结束 +08h VirtualSize: dd ;没有做内存对齐处理的大小 +0ch VirtualAddress: dd ;RVA +10h SizeOfRawData: dd ;文件对齐后的大小 +14h PointerToRawData: dd ;文件偏移 +18h PointerToRelocations: dd +1ch PointerToLinenumbers: dd +20h NumberOfRelocations: dw +22h NumberOfLinenumbers: dw +24h Characteristics: dd ;节属性,加载时用该属性去设置内存页属性 IMAGE_SECTION_HEADER ends 注意:上面的偏移是针对本结构的偏移量。 加载程序根据此机构加载相应的节块。
字段值 |
用 途 |
00000020h |
包含代码,常与10000000h一起设置 |
00000040h |
包含已初始化数据 |
00000080h |
包含未初始化数据 |
02000000h |
可以被丢弃 |
10000000h |
共享块 |
20000000h |
可执行 |
40000000h |
可读 |
80000000h |
可写 |
附代码:显示pe文件头信息和节表信息 文件分为3部分: peinfo.rc:对话框资源文件 peinfo.asm:界面显示处理 processpefile.asm:提取pe文件头信息和节表信息 资源文件peinfo.rc #include <resource.h> #define ICO_MAIN 1000 #define DLG_MAIN 2000 #define IDC_INFO 2001 #define IDM_MAIN 3000 #define IDM_OPEN 3001 #define IDM_EXIT 3002 ICO_MAIN ICON "peinfo.ico" DLG_MAIN dialog 100, 100, 450, 340 style DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU caption "pe文件基本信息" menu IDM_MAIN font 9, "宋体" { CONTROL "", IDC_INFO, "RichEdit20A", 196 | ES_WANTRETURN | WS_CHILD | ES_READONLY | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 0, 0, 449, 340 } IDM_MAIN menu discardable begin popup "文件(&F)" begin menuitem "打开文件(&O)...", IDM_OPEN menuitem separator menuitem "退出(&X)", IDM_EXIT end end 界面显示peinfo.asm ;======================= ;查看pe文件基本信息 ;by 紫陌 ;======================= .386 .model flat, stdcall option casemap:none ;======================= ;include头文件 ;======================= include windows.inc include user32.inc include kernel32.inc include comdlg32.inc includelib user32.lib includelib kernel32.lib includelib comdlg32.lib ;======================= ;equ等值定义 ;======================= ICO_MAIN equ 1000 DLG_MAIN equ 2000 IDC_INFO equ 2001 IDM_MAIN equ 3000 IDM_OPEN equ 3001 IDM_EXIT equ 3002 ;======================= ;数据段 ;======================= .data? hInstance dd ? hRichEdit dd ? hMainWnd dd ? szFileName db MAX_PATH dup (?) lpImageBase dd ? szShowMsg db 1024 dup(?) .const szDllEdit db 'RichEd20.dll', 0 szFont db '宋体', 0 szExtPe db 'PE文件', 0, '*.exe;*.dll;*.scr;*.fon;*.drv;*.sys', 0 db '所有文件', 0, '*.*', 0, 0 szErrOpen db '打开文件失败', 0 szErrCreateMap db '创建文件映射失败', 0 szErrMap db '映射文件失败', 0 szErrFormat db '无效的pe文件', 0 szErrExp db '异常发生地址:%08X,异常代码:%08X,标志:%08X', 0 ;======================= ;代码段 ;======================= .code include processpefile.asm ;异常处理SEH ;--------------- _handler proc C _lpExceptionRecord, _lpSeh, _lpContext, _lpDispatcher local @szBuf[256]:BYTE pushad mov esi, _lpExceptionRecord mov edi, _lpContext assume esi:ptr EXCEPTION_RECORD, edi:ptr CONTEXT invoke wsprintf, addr @szBuf, addr szErrExp, [edi].regEip, [esi].ExceptionCode, [esi].ExceptionFlags invoke MessageBox, NULL, addr @szBuf, NULL, MB_ICONSTOP ;************************** ;恢复寄存器 ;************************** mov eax, _lpSeh push DWORD ptr [eax + 0ch] pop [edi].regEbp push DWORD ptr [eax + 8] pop [edi].regEip push eax pop [edi].regEsp assume esi:nothing, edi:nothing popad mov eax, ExceptionContinueExecution ret _handler endp ;--------------- ;初始化程序 ;--------------- _Init proc local @stCF:CHARFORMAT pushad ;***************** ;图标 ;***************** invoke LoadIcon, hInstance, ICO_MAIN invoke SendMessage, hMainWnd, WM_SETICON, ICON_BIG, eax ;***************** ;richedit控件句柄 ;***************** invoke GetDlgItem, hMainWnd, IDC_INFO mov hRichEdit, eax ;***************** ;初始化richedit ;***************** invoke SendMessage, hMainWnd, EM_SETTEXTMODE, TM_PLAINTEXT, 0 mov @stCF.cbSize, sizeof CHARFORMAT mov @stCF.dwMask, CFM_FACE or CFM_SIZE or CFM_BOLD mov @stCF.yHeight, 9 * 20 invoke lstrcpy, addr @stCF.szFaceName, addr szFont invoke SendMessage, hMainWnd, EM_SETCHARFORMAT, 0, addr @stCF invoke SendMessage, hMainWnd, EM_EXLIMITTEXT, 0, -1 popad ret _Init endp ;--------------- ;打开对话框子程序 ;--------------- _OpenFile proc local @stOF:OPENFILENAME local @hFile local @hMap pushad ;***************** ;文件打开对话框 ;***************** invoke RtlZeroMemory, addr @stOF, sizeof OPENFILENAME mov @stOF.lStructSize, sizeof OPENFILENAME push hMainWnd pop @stOF.hwndOwner mov @stOF.lpstrFilter, offset szExtPe mov @stOF.lpstrFile, offset szFileName mov @stOF.nMaxFile, MAX_PATH mov @stOF.Flags, OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST invoke GetOpenFileName, addr @stOF .if !eax jmp _overpos .endif ;******************* ;打开文件并建立map ;******************* invoke CreateFile, addr szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 .if eax == INVALID_HANDLE_VALUE invoke MessageBox, NULL, szErrOpen, NULL, MB_ICONSTOP jmp _overpos .endif mov @hFile, eax invoke CreateFileMapping, @hFile, NULL, PAGE_READONLY, 0, 0, NULL .if !eax invoke MessageBox, NULL, addr szErrCreateMap, NULL, MB_ICONSTOP invoke CloseHandle, @hFile jmp _overpos .endif mov @hMap, eax invoke MapViewOfFile, @hMap, FILE_MAP_READ, 0, 0, 0 .if !eax invoke MessageBox, NULL, addr szErrMap, NULL, MB_ICONSTOP invoke CloseHandle, @hFile jmp _overpos .endif mov lpImageBase, eax ;******************** ;seh结构异常处理 ;******************** push ebp push offset _errexit push offset _handler assume fs:nothing push fs:[0] mov fs:[0], esp ;******************** ;检查PE文件是否有效 ;******************** mov esi, lpImageBase assume esi:ptr IMAGE_DOS_HEADER .if [esi].e_magic != IMAGE_DOS_SIGNATURE jmp _errformat .endif add esi, [esi].e_lfanew assume esi:ptr IMAGE_NT_HEADERS .if [esi].Signature != IMAGE_NT_SIGNATURE jmp _errformat .endif invoke _ProcessPeFile, lpImageBase jmp _errexit _errformat: invoke MessageBox, NULL, addr szErrFormat, NULL, MB_ICONSTOP _errexit: pop fs:[0] add esp, 0ch ;********************* ;关闭映射,句柄 ;********************* invoke CloseHandle, @hFile invoke CloseHandle, @hMap invoke UnmapViewOfFile, lpImageBase _overpos: popad ret _OpenFile endp ;--------------- ;对话框结束子程序 ;--------------- _EndDlgProc proc _lphWnd pushad invoke EndDialog, _lphWnd, 0 popad ret _EndDlgProc endp ;-------------- ;主窗口程序 ;-------------- _MainDlgProc proc uses ebx esi edi hWnd, uMsg, wParam, lParam local @hMainIco mov eax, uMsg .if eax == WM_CLOSE invoke _EndDlgProc, hWnd .elseif eax == WM_INITDIALOG push hWnd pop hMainWnd call _Init .elseif eax == WM_COMMAND mov eax, wParam .if ax == IDM_EXIT invoke _EndDlgProc, hWnd .elseif ax == IDM_OPEN call _OpenFile .endif .else mov eax, FALSE ret .endif mov eax, TRUE ret _MainDlgProc endp ;--------------------- ;主程序 ;--------------------- _Main proc invoke LoadLibrary, addr szDllEdit mov hRichEdit, eax invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam, hInstance, DLG_MAIN, NULL, _MainDlgProc, 0 invoke FreeLibrary, hRichEdit ret _Main endp start: call _Main invoke ExitProcess, 0 end start 提取pe文件信息processpefile.asm ;========================= ;pe处理文件 ;========================= ;======================= ;数据段 ;======================= .const szNTHead db '文件名:%s', 0dh, 0ah db '------------------------------------------', 0dh, 0ah db '运行平台:%04X', 0dh, 0ah db '节区数量:%04X', 0dh, 0ah db '创建时间:%08X', 0dh, 0ah db '选项头大小:%04X', 0dh, 0ah db '文件属性:%04X', 0dh, 0ah db '入口地址:%08X', 0dh, 0ah db '建议装载地址:%08X', 0dh, 0ah db '内存对齐粒度:%08X', 0dh, 0ah db '文件对齐粒度:%08X', 0dh, 0ah db '子系统:%08X', 0dh, 0ah, 0 szSectionCap db '名称 VirtualSize VirtualAddress SizeOfRawData PointOfRawData 属性', 0dh, 0ah, 0 szSectionData db '%s %08X %08X %08X %08X %08X', 0dh, 0ah, 0
;======================= ;代码段 ;======================= .code _ProcessPeFile proc _lpImageBase local @szBuf[512]:BYTE local @Machine:DWORD local @NumberOfSections:DWORD local @SizeOfOptionalHeader:DWORD local @Characteristics:DWORD local @Subsystem:DWORD local @SectionName[9]:BYTE pushad ;*************** ;edi指向pe头,提取并显示文件头信息 ;*************** mov edi, _lpImageBase assume edi:ptr IMAGE_DOS_HEADER add edi, [edi].e_lfanew assume edi:ptr IMAGE_NT_HEADERS movzx eax, [edi].FileHeader.Machine mov @Machine, eax movzx eax, [edi].FileHeader.NumberOfSections mov @NumberOfSections, eax movzx eax, [edi].FileHeader.SizeOfOptionalHeader mov @SizeOfOptionalHeader, eax movzx eax, [edi].FileHeader.Characteristics mov @Characteristics, eax movzx eax, [edi].OptionalHeader.Subsystem mov @Subsystem, eax invoke wsprintf, addr @szBuf, addr szNTHead, \ addr szFileName, \ @Machine, \ @NumberOfSections, \ [edi].FileHeader.TimeDateStamp, \ @SizeOfOptionalHeader, \ @Characteristics, \ [edi].OptionalHeader.AddressOfEntryPoint, \ [edi].OptionalHeader.ImageBase, \ [edi].OptionalHeader.SectionAlignment, \ [edi].OptionalHeader.FileAlignment, \ @Subsystem invoke RtlZeroMemory, addr szShowMsg, sizeof szShowMsg invoke lstrcat, addr szShowMsg, addr @szBuf invoke SetWindowText, hRichEdit, addr szShowMsg ;******************** ;节表信息 ;******************** invoke lstrcat, addr szShowMsg, addr szSectionCap invoke SetWindowText, hRichEdit, addr szShowMsg add edi, 4 add edi, sizeof IMAGE_FILE_HEADER add edi, @SizeOfOptionalHeader assume edi:ptr IMAGE_SECTION_HEADER mov ecx, @NumberOfSections .repeat push ecx push edi invoke RtlZeroMemory, addr @SectionName, 9 invoke lstrcpyn, addr @SectionName, edi, 8 invoke wsprintf, addr @szBuf, addr szSectionData, \ addr @SectionName, \ [edi].Misc.VirtualSize, \ [edi].VirtualAddress, \ [edi].SizeOfRawData, \ [edi].PointerToRawData, \ [edi].Characteristics invoke lstrcat, addr szShowMsg, addr @szBuf invoke SetWindowText, hRichEdit, addr szShowMsg pop edi pop ecx add edi, sizeof IMAGE_SECTION_HEADER .untilcxz assume edi:nothing popad ret _ProcessPeFile endp
|