看雪论坛
发新帖
3

[源码学习] [共享]自己动手用汇编写PE文件头信息查看工具

xhK 2008-11-27 09:41 9260
编程语言: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文件头信息的工具就出来了
上传的附件:
本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (14)
小菜鸟一 2008-11-27 12:42
2
楼主强大   
arsionkx 2008-11-27 15:13
3
我晕,这也是原创?和罗的书上的代码界面基本一样,我还以为不同的界面在程序里有,原来是其它软件改过来的
3
xhK 2008-11-27 17:05
4
看来你真的是晕了,界面是系统的,因为用的系统的东西
7
newjueqi 2008-11-27 21:06
5
谢谢楼主分享,挺好的编程资料
陈埃 2008-12-1 00:03
6
下载一个收藏。感谢原创分享!
adsljz 2008-12-1 05:29
7
这个是干嘛的?
yanguu 2008-12-1 08:41
8
收藏收藏,路过路过。。。。
7
北极狐狸 2008-12-1 09:40
9
学习手记,值得赞扬....
毫子 2008-12-2 23:26
10
dddddddddddddddddd
panti 2008-12-3 05:43
11
强大,ASM的,难为了
okyzx 2008-12-19 15:43
12
好东西定~~~
AsmBrat 2009-2-9 02:52
13
跟罗云彬书上的一模一样我汗。
cswuyg 2010-4-12 22:48
14
⊙﹏⊙b汗,我搜'RichEd20.dll'无意中跑来这里,竟然发现这个例子跟书上的差不多。⊙﹏⊙b汗
不过也不是完全一样,把“_ProcessPeFile.asm”文件的函数放到Main.asm里面了。。
还有,下面的第三行复制漏了个‘0’,所以显示的时候中间多了一行东西。
szMsgSection  db    '---------------------------------------------',0dh,0ah
        db    '节区名称   节区大小 虚拟地址 Raw_尺寸  Raw_偏移  节区属性',0dh,0ah
        db    '----------------------------------------------',0dh,0ah
hackjack 2010-4-19 14:09
15
我自己写了一个PE文件头的查看程序。不过是自己把PE文件信息打印到控制台啦。
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.015, SQL: 13 / 京ICP备10040895号-17