(Win32ASM)Spy(功能还未完善)

发现很久没写日志了,也发现自己以前写的东西真的没点技术含量!主要是因为底子薄,不敢出来露怯,怕广大同志们所为不齿。这次的东西稍微有点技术,因为涉及了钩子,因为涉及了一些底层的API。程序的主要功能如下:

  • 获取鼠标所在位置窗口的句柄以及类名
  • 激活一些应用程序的灰化按钮

拦取鼠标信息,钩子名称是WH_MOUSE,不同的钩子涉及到不同的钩子信息:

WH_MOUSE

  • nCode 为HC_ACTION 或 HC_NOREMOVE
  • wParam 包含鼠标的事件消息
  • lParam 指向MOUSEHOOKSTRUCT型结构体变量的指针
  • return value: 如果不处理返回0,否则返回非0值

MHook.asm源代码如下,我们的任务是将它封装成DLL,并且将.bss段编译成共享

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                .386
                .model  flat, stdcall
                option  casemap :none
;------------------------------------------------------------------
include         windows.inc
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.lib

include         macro.asm
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
WM_MOUSEHOOK    equ     WM_USER + 4

                .data?
hHook           dd      ?
hWnd            dd      ?
        
                .data
hInstance       dd      ?
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                .code

DLLEntry        proc    hInstDLL, dwReason, dwReserved
        
        mov     eax,dwReason
        .if     eax ==  DLL_PROCESS_ATTACH
                push    hInstDLL
                pop     hInstance
        .endif
        mov     eax,TRUE
        ret
        
DLLEntry        endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HookProc        proc    _nCode, _wParam, _lParam
        
        invoke  CallNextHookEx,hHook,_nCode,_wParam,_lParam
        mov     edx,_lParam
        assume  edx:ptr MOUSEHOOKSTRUCT
        invoke  WindowFromPoint,[edx].pt.x,[edx].pt.y
        invoke  PostMessage,hWnd,WM_MOUSEHOOK,eax,0
        assume  edx:nothing
        xor     eax,eax
        ret
HookProc        endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
InstallHook     proc    _hWnd
        
        push    _hWnd
        pop     hWnd
        invoke  SetWindowsHookEx,WH_MOUSE,offset HookProc,hInstance,NULL
        mov     hHook,eax
        ret
        
InstallHook     endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
UninstallHook   proc
        
        invoke  UnhookWindowsHookEx,hHook
        ret
        
UninstallHook   endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                end     DLLEntry

主函数内容主要是处理WM_MOUSEHOOK消息,这是我们自定义的消息,值为WM_USER + 4,Spy--.asm代码如下:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                .386
                .model  flat, stdcall
                option  casemap :none
;------------------------------------------------------------------
include         windows.inc
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.lib
include         shell32.inc
includelib      shell32.lib
include         mhook.inc
includelib      mhook.lib

include         macro.asm
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ICO_MAIN                equ     1000
DLG_MAIN                equ     100
IDC_ENABLEWINDOW        equ     101
IDC_FGHandle            equ     102
IDC_CLASSNAME           equ     103
IDC_HANDLE              equ     104
IDC_WNDPROC             equ     105
IDC_CURSORPOS           equ     106
IDC_ABOUT               equ     107
IDC_HOOK                equ     108
IDC_EXIT                equ     109
IDC_HELPER              equ     110

DLG_HELP                equ     200

WM_MOUSEHOOK            equ     WM_USER + 4
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                .data?
hInstance       dd      ?
hMutex          dd      ?

                .data
HookFlag        dd      FALSE
EnableFlag      dd      FALSE
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                
                .code
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_ProcDlgHelp    proc    uses ebx edi esi _hWnd, _wMsg, _wParam, _lParam
        
        mov     eax,_wMsg
        .if     eax ==  WM_COMMAND
                mov     eax,_wParam
                .if     ax ==  IDOK
                        invoke  EndDialog,_hWnd,NULL
                .endif
        .elseif eax ==  WM_CLOSE
                invoke  EndDialog,_hWnd,NULL
        .else
                mov     eax,FALSE
                ret
        .endif
        mov     eax,TRUE
        ret
        
_ProcDlgHelp    endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_EnableButton   proc    _hWnd, _lParam
        
        invoke  IsWindowEnabled,_hWnd
        .if     ! eax
                invoke  EnableWindow,_hWnd,TRUE
        .endif
        mov     eax,TRUE
        ret
        
_EnableButton   endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_ProcDlgMain    proc    uses ebx edi esi hWnd, wMsg, wParam, lParam
        local   @szBuffer[128]:BYTE
        local   @szBufferNew[128]:BYTE
        local   @stPos:POINT
        
        mov     eax,wMsg
        .if     eax ==  WM_MOUSEHOOK
                invoke  GetDlgItemText,hWnd,IDC_HANDLE,addr @szBuffer,128
                invoke  wsprintf,addr @szBufferNew,CTXT("%lX"),wParam
                invoke  lstrcmpi,addr @szBuffer,addr @szBufferNew
                .if     eax
                        invoke  SetDlgItemText,hWnd,IDC_HANDLE,addr @szBufferNew
                .endif
                invoke  GetDlgItemText,hWnd,IDC_CLASSNAME,addr @szBuffer,128
                invoke  GetClassName,wParam,addr @szBufferNew,128
                invoke  lstrcmpi,addr @szBuffer,addr @szBufferNew
                .if     eax
                        invoke  SetDlgItemText,hWnd,IDC_CLASSNAME,addr @szBufferNew
                .endif
                invoke  GetDlgItemText,hWnd,IDC_WNDPROC,addr @szBuffer,128
                invoke  GetClassLong,wParam,GCL_WNDPROC
                invoke  wsprintf,addr @szBufferNew,CTXT("%lX"),eax
                invoke  lstrcmpi,addr @szBuffer,addr @szBufferNew
                .if     eax
                        invoke  SetDlgItemText,hWnd,IDC_WNDPROC,addr @szBufferNew
                .endif
                invoke  GetCursorPos,addr @stPos
                invoke  wsprintf,addr @szBuffer,CTXT("%ld, %ld"),@stPos.x,@stPos.y
                invoke  SetDlgItemText,hWnd,IDC_CURSORPOS,addr @szBuffer
                ;----------------------------------
                ; 根据标志位来判断是否执行激活按钮选项
                ;----------------------------------
                .if     EnableFlag
                        invoke  GetForegroundWindow
                        push    eax
                        invoke  wsprintf,addr @szBuffer,CTXT("%lX"),eax
                        invoke  SetDlgItemText,hWnd,IDC_FGHandle,addr @szBuffer
                        pop     eax
                        invoke  EnumChildWindows,eax,offset _EnableButton,NULL
                .endif
        .elseif eax ==  WM_COMMAND
                mov     eax,wParam
                .if     ax ==  IDC_ENABLEWINDOW
                        invoke  IsDlgButtonChecked,hWnd,IDC_ENABLEWINDOW
                        .if     eax ==  BST_CHECKED
                                mov     EnableFlag,TRUE
                        .else
                                mov     EnableFlag,FALSE
                                invoke  SetDlgItemText,hWnd,IDC_FGHandle,NULL
                        .endif
                .elseif ax ==  IDC_HOOK
                        .if     HookFlag == FALSE
                                invoke  InstallHook,hWnd
                                .if     eax
                                        mov     HookFlag,TRUE
                                        invoke  SetDlgItemText,hWnd,IDC_HOOK,CTXT("&UnHook")
                                .endif
                        .else
                                invoke  UninstallHook
                                mov     HookFlag,FALSE
                                invoke  SetDlgItemText,hWnd,IDC_HOOK,CTXT("&Hook")
                                invoke  SetDlgItemText,hWnd,IDC_CLASSNAME,NULL
                                invoke  SetDlgItemText,hWnd,IDC_HANDLE,NULL
                                invoke  SetDlgItemText,hWnd,IDC_WNDPROC,NULL
                                invoke  SetDlgItemText,hWnd,IDC_CURSORPOS,NULL
                                invoke  SetDlgItemText,hWnd,IDC_FGHandle,NULL
                        .endif
                .elseif ax ==  IDC_ABOUT
                        invoke  ShellExecute,hWnd,CTXT("open"),CTXT("http://blog.csdn.net/sunweiqq"),NULL,NULL,SW_SHOW
                .elseif ax ==  IDC_HELPER
                        invoke  DialogBoxParam,hInstance,DLG_HELP,hWnd,offset _ProcDlgHelp,NULL
                .elseif ax ==  IDC_EXIT
                        invoke  SendMessage,hWnd,WM_CLOSE,0,0
                .endif  
        .elseif eax ==  WM_INITDIALOG
                invoke  LoadIcon,hInstance,ICO_MAIN
                invoke  SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
                invoke  SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE or SWP_NOMOVE
        .elseif eax ==  WM_CLOSE
                .if     HookFlag ==  TRUE
                        invoke  UninstallHook
                .endif
                invoke  EndDialog,hWnd,NULL
        .else
                mov     eax,FALSE
                ret
        .endif
        mov     eax,TRUE
        ret
        
_ProcDlgMain    endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
start:
        invoke  CreateMutex,0,FALSE,CTXT("ONLY_ONE")
        mov     hMutex,eax
        invoke  GetLastError
        .if     eax ==  ERROR_ALREADY_EXISTS
                invoke  MessageBox,NULL,CTXT("程序已经有个实例在运行!"),NULL,MB_ICONWARNING
                jmp     GoEnd
        .endif
        invoke  LoadLibrary,CTXT("Splash.dll")
        .if     eax
                invoke  FreeLibrary,eax
        .else
                invoke  MessageBox,NULL,CTXT("Splash.dll 丢失或装载失败"),NULL,MB_OK or MB_ICONERROR
                jmp     @F
        .endif 
        invoke  GetModuleHandle,NULL
        mov     hInstance,eax
        invoke  DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
@@:
        invoke  CloseHandle,hMutex
GoEnd:
        invoke  ExitProcess,NULL
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        end     start

当然程序中也用到了另外一个Splash.dll,启动画面的功能组件,没什么技术,就不拿出来露怯了。另外还想完成的功能是:

  • 像Jeffrey的SPY++一样有截取消息的功能
  • 有个探取按钮,当鼠标点在上面的时候,光标形状变成一个小圆,并且光标所到之处能显示出来控件的形状,我想主要涉及到一些绘图函数,很容易解决

如下图:SPY++

本程序截图如下:

SPY--

-------------------------------------------------------

kedebug

Department of Computer Science and Engineering,

Shanghai Jiao Tong University

E-mail: kedebug0@gmail.com

GitHub: http://github.com/kedebug

-------------------------------------------------------

原文地址:https://www.cnblogs.com/kedebug/p/2791755.html