请问大家能否对专门一个程序安装钩子?根据我的理解,我用IceSword查出了其他程序的线程ID,设置为第四个参数,可一点效果都没有。就拿记事本程序做实验,我查出它是单线程的。不论我把第四个参数设置成它的进程ID还是线程ID都不起作用。(都采用了dll,程序没有问题,全局钩子都可以实现,仅仅改变了ID)
思考了原因我有以下疑问:
1.难道SetWindowsHookEx()函数只能为本身安装钩子或者安装全局钩子?不能为其他单个程序安装钩子?
2.我知道进程ID是系统唯一的,但是线程ID是在某一个进程内唯一,还是在整个操作系统内唯一?
3.说了那么多废话,前面大家可以不理,只要求实现一个事情:打开记事本窗口,通过编写一个钩子屏蔽记事本的键盘或鼠标消息,要求只能屏蔽记事本范围内的,不允许写全局钩子屏蔽所有程序的。也就是说,只有记事本接收不到鼠标和键盘消息,其他的程序不受影响.无论大家是自己写还是转贴,贴源代码也好,说思想也好,经测试能实现的100分送出。
16 个解决方案
#1
1.为其他单个程序安装钩子,设置第三个参数hMod为需要设置的应用程序的实例句柄,dwThreadId设为空
2.进程线程id都是系统唯一的
3。SetWindowsHookEx(WH_KEYBOARD|WH_MOUSE,lpfn,hMod,NULL)
hmod为记事本程序的实例句柄
2.进程线程id都是系统唯一的
3。SetWindowsHookEx(WH_KEYBOARD|WH_MOUSE,lpfn,hMod,NULL)
hmod为记事本程序的实例句柄
#2
1、不能。
2、系统唯一。
3、可以这样试试:Hook全局键盘和鼠标事件,键盘函数中判断当前活动窗口,鼠标函数根据鼠标位置判断窗口,然后再GetWindowThreadProcessId获得窗口所属进程ID,判断出是记事本时直接返回非0值。
2、系统唯一。
3、可以这样试试:Hook全局键盘和鼠标事件,键盘函数中判断当前活动窗口,鼠标函数根据鼠标位置判断窗口,然后再GetWindowThreadProcessId获得窗口所属进程ID,判断出是记事本时直接返回非0值。
#3
你测试成功了?
hMod
Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
hMod是动态链接库实例的句柄,不是要挂钩的程序实例句柄。
#4
1 全局的钩子可以用GetModuleFileName判断当前进程是不是你要钩的进程
2 操作系统内唯一
3 见1
2 操作系统内唯一
3 见1
#5
hmod为记事本模块的实例句柄,即记事本可执行文件模块句柄
#6
Up
#7
SetWindowsHookEx()貌似可以为某个程序安装钩子啊,我都是这么干的。。。
hMod为你要插入的Dll的句柄,dwThreadId为目标线程的Id(一般是目标进程的主线程)
dwThreadId一般使用GetWindowThreadProcessId的返回值
hMod为你要插入的Dll的句柄,dwThreadId为目标线程的Id(一般是目标进程的主线程)
dwThreadId一般使用GetWindowThreadProcessId的返回值
#8
up
#9
HINSTANCE表示的是该模块在进程内的开始地址,不能用它来识别进程,我所见过的EXE模块的HINSTANCE都是0x400000。
#10
up
#11
有源代码吗?我直接添ID号都不行
#12
用GetWindowThreadProcessId得到该窗口的线程的id,其他第三方软件查的可能不准。
你可以先FindWindowEx到记事本的句柄。
你可以先FindWindowEx到记事本的句柄。
#13
WH_MOUSE不能针对其它进程的某个线程,但是WH_GETMESSAGE可以
Hook.h
Hook.cpp
Hook.h
#ifdef HOOK_EXPORTS
#define HOOK_API __declspec(dllexport)
#else
#define HOOK_API __declspec(dllimport)
#endif
#define WM_HOOK WM_USER + 1
HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId);
HOOK_API BOOL UnHook();
Hook.cpp
#include "stdafx.h"
#include "Hook.h"
#pragma data_seg("HookShared")
HHOOK hHook = NULL;
HWND hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:HookShared,RWS")
HINSTANCE hMod;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hMod = (HINSTANCE)hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LRESULT WINAPI HookProc(int code, WPARAM wParam, LPARAM lParam)
{
PMSG pMsg = (PMSG)lParam;
if (pMsg->message == WM_MOUSEMOVE)
SendMessage(hWnd, WM_HOOK, pMsg->wParam, pMsg->lParam);
return CallNextHookEx(hHook, code, wParam, lParam);
}
HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId)
{
hWnd = hWindow;
hHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, hMod, dwThreadId);
return hHook != NULL;
}
HOOK_API BOOL UnHook()
{
hWnd = NULL;
return UnhookWindowsHookEx(hHook);
}
#14
HostDlg.h
HostDlg.cpp
那些MFC自动生成的我就没贴了
m_EdtWnd是个文本框、BtnStart和BtnStop是两个按钮,没其它东西了,资源文件就不贴了
class CHostDlg : public CDialog
{
// Construction
public:
CHostDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CHostDlg)
enum { IDD = IDD_HOST_DIALOG };
CEdit m_EdtWnd;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHostDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CHostDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnBtnStart();
afx_msg void OnBtnStop();
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnHookMsg(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
HostDlg.cpp
void CHostDlg::OnBtnStart()
{
// TODO: Add your control notification handler code here
this->SetCapture();
m_EdtWnd.SetWindowText(_T("单击任意窗体"));
}
void CHostDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
::ReleaseCapture();
POINT pt;
::GetCursorPos(&pt);
HWND hWnd = ::WindowFromPoint(pt);
TCHAR szCaption[128];
::GetWindowText(hWnd, szCaption, 127);
DWORD dwThreadId = ::GetWindowThreadProcessId(hWnd, NULL);
if (dwThreadId != 0)
{
if (SetHook(this->m_hWnd, dwThreadId))
StrCat(szCaption, _T("-钩挂成功"));
else
StrCat(szCaption, _T("-钩挂失败"));
m_EdtWnd.SetWindowText(szCaption);
}
CDialog::OnLButtonUp(nFlags, point);
}
LRESULT CHostDlg::OnHookMsg(WPARAM wParam, LPARAM lParam)
{
POINT pt;
TCHAR szInfo[128];
::GetCursorPos(&pt);
wsprintf(szInfo, "鼠标位置:X:%d Y:%d", pt.x, pt.y);
m_EdtWnd.SetWindowText(szInfo);
return 0;
}
void CHostDlg::OnBtnStop()
{
// TODO: Add your control notification handler code here
UnHook();
m_EdtWnd.SetWindowText(NULL);
}
那些MFC自动生成的我就没贴了
m_EdtWnd是个文本框、BtnStart和BtnStop是两个按钮,没其它东西了,资源文件就不贴了
#15
记得加上ON_MESSAGE(WM_HOOK, OnHookMsg)这句消息映射,这个忘贴了
#16
钻石级的就是牛叉啊,GetModuleFlieName判断一下果然搞定。
#1
1.为其他单个程序安装钩子,设置第三个参数hMod为需要设置的应用程序的实例句柄,dwThreadId设为空
2.进程线程id都是系统唯一的
3。SetWindowsHookEx(WH_KEYBOARD|WH_MOUSE,lpfn,hMod,NULL)
hmod为记事本程序的实例句柄
2.进程线程id都是系统唯一的
3。SetWindowsHookEx(WH_KEYBOARD|WH_MOUSE,lpfn,hMod,NULL)
hmod为记事本程序的实例句柄
#2
1、不能。
2、系统唯一。
3、可以这样试试:Hook全局键盘和鼠标事件,键盘函数中判断当前活动窗口,鼠标函数根据鼠标位置判断窗口,然后再GetWindowThreadProcessId获得窗口所属进程ID,判断出是记事本时直接返回非0值。
2、系统唯一。
3、可以这样试试:Hook全局键盘和鼠标事件,键盘函数中判断当前活动窗口,鼠标函数根据鼠标位置判断窗口,然后再GetWindowThreadProcessId获得窗口所属进程ID,判断出是记事本时直接返回非0值。
#3
你测试成功了?
hMod
Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
hMod是动态链接库实例的句柄,不是要挂钩的程序实例句柄。
#4
1 全局的钩子可以用GetModuleFileName判断当前进程是不是你要钩的进程
2 操作系统内唯一
3 见1
2 操作系统内唯一
3 见1
#5
hmod为记事本模块的实例句柄,即记事本可执行文件模块句柄
#6
Up
#7
SetWindowsHookEx()貌似可以为某个程序安装钩子啊,我都是这么干的。。。
hMod为你要插入的Dll的句柄,dwThreadId为目标线程的Id(一般是目标进程的主线程)
dwThreadId一般使用GetWindowThreadProcessId的返回值
hMod为你要插入的Dll的句柄,dwThreadId为目标线程的Id(一般是目标进程的主线程)
dwThreadId一般使用GetWindowThreadProcessId的返回值
#8
up
#9
HINSTANCE表示的是该模块在进程内的开始地址,不能用它来识别进程,我所见过的EXE模块的HINSTANCE都是0x400000。
#10
up
#11
有源代码吗?我直接添ID号都不行
#12
用GetWindowThreadProcessId得到该窗口的线程的id,其他第三方软件查的可能不准。
你可以先FindWindowEx到记事本的句柄。
你可以先FindWindowEx到记事本的句柄。
#13
WH_MOUSE不能针对其它进程的某个线程,但是WH_GETMESSAGE可以
Hook.h
Hook.cpp
Hook.h
#ifdef HOOK_EXPORTS
#define HOOK_API __declspec(dllexport)
#else
#define HOOK_API __declspec(dllimport)
#endif
#define WM_HOOK WM_USER + 1
HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId);
HOOK_API BOOL UnHook();
Hook.cpp
#include "stdafx.h"
#include "Hook.h"
#pragma data_seg("HookShared")
HHOOK hHook = NULL;
HWND hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:HookShared,RWS")
HINSTANCE hMod;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hMod = (HINSTANCE)hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LRESULT WINAPI HookProc(int code, WPARAM wParam, LPARAM lParam)
{
PMSG pMsg = (PMSG)lParam;
if (pMsg->message == WM_MOUSEMOVE)
SendMessage(hWnd, WM_HOOK, pMsg->wParam, pMsg->lParam);
return CallNextHookEx(hHook, code, wParam, lParam);
}
HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId)
{
hWnd = hWindow;
hHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, hMod, dwThreadId);
return hHook != NULL;
}
HOOK_API BOOL UnHook()
{
hWnd = NULL;
return UnhookWindowsHookEx(hHook);
}
#14
HostDlg.h
HostDlg.cpp
那些MFC自动生成的我就没贴了
m_EdtWnd是个文本框、BtnStart和BtnStop是两个按钮,没其它东西了,资源文件就不贴了
class CHostDlg : public CDialog
{
// Construction
public:
CHostDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CHostDlg)
enum { IDD = IDD_HOST_DIALOG };
CEdit m_EdtWnd;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHostDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CHostDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnBtnStart();
afx_msg void OnBtnStop();
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg LRESULT OnHookMsg(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
HostDlg.cpp
void CHostDlg::OnBtnStart()
{
// TODO: Add your control notification handler code here
this->SetCapture();
m_EdtWnd.SetWindowText(_T("单击任意窗体"));
}
void CHostDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
::ReleaseCapture();
POINT pt;
::GetCursorPos(&pt);
HWND hWnd = ::WindowFromPoint(pt);
TCHAR szCaption[128];
::GetWindowText(hWnd, szCaption, 127);
DWORD dwThreadId = ::GetWindowThreadProcessId(hWnd, NULL);
if (dwThreadId != 0)
{
if (SetHook(this->m_hWnd, dwThreadId))
StrCat(szCaption, _T("-钩挂成功"));
else
StrCat(szCaption, _T("-钩挂失败"));
m_EdtWnd.SetWindowText(szCaption);
}
CDialog::OnLButtonUp(nFlags, point);
}
LRESULT CHostDlg::OnHookMsg(WPARAM wParam, LPARAM lParam)
{
POINT pt;
TCHAR szInfo[128];
::GetCursorPos(&pt);
wsprintf(szInfo, "鼠标位置:X:%d Y:%d", pt.x, pt.y);
m_EdtWnd.SetWindowText(szInfo);
return 0;
}
void CHostDlg::OnBtnStop()
{
// TODO: Add your control notification handler code here
UnHook();
m_EdtWnd.SetWindowText(NULL);
}
那些MFC自动生成的我就没贴了
m_EdtWnd是个文本框、BtnStart和BtnStop是两个按钮,没其它东西了,资源文件就不贴了
#15
记得加上ON_MESSAGE(WM_HOOK, OnHookMsg)这句消息映射,这个忘贴了
#16
钻石级的就是牛叉啊,GetModuleFlieName判断一下果然搞定。