首页
社区
课程
招聘
[求助]帮我看看问题出在哪里
发表于: 2007-9-5 21:13 4395

[求助]帮我看看问题出在哪里

2007-9-5 21:13
4395
我本想模仿Stud_PE 界面和模块功能实现PE 格式文件信息查看的功能,顺便加深对PE格式文件的理解,没想到刚编写到映射文件到内存这步就卡壳了。我是用Radasm编辑器编写的masm汇编源文件。源文件如下:

ASM 文件:

.386
.model flat,stdcall
option casemap:none

include PE_viewer.inc

.code

start:

        invoke GetModuleHandle,NULL
        mov    hInstance,eax
        invoke GetCommandLine
        mov    CommandLine,eax
        invoke InitCommonControls
        invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
        LOCAL        wc:WNDCLASSEX
        LOCAL        msg:MSG

        mov                wc.cbSize,sizeof WNDCLASSEX
        mov                wc.style,CS_HREDRAW or CS_VREDRAW
        mov                wc.lpfnWndProc,offset WndProc
        mov                wc.cbClsExtra,NULL
        mov                wc.cbWndExtra,DLGWINDOWEXTRA
        push        hInst
        pop                wc.hInstance
        mov                wc.hbrBackground,COLOR_BTNFACE+1
        mov                wc.lpszMenuName,IDM_MENU
        mov                wc.lpszClassName,offset ClassName
        invoke LoadIcon,NULL,IDI_APPLICATION
        mov                wc.hIcon,eax
        mov                wc.hIconSm,eax
        invoke LoadCursor,NULL,IDC_ARROW
        mov                wc.hCursor,eax
        invoke RegisterClassEx,addr wc
        invoke CreateDialogParam,hInstance,IDD_DIALOG,NULL,offset WndProc,NULL
        invoke ShowWindow,hWnd,SW_SHOWNORMAL
        invoke UpdateWindow,hWnd
        .while TRUE
                invoke GetMessage,addr msg,NULL,NULL,NULL
          .BREAK .if !eax
                invoke TranslateMessage,addr msg
                invoke DispatchMessage,addr msg
        .endw
        mov                eax,msg.wParam
        ret

WinMain endp

WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
        
        mov eax,uMsg
        .if eax==WM_INITDIALOG
                push        hWin
                pop        hWnd
        .elseif eax==WM_COMMAND
                mov eax,wParam
                and eax,0FFFFh
                .if eax==IDM_FILE_OPEN
                    invoke OPenFile
                .elseif eax==IDM_HELP_ABOUT
                    invoke ShellAbout,hWin,offset AppName,offset AboutMsg,NULL  
                .elseif eax==IDM_FILE_EXIT
                    invoke SendMessage,hWin,WM_CLOSE,NULL,NULL        
                .endif
;        .elseif eax==WM_SIZE
        .elseif eax==WM_CLOSE
                invoke DestroyWindow,hWin
        .elseif uMsg==WM_DESTROY
                invoke PostQuitMessage,NULL
        .else
                invoke DefWindowProc,hWin,uMsg,wParam,lParam
                ret
        .endif
        xor    eax,eax
        ret

WndProc endp
SEHHandler proc C uses edx pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
mov edx,pFrame
assume edx:ptr SEH
mov eax,pContext
assume eax:ptr CONTEXT
push [edx].SafeOffset
pop [eax].regEip
push [edx].PrevEsp
pop [eax].regEsp
push [edx].PrevEbp
pop [eax].regEbp
mov ValidPE,FALSE
mov eax,ExceptionContinueExecution
ret
SEHHandler endp

OPenFile proc
         LOCAL seh:SEH
         mov ofn.lStructSize,sizeof ofn
         mov ofn.hwndOwner,NULL
         push hWnd
         pop ofn.hInstance
         mov ofn.lpstrFilter,offset FilterString
         mov ofn.lpstrFile,offset FileNameBuffer
         mov ofn.nMaxFile,MAXSIZE
         mov ofn.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or \
                       OFN_EXPLORER or OFN_HIDEREADONLY
         invoke GetOpenFileName, offset ofn
         .if (eax)
                 invoke CreateFile,offset FileNameBuffer,GENERIC_READ,\
                 FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
                 invoke GetWindowText,hWnd,offset WinCaption,MAXSIZE
                 invoke lstrcat,offset WinCaption,offset SeparatingChar
                 invoke lstrcat,offset WinCaption,offset FileNameBuffer
                 invoke wsprintf,offset WinCaption,offset StringFormatter,offset WinCaption
                 invoke SetDlgItemText,hWnd,IDC_EDT_FULLPATH,offset FileNameBuffer
                 invoke SetWindowText,hWnd,offset WinCaption
                 invoke RtlZeroMemory,offset WinCaption,MAXSIZE
                 ;invoke RtlZeroMemory,offset FileNameBuffer,MAXSIZE
;出现无法把文件映射到内存的原因是:
                ;红色字体部分放错位置了,在创建文件并没有执行保存文件句柄前调用了库函数,直接将返回到eax的
;文件句柄覆盖了,当然在下面的绿色字体部分保存文件句柄时已经不再是创建文件的句柄,而是上面红色字体部分最后被调用函数
;的返回值,因此出错

                 .if eax!=INVALID_HANDLE_VALUE
                         mov hFile,eax
               ;应该放到这里才正确并修正为(红色部分)
                invoke lstrcat,offset WinCaption,offset AppName
                 invoke lstrcat,offset WinCaption,offset SeparatingChar
                 invoke lstrcat,offset WinCaption,offset FileNameBuffer
                 invoke wsprintf,offset WinCaption,offset StringFormatter,offset WinCaption
                 invoke SetDlgItemText,hWnd,IDC_EDT_FULLPATH,offset FileNameBuffer
                 invoke SetWindowText,hWnd,offset WinCaption ;这句可有可无吗?
                 invoke RtlZeroMemory,offset WinCaption,MAXSIZE ;这句可有可无吗?
                 invoke RtlZeroMemory,offset FileNameBuffer,MAXSIZE

                 ;到此为止
                         invoke CreateFileMapping,hFile,NULL,PAGE_READONLY,NULL,NULL,NULL
                         .if eax!=NULL
                                 mov pMapping,eax
                                 assume fs:nothing
                                 push fs:[0]
                                 pop seh.PrevLink
                                 mov seh.CurrentHandler,offset SEHHandler
                                 mov seh.SafeOffset,offset FinalExit
                                 lea eax,seh
                                 mov fs:[0],eax
                                 mov seh.PrevEsp,esp
                                 mov seh.PrevEbp,ebp
                                 mov edi,pMapping
                                 assume edi:ptr IMAGE_DOS_HEADER
                                 .if [edi].e_magic==IMAGE_DOS_SIGNATURE
                                         add edi,[edi].e_lfanew
                                         assume edi:ptr IMAGE_NT_HEADERS
                                         .if [edi].Signature==IMAGE_NT_SIGNATURE
                                                 mov ValidPE,TRUE
                                         .else
                                                 mov ValidPE,FALSE
                                         .endif
                                 .else
                                         mov ValidPE,FALSE       
                                 .endif
                         FinalExit:
                                 .if ValidPE==TRUE
                                         invoke MessageBox,NULL,offset FileValidPE,offset AppName,MB_OK+MB_ICONINFORMATION
                                 .else
                                         invoke MessageBox,NULL,offset FileInValidPE,offset AppName,MB_OK+MB_ICONINFORMATION       
                                 .endif
                                 push seh.PrevLink
                                 pop fs:[0]
                                 invoke UnmapViewOfFile,pMapping
                         .else
                                 invoke MessageBox,NULL,offset FileMappingError,offset AppName,MB_OK+MB_ICONERROR
                         .endif
                         invoke CloseHandle,hMapping
                 .else
                         invoke MessageBox,NULL,offset FileOpenMappingError,offset AppName,MB_OK+MB_ICONERROR
                 .endif
                 invoke CloseHandle,hFile
         .else
                 invoke MessageBox,NULL,offset FileOpenError,offset AppName,MB_OK+MB_ICONERROR
         .endif
ret
OPenFile endp

end start

包含文件:

include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
include comctl32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib comctl32.lib
includelib comdlg32.lib

WinMain                                PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc                                PROTO :DWORD,:DWORD,:DWORD,:DWORD
OPenFile                        PROTO
IDD_DIALOG                        equ 1000
IDC_EDT_FULLPATH                equ 1003
IDM_MENU                        equ 10000
IDM_FILE_EXIT                        equ 10001
IDM_FILE_OPEN                   equ 10002
IDM_HELP_ABOUT                        equ 10101
MAXSIZE                         equ 260
SEH  struct
   PrevLink                     dd ?
   CurrentHandler               dd ?
   SafeOffset                   dd ?
   PrevEsp                      dd ?
   PrevEbp                      dd ?
SEH  ends

.data

ClassName                        db 'DLGCLASS',0
AppName                                db 'PE_viewer',0
AboutMsg                        db 'MASM32 RadASM Dialog as main',13,10,'Copyright ?MASM32 2001',0
ofn                             OPENFILENAME <>
FilterString                    db '可执行文件(*.exe,*.dll)',0,'*.exe;*.dll',0 ;注意过滤类型串
;中*.exe和*.dll 之间的分隔符必须为分号(;),而不能为逗号(,),否则将所有文件过滤掉
                                db '所有文件(*.*)',0,'*.*',0,0
FileOpenError                   db "无法读取文件",0
FileOpenMappingError            db "无法打开要映射的文件",0
FileMappingError                db "无法把文件映射到内存",0
FileValidPE                     db "这是一个有效的PE格式文件",0
FileInValidPE                   db "这不是一个有效的PE格式文件",0
SeparatingChar                  db " - ",0
HexFomatter                     db '%08X',0
DecFormatter                        DB "%d",0
StringFormatter                        DB "%s",0                        
.data?

hInstance                        dd ?
CommandLine                        dd ?
hWnd                                dd ?
FileNameBuffer                  db MAXSIZE dup(?)
WinCaption                      db MAXSIZE dup(?)
hFile                           dd ?
hMapping                        dd ?
pMapping                        dd ?
ValidPE                         dd ?

资源文件:

#include "Res/PE_viewerMnu.rc"
#include "Res/PE_viewerDlg.rc"

PE_viewerMnu.rc 文件:

#define IDM_MENU 10000
#define IDM_FILE_OPEN 10002
#define IDM_FILE_EXIT 10001
#define IDM_HELP_ABOUT 10101
IDM_MENU MENUEX
BEGIN
  POPUP "文件(&F)"
  BEGIN
    MENUITEM "打开(&O)",IDM_FILE_OPEN
    MENUITEM "退出(&X)",IDM_FILE_EXIT
  END
  POPUP "帮助(&H)"
  BEGIN
    MENUITEM "关于(&A)",IDM_HELP_ABOUT
  END
END

PE_viewerDlg.rc 文件:

#define IDD_DIALOG 1000
#define IDC_GRP1 1001
#define IDC_STC_FULLPATH 1002
#define IDC_EDT_FULLPATH 1003
IDD_DIALOG DIALOGEX 6,4,318,236
CAPTION "PE_viewer"
FONT 9,"宋体",400,0
CLASS "DLGCLASS"
STYLE 0x10CA0800
EXSTYLE 0x00000000
BEGIN
  CONTROL "",IDC_GRP1,"Button",0x50000007,2,0,314,18,0x00000000
  CONTROL "文件完整路径:",IDC_STC_FULLPATH,"Static",0x50000000,4,8,56,8,0x00000000
  CONTROL "",IDC_EDT_FULLPATH,"Edit",0x50010800,60,6,254,10,0x00020000
END

结果执行菜单上的文件->打开项后能正确调用打开通用对话框,并能正确过滤文件类型,可是本来我想实现窗口标题默认就是PE_viewer,打开文件后窗口标题显示成
原标题 - 打开文件的完整路径的组合,没想到“实现了”,看下图:


然而,只要你不关闭这个主窗口,继续通过菜单打开文件时,竟然变成了:原窗口标题 - 最先打开文件的完整路径 - 第2个打开文件的完整路径 - ……,这显然没道理,不知是何原因????,看下图:


第二个就是我反复看了源文件也没找到哪里出问题,始终任意打开一个可执行文件,马上就这样:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
关于窗口标题出现那样的问题是很显然的。。。
直接用 “PE_viewer”去和打开的文件名去 lstrcat ,
这句
invoke GetWindowText,hWnd,offset WinCaption,MAXSIZE
就不要了
2007-9-6 21:37
0
雪    币: 63
活跃值: (71)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
非常谢谢十指紧扣,这样编写确实解决了窗口标题的问题,如果窗口标题是动态改变的话(比如木马克星就是如此),那这种情况又怎么处理呢?
2007-9-7 13:28
0
游客
登录 | 注册 方可回帖
返回
//