⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut24.html

📁 win32汇编教程 希望各位多多支持
💻 HTML
📖 第 1 页 / 共 4 页
字号:
button, the program checks if the hook is already installed. If it is not,
it call InstallHook function in the hook DLL to install it. Note that we
pass the handle of the main dialog as the parameter of the function so
the hook DLL can send the WM_MOUSEHOOK messages to the right window i.e.
our own.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>When the program is loaded,
the hook DLL is loaded too. Actually, DLLs are loaded immediately after
the program is in memory. The DLL entrypoint function is called before
the first instruction in the main program is execute even. So when the
main program executes the DLL(s) is/are initialized. We put the following
code in the DLL entrypoint function of the hook DLL:</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; .if
reason==DLL_PROCESS_ATTACH</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push hInst</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop hInstance</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; .endif</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>The code just saves the instance
handle of the hook DLL itself to a global variable named hInstance for
use within the InstallHook function. Since the DLL entrypoint function
is called before other functions in the DLL are called , hInstance is always
valid. We put hInstance in .data section so that this value is kept on
per-process basis. Since when the mouse cursor hovers over a window, the
hook DLL is mapped into the process. Imagine that there is already a DLL
that occupies the intended load address of the hook DLL, the hook DLL would
be remapped to another address. The value of hInstance will be updated
to those of the new load address. When the user presses Unhook button and
then Hook button, SetWindowsHookEx will be called again. However, this
time, it will use the new load address as the instance handle which will
be wrong because in the example process, the hook DLL's load address hasn't
been changed. The hook will be a local one where you can hook only the
mouse events that occur in your own window. Hardly desirable.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>InstallHook proc hwnd:DWORD</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; push
hwnd</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; pop
hWnd</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; invoke
SetWindowsHookEx,WH_MOUSE,addr MouseProc,hInstance,NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; mov
hHook,eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; ret</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>InstallHook endp</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>The InstallHook function
itself is very simple. It saves the window handle passed as its parameter
to a global variable named hWnd for future use. It then calls SetWindowsHookEx
to install a mouse hook. The return value of SetWindowsHookEx is stored
in a global variable named hHook for use with UnhookWindowsHookEx.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>After SetWindowsHookEx is
called, the mouse hook is functional. Whenever a mouse event occurs in
the system, MouseProc ( your hook procedure) is called.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; invoke
CallNextHookEx,hHook,nCode,wParam,lParam</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; mov
edx,lParam</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; assume
edx:PTR MOUSEHOOKSTRUCT</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; invoke
WindowFromPoint,[edx].pt.x,[edx].pt.y</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; invoke
PostMessage,hWnd,WM_MOUSEHOOK,eax,0</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; assume
edx:nothing</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; xor
eax,eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; ret</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>MouseProc endp</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>The first thing it does is
to call CallNextHookEx to give the other hooks the chance to process the
mouse event. After that, it calls WindowFromPoint function to retrieve
the handle of the window at the specified screen coordinate. Note that
we use the POINT structure in the MOUSEHOOKSTRUCT structure pointed to
by lParam as the current mouse coordinate. After that we send the window
handle to the main program via PostMessage with WM_MOUSEHOOK message. One
thing you should remember is that: you should not use SendMessage inside
the hook procedure, it can cause message deadlock. PostMessage is recommended.
The MOUSEHOOKSTRUCT structure is defined below:</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>MOUSEHOOKSTRUCT STRUCT
DWORD</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp; pt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
POINT &lt;></font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp; hwnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp; wHitTestCode&nbsp;
DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp; dwExtraInfo&nbsp;&nbsp;
DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>MOUSEHOOKSTRUCT ENDS</font></font></b>
<br>&nbsp;
<ul>
<li>
<font face="Arial,Helvetica"><font size=-1>pt is the current screen coordinate
of the mouse cursor</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>hwnd is the handle of the window
that will receive the mouse message. It's usually the window under the
mouse cursor but not always. If a window calls SetCapture, the mouse input
will be redirected to that window instead. Because of this reason, I don't
use the hwnd member of this structure but choose to call WindowFromPoint
instead.</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>wHitTestCode specifies the hit-test
value. The hit-test value gives more information about the current mouse
cursor position. It specifies on what part of window the mouse cursor is.
For complete list, check your win32 api reference under WM_NCHITTEST message.</font></font></li>

<li>
<font face="Arial,Helvetica"><font size=-1>dwExtraInfo contains the extra
information associated with the message. Normally this value is set by
calling mouse_event and retrieved by calling GetMessageExtraInfo.</font></font></li>
</ul>
<font face="Arial,Helvetica"><font size=-1>When the main window receives
WM_MOUSEHOOK message, it uses the window handle in wParam to retrieve the
information about the window.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; .elseif
uMsg==WM_MOUSEHOOK</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetDlgItemText,hDlg,IDC_HANDLE,addr buffer1,128</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke wsprintf,addr buffer,addr template,wParam</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke lstrcmpi,addr buffer,addr buffer1</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if eax!=0</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_HANDLE,addr buffer</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer1,128</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetClassName,wParam,addr buffer,128</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke lstrcmpi,addr buffer,addr buffer1</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if eax!=0</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetDlgItemText,hDlg,IDC_WNDPROC,addr buffer1,128</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetClassLong,wParam,GCL_WNDPROC</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke wsprintf,addr buffer,addr template,eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke lstrcmpi,addr buffer,addr buffer1</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if eax!=0</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>To avoid flickers, we check
the text already in the edit controls and the text we will put into them
if they are identical. If they are, we skip them.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>We retrieve the class name
by calling GetClassName, the address of the window procedure by calling
GetClassLong with GCL_WNDPROC and then format them into strings and put
them into the appropriate edit controls.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke UninstallHook</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_HOOK,addr HookText</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov HookFlag,FALSE</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_HANDLE,NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetDlgItemText,hDlg,IDC_WNDPROC,NULL</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>When the user presses Unhook
button, the program calls UninstallHook function in the hook DLL. UninstallHook
just calls UnhookWindowsHookEx. After that, it changes the text of the
button back to "Hook", HookFlag to FALSE and clears the content of the
edit controls.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>Note the linker switch in
the makefile.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Link /SECTION:.bss,S&nbsp; /DLL /DEF:$(NAME).def /SUBSYSTEM:WINDOWS</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>It specifies .bss section
as a shared section to make all processes share the same uninitialized
data section of the hook DLL. Without this switch, your hook DLL will not
function correctly.</font></font>
<br>
<hr WIDTH="100%">
<center><b>[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly
Homepage</a>]</b></center>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -