Update README.md

This commit is contained in:
Cc28256 2020-08-01 17:50:25 +08:00 committed by GitHub
parent 4ae635cd38
commit 1440a5de60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -331,9 +331,13 @@ __in HINSTANCE hMod, \\ 实例句柄 (包含钩子函数的模块句柄)
__in DWORD dwThreadId); \\ 线程ID (指定监视的线程,如果指定确定的线程,即为线程专用钩子;如果指定为空,即为全局钩子。)
```
几点需要说明的地方:
  1 如果对于同一事件(如键盘消息)既安装了线程钩子又安装了系统钩子,系统会优先调用线程钩子,然后调用系统钩子。
  2 对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。处理顺序是先安装的后处理,后安装的先处理。
  3 钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装钩子,在使用完毕后要及时卸载。
###### 定义钩子回调
LRESULT CALLBACK HookProc(int nCode ,WPARAM wParam,LPARAM lParam)
@ -352,6 +356,35 @@ __in DWORD dwThreadId); \\ 线程ID (指定监视的线程,如果指定确
值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。
线程钩子一般在当前线程或者当前线程派生的线程内,而系统钩子必须放在独立的动态链接库中。
#### 6 窗口监控
EnumWindows可以遍历当前屏幕上所有的父窗口创建lpEnumFunc回调函数遍历每一个顶层窗口
```c
BOOL EnumWindows( // 枚举桌面上的所有窗口
_In_ WNDENUMPROC lpEnumFunc, // 回调函数,自己定义 当枚举到窗口时系统就会调用这个函数
_In_ LPARAM lParam // 向回调函数传递的一个参数
);
```
回调函数的返回值必须为TRUE才能保证系统会依次遍历每一个窗口。如果返回值非TRUE则在当前窗口后不会进行后续的遍历动作。
```c
BOOL CALLBACK EnumWindowsProc( // 回调函数的定义
_In_ HWND hwnd, // 系统传递进来的窗口句柄
_In_ LPARAM lParam // 传递进来的那个参数
);
```
GetWindowText、GetWindowThreadProcessId可以通过遍历到的HWND得到对应window的Title、PID
不过这里有个问题在我自己写的demo调用dll枚举窗口时遍历获取信息没有发生问题当使用rundll32调用导出出现了问题
在某一个窗口句柄调用GetWindowText时出现阻塞无法返回。
经过调试分析发现:
调用GetWindowText的进程 == 目标窗口所属于的进程 && 调用GetWindowText的线程 != 目标窗口所属于的线程
此时 GetWindowText将发送WM_GETTEXT消息至目标窗口所在的线程线程响应此消息返回窗口标题。如果目标窗口所在的线程刚好此时无法响应消息则会导致GetWindowText一直处于阻塞状态直到目标窗口所在进程响应了消息才会得到返回。就会出现没有反应或卡死的情况。
解决方案就是调用GetWindowText时判断目标窗口所在进程和线程ID,使用InternalGetWindowText替换GetWindowText
当目标窗口所在进程ID == 调用者所在进程ID && 目标进程所在线程ID != 调用者所在线程ID时->InternalGetWindowText替换GetWindowText
#### active启动方式
win7 64下