编程语言:MASAM32 汇编
编程环境:MASM32
所需知识:汇编语言,PE文件结构(http://bbs.pediy.com/showthread.php?s=&threadid=22892这里有)
首先是写有界面的程序,需要定义资源文件
不定义资源文件,若在编程过程中生成控件,则是相当麻烦的
程序最终界面如下
所以定义如下资源,贴出代码
#include <resource.h>
#define ICO_MAIN 2000
#define DLG_MAIN 2000
#define IDC_INFO 2001
#define IDM_MAIN 4000
#define IDM_OPEN 4001
#define IDM_EXIT 4002
ICO_MAIN ICON "Main.ico"
DLG_MAIN DIALOG 100,100,250,140
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,249,140
}
IDM_MAIN menu discardable
{
popup "文件(&F)"
BEGIN
menuitem "打开文件(&O)...", IDM_OPEN
menuitem separator
menuitem "退出(&X)", IDM_EXIT
END
}
将这些代码放进peinfo.rc文件中,用rc.exe进行编译生成peinfo.res文件
下来写主程序文件,也贴出代码,必要的地方有注释
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include comdlg32.inc
includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib
ICO_MAIN equ 2000
DLG_MAIN equ 2000
IDC_INFO equ 2001
IDM_MAIN equ 4000
IDM_OPEN equ 4001
IDM_EXIT equ 4002
.data?
hInstance dd ?
hRichEdit dd ?
hWinMain dd ?
hWinEdit dd ?
szFileName db MAX_PATH dup (?)
.const
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szFont db '宋体',0
szExtPe db 'PE Files',0,'*.exe;*dll;*.scr;*fon;*.drv',0
db 'All Files(*.*)',0,'*.*',0,0
szErr db '文件格式错误!',0
szErrFormat db '这个文件不是PE格式的文件!',0
szMsg db '文件名:%s',0dh,0ah
db '--------------------------------------------',0dh,0ah
db '运行平台: 0x%04X',0dh,0ah
db '节区数量: %d',0dh,0ah
db '文件标记: 0x%04X',0dh,0ah
db '建议装入地址: 0x%08X',0dh,0ah,0
szMsgSection db '---------------------------------------------',0dh,0ah
db '节区名称 节区大小 虚拟地址 Raw_尺寸 Raw_偏移 节区属性',0dh,0ah
db '----------------------------------------------',0dh,0ah
szFmtSection db '%s %08X %08X %08X %08X %08X',0dh,0ah,0,0
;///////////////////////////////////////////////////////////////////////////
.code
_AppendInfo proc _lpsz
local @stCR:CHARRANGE
pushad
invoke GetWindowTextLength,hWinEdit
mov @stCR.cpMin,eax
mov @stCR.cpMax,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
popad
ret
_AppendInfo endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_ProcessPeFile proc _lpFile,_lpPeHead,_dwSize
local @szBuffer[1024]:byte,@szSectionName[16]:byte
pushad
mov edi,_lpPeHead
assume edi:ptr IMAGE_NT_HEADERS
movzx ecx,[edi].FileHeader.Machine
movzx edx,[edi].FileHeader.NumberOfSections
movzx ebx,[edi].FileHeader.Characteristics
invoke wsprintf,addr @szBuffer,addr szMsg,\
addr szFileName,ecx,edx,ebx,[edi].OptionalHeader.ImageBase
invoke SetWindowText,hWinEdit,addr @szBuffer
;----------------------------------------------
;循环显示每个节区的信息
;----------------------------------------------
invoke _AppendInfo,addr szMsgSection
movzx ecx,[edi].FileHeader.NumberOfSections
add edi,sizeof IMAGE_NT_HEADERS
assume edi:ptr IMAGE_SECTION_HEADER
.repeat
push ecx
;-----------------------------------------------------------------
;获取节的名称,由于节名名称不一定是以0结尾的,所以要进行处理
;-----------------------------------------------------------------
invoke RtlZeroMemory,addr @szSectionName,sizeof @szSectionName
push esi
push edi
mov ecx,8
mov esi,edi
lea edi,@szSectionName
cld
@@:
lodsb
.if !al
mov al,' '
.endif
stosb
loop @B
pop edi
pop esi
;---------------------------------------------------------------------
invoke wsprintf,addr @szBuffer,addr szFmtSection,\
addr @szSectionName,[edi].Misc.VirtualSize,\
[edi].VirtualAddress,[edi].SizeOfRawData,\
[edi].PointerToRawData,[edi].Characteristics
invoke _AppendInfo,addr @szBuffer
add edi,sizeof IMAGE_SECTION_HEADER
pop ecx
.untilcxz
assume edi:nothing
popad
ret
_ProcessPeFile endp
;/////////////////////////////////////////////////////////////////////////////////
_Init proc
local @stCf:CHARFORMAT
invoke GetDlgItem,hWinMain,IDC_INFO
mov hWinEdit,eax
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_Init endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_Handler proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push [eax + 0ch]
pop [edi].regEbp
push [eax + 8]
pop [edi].regEip
push eax
pop [edi].regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_Handler endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_OpenFile proc
local @stOF:OPENFILENAME
local @hFile,@dwFileSize,@hMapFile,@lpMemory
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
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 @F
.endif
;----------------------------------------------------------
;打开文件并建立Mapping
;----------------------------------------------------------
invoke CreateFile,addr szFileName,GENERIC_READ,\
FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,\
OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile,eax
invoke GetFileSize,eax,NULL
mov @dwFileSize,eax
.if eax
invoke CreateFileMapping,@hFile,\
NULL,PAGE_READONLY,0,0,NULL
.if eax
mov @hMapFile,eax
invoke MapViewOfFile,eax,\
FILE_MAP_READ,0,0,0
.if eax
mov @lpMemory,eax
;-------------------------------------
;创建用于错误处理的SEH结构
;-------------------------------------
assume fs:nothing
push ebp
push offset _ErrFormat
push offset _Handler
push fs:[0]
mov fs:[0],esp
;-------------------------
;检测PE文件是否有效
;-------------------------
mov esi,@lpMemory
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,@lpMemory,esi,@dwFileSize
jmp _ErrorExit
_ErrFormat: invoke MessageBox,hWinMain,addr szErrFormat,NULL,MB_OK
_ErrorExit:
pop fs:[0]
add esp,0ch
invoke UnmapViewOfFile,@lpMemory
.endif
invoke CloseHandle,@hMapFile
.endif
invoke CloseHandle,@hMapFile
.endif
.endif
@@:
ret
_OpenFile endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
call _Init
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDM_OPEN
call _OpenFile
;invoke MessageBox,NULL,NULL,NULL,NULL
.elseif ax == IDM_EXIT
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
invoke LoadLibrary,offset szDllEdit
mov hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke FreeLibrary,hRichEdit
invoke ExitProcess,NULL
end start
代码在这里这里显示的确够乱的,我会打包上去,供大家下载的
把peinfo.asm编译成peinfo.obj,再与peinfo.res连接,就大功告成了,一个查看pe文件头信息的工具就出来了
- 标 题:自己动手用汇编写PE文件头信息查看工具
- 作 者:xhK
- 时 间:2008-11-27 09:41
- 链 接:http://bbs.pediy.com/showthread.php?t=77544