编写PEDump,读取内容跟FlexHex的显示格式差不多
- .386
- .model flat,stdcall
- option casemap:none
-
- include windows.inc
- include user32.inc
- includelib user32.lib
- include kernel32.inc
- includelib kernel32.lib
- include comdlg32.inc
- includelib comdlg32.lib
-
-
- ICO_MAIN equ 1000
- DLG_MAIN equ 1000
- IDC_INFO equ 1001
- IDM_MAIN equ 2000
- IDM_OPEN equ 2001
- IDM_EXIT equ 2002
- IDM_1 equ 4000
- IDM_2 equ 4001
- IDM_3 equ 4002
-
- .data
- hInstance dd ? ; 进程句柄
- hRichEdit dd ?
- hWinMain dd ? ; 弹出窗口句柄
- hWinEdit dd ? ; 富文本框句柄
- totalSize dd ? ; 文件大小
- lpMemory dd ? ; 内存映像文件在内存的起始位置
- szFileName db MAX_PATH dup(?) ;要打开的文件路径及名称名
-
- lpServicesBuffer db 100 dup(0) ;所有内容
- bufDisplay db 50 dup(0) ;第三列ASCII码字符显示
- szBuffer db 200 dup(0) ;临时缓冲区
- lpszFilterFmt4 db '%08x ',0
- lpszManyBlanks db ' ',0
- lpszBlank db ' ',0
- lpszSplit db '-',0
- lpszScanFmt db '%02x',0
- lpszHexArr db '0123456789ABCDEF',0
- lpszReturn db 0dh,0ah,0
- lpszDoubleReturn db 0dh,0ah,0dh,0ah,0
- lpszOut1 db '文件大小:%d',0
- dwStop dd 0
- .const
- szDllEdit db 'RichEd20.dll',0
- szClassEdit db 'RichEdit20A',0
- szFont db '宋体',0
- szExtPe db 'PE File',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
- db 'All Files(*.*)',0,'*.*',0,0
- szErr db '文件格式错误!',0
- szErrFormat db '操作文件时出现错误!',0
-
-
- .code
-
- ;----------------
- ;初始化窗口程序
- ;----------------
- _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,14*1440/96
- 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
- ;------------------
- _Handler proc _lpExceptionRecord,_lpSEH,\
- _lpContext,_lpDispathcerContext
-
- 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
-
- ;---------------------
- ; 往文本框中追加文本
- ;---------------------
- _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
-
-
- ;--------------------
- ; 打开PE文件并处理
- ;--------------------
- _openFile proc
- local @stOF:OPENFILENAME
- local @hFile,@hMapFile
- local @bufTemp1 ; 十六进制字节码
- local @bufTemp2 ; 第一列
- local @dwCount ; 计数,逢16则重新计
- local @dwCount1 ; 地址顺号
- local @dwBlanks ; 最后一行空格数
-
- 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
- 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 totalSize,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 ;获得文件在内存的映象起始位置
- assume fs:nothing
- push ebp
- push offset _ErrFormat
- push offset _Handler
- push fs:[0]
- mov fs:[0],esp
-
- ;开始处理文件
-
- ;缓冲区初始化
- invoke RtlZeroMemory,addr @bufTemp1,10
- invoke RtlZeroMemory,addr @bufTemp2,20
- invoke RtlZeroMemory,addr lpServicesBuffer,100
- invoke RtlZeroMemory,addr bufDisplay,50
-
- mov @dwCount,1
- mov esi,lpMemory
- mov edi,offset bufDisplay
-
- ; 将第一列写入lpServicesBuffer
- mov @dwCount1,0
- invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,@dwCount1
- invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2
-
- ;求最后一行的空格数(16-长度%16)*3
- xor edx,edx
- mov eax,totalSize
- mov ecx,16
- div ecx
- mov eax,16
- sub eax,edx
- xor edx,edx
- mov ecx,3
- mul ecx
- mov @dwBlanks,eax
-
- ;invoke wsprintf,addr szBuffer,addr lpszOut1,totalSize
- ;invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK
-
- .while TRUE
- .if totalSize==0 ;最后一行
- ;填充空格
- .while TRUE
- .break .if @dwBlanks==0
- invoke lstrcat,addr lpServicesBuffer,addr lpszBlank
- dec @dwBlanks
- .endw
- ;第二列与第三列中间的空格
- invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
- ;第三列内容
- invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
- ;回车换行符号
- invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
- .break
- .endif
- ;将al翻译成可以显示的ascii码字符,注意不能破坏al的值
- mov al,byte ptr [esi]
- .if al>20h && al<7eh
- mov ah,al
- .else ;如果不是ASCII码值,则显示“.”
- mov ah,2Eh
- .endif
- ;写入第三列的值
- mov byte ptr [edi],ah
-
- ;win2k不支持al字节级别,经常导致程序无故结束,
- ;因此用以下方法替代
- ;invoke wsprintf,addr @bufTemp1,addr lpszFilterFmt3,al
-
- mov bl,al
- xor edx,edx
- xor eax,eax
- mov al,bl
- mov cx,16
- div cx ;结果高位在al中,余数在dl中
-
- ;组合字节的十六进制字符串到@bufTemp1中,类似于:“7F \0”
- push edi
- xor bx,bx
- mov bl,al
- movzx edi,bx
- mov bl,byte ptr lpszHexArr[edi]
- mov byte ptr @bufTemp1[0],bl
-
- xor bx,bx
- mov bl,dl
- movzx edi,bx
- mov bl,byte ptr lpszHexArr[edi]
- mov byte ptr @bufTemp1[1],bl
- mov bl,20h
- mov byte ptr @bufTemp1[2],bl
- mov bl,0
- mov byte ptr @bufTemp1[3],bl
- pop edi
-
- ; 将第二列写入lpServicesBuffer
- invoke lstrcat,addr lpServicesBuffer,addr @bufTemp1
-
- .if @dwCount==16 ;已到16个字节,
- ;第二列与第三列中间的空格
- invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
- ;显示第三列字符
- invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
- ;回车换行
- invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
-
- ;写入内容
- invoke _appendInfo,addr lpServicesBuffer
- invoke RtlZeroMemory,addr lpServicesBuffer,100
-
- .break .if dwStop==1
-
- ;显示下一行的地址
- inc @dwCount1
- invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,\
- @dwCount1
- invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2
- dec @dwCount1
-
- mov @dwCount,0
- invoke RtlZeroMemory,addr bufDisplay,50
- mov edi,offset bufDisplay
- ;为了能和后面的inc edi配合使edi正确定位到bufDisplay处
- dec edi
- .endif
-
- dec totalSize
- inc @dwCount
- inc esi
- inc edi
- inc @dwCount1
- .endw
-
- ;添加最后一行
- invoke _appendInfo,addr lpServicesBuffer
-
-
- ;处理文件结束
-
- jmp _ErrorExit
-
- _ErrFormat:
- invoke MessageBox,hWinMain,offset szErrFormat,NULL,MB_OK
- _ErrorExit:
- pop fs:[0]
- add esp,0ch
- invoke UnmapViewOfFile,lpMemory
- .endif
- invoke CloseHandle,@hMapFile
- .endif
- invoke CloseHandle,@hFile
- .endif
- .endif
- @@:
- ret
- _openFile endp
- ;-------------------
- ; 窗口程序
- ;-------------------
- _ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
- local @sClient
-
- 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 eax==IDM_EXIT ;退出
- invoke EndDialog,hWnd,NULL
- .elseif eax==IDM_OPEN ;打开文件
- mov dwStop,0
- invoke CreateThread,NULL,0,addr _openFile,addr @sClient,0,NULL
- ;invoke _openFile
- .elseif eax==IDM_1
- mov dwStop,1
- .elseif eax==IDM_2
- .elseif eax==IDM_3
- .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
编译ASM生成OBJ
ml -c -coff pedump.asm
链接pe.res pedump.obj生成pedump.exe
link -subsystem:windows pedump.obj pe.res