阻止Spy++之类的工具捕捉软件窗口
来源:互联网 发布:dom编程艺术 编辑:程序博客网 时间:2024/05/13 10:43
Spy++之类的程序一般通过API函数WindowFromPoint和ChildWindowFromPoint来获取指定位置的窗口句柄。拦截一下WindowFromPoint函数,如果捕捉到的是自己程序的窗口,而且实施捕捉的进程不是自己程序的进程,那就直接返回NULL(这样自己的程序捕捉自己的窗口就不会受影响).拦截API我直接用微软的Detour库,使用起来方便.
由于是拦截所有进程地址空间的WindowFromPoint函数,我借助于全局WH_SHELL钩子,因此拦截操作放在一单独的DLL项目中.先封装一下Detour操作CInterceptSpyFun类:
class CInterceptSpyFun{private: //是否已经拦截 BOOL m_bIntercepted;public: //保存要屏蔽WindowFromPoint函数的进程ID static DWORD m_dwValidProcessID; public: CInterceptSpyFun( ); ~CInterceptSpyFun( ); BOOL IsIntercepted() { return this->m_bIntercepted; } /* * 拦截操作 * dwValidProcessID: 待屏蔽WindowFromPoint函数的进程ID * 返回拦截成功与否 */ BOOL Intercept( DWORD dwValidProcessID ); /* * 取消拦截,还原成原先的操作 */ void UnIntercept();};
DWORD CInterceptSpyFun::m_dwValidProcessID = 0;//让Real_WindowFromPoint指针指向实际上的WindowFromPoint函数地址DETOUR_TRAMPOLINE( HWND WINAPI Real_WindowFromPoint( POINT pt ), WindowFromPoint );/** 自定义WindowFromPoint函数的处理*/HWND WINAPI Mine_WindowFromPoint( POINT pt ){ //调用实际上的WindowFromPoint函数,取得窗口句柄 HWND hWnd = Real_WindowFromPoint( pt ); //获取窗口所属的进程ID DWORD dwProcessID(0); ::GetWindowThreadProcessId( hWnd, &dwProcessID ); if( ( CInterceptSpyFun::m_dwValidProcessID == dwProcessID ) && ( ::GetCurrentProcessId() != CInterceptSpyFun::m_dwValidProcessID ) ) { //如果窗口属于指定的进程并且是被不是指定进程的其他进程调用WindowFromPoint访问时,返回NULL return NULL; } return hWnd;}CInterceptSpyFun::CInterceptSpyFun( ){ m_bIntercepted = FALSE;}CInterceptSpyFun::~CInterceptSpyFun( ){}BOOL CInterceptSpyFun::Intercept( DWORD dwValidProcessID ){ CInterceptSpyFun::m_dwValidProcessID = dwValidProcessID; //Detour库拦截处理 m_bIntercepted = DetourFunctionWithTrampoline( (PBYTE)Real_WindowFromPoint, (PBYTE)Mine_WindowFromPoint ); return m_bIntercepted;}void CInterceptSpyFun::UnIntercept(){ if( m_bIntercepted ) { //取消拦截 DetourRemove( (PBYTE)Real_WindowFromPoint,(PBYTE)Mine_WindowFromPoint ); m_bIntercepted = FALSE; }}
dwValidProcessID(要拦截WindowFromPoint函数的进程ID)需要在LoadLibrary之后,安装钩子之前传递,并且需要保存到共享节中以达到在所有的进程中数据共享的目的.
#pragma data_seg(".unspy")
HHOOK hHook = NULL;
DWORD dwValidProcessID = 0;
#pragma data_seg()
#pragma comment(linker,"/section:.unspy,rws")
HOOK句柄和dwValidProcessID 都保存到共享节”.unspy”中。
设置dwValidProcessID 的导出函数:
extern"C" __declspec( dllexport ) void SetValidProcessID( DWORD dwProcessID )
{
dwValidProcessID = dwProcessID;
}
声明拦截类的全局变量:
CInterceptSpyFun interceptSpy;
HMODULE hDllModule = NULL; //保存DLL模块句柄
SHELL钩子处理:
LRESULT CALLBACK CustomShellProc (int nCode, WPARAM wParam, LPARAM lParam){ if( !interceptSpy.IsIntercepted() ) { //拦截API interceptSpy.Intercept( dwValidProcessID ); } return ::CallNextHookEx( hHook, nCode, wParam, lParam );}extern"C" __declspec( dllexport ) void InstallHook( ){ hHook = ::SetWindowsHookEx( WH_SHELL , CustomShellProc ,(HINSTANCE)hDllModule, 0 );}extern"C" __declspec( dllexport ) void UninstallHook(){ if( hHook != NULL ) { ::UnhookWindowsHookEx( hHook ); } hHook = NULL;}
取消拦截操作应在卸载DLL的时候:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
hDllModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
interceptSpy.UnIntercept();
}
break;
}
return TRUE;
}
至此,DLL部分已经完成.在需要屏蔽WindowFromPoint函数的程序中需加载该DLL,调用DLL的SetValidProcessID,将当前的进程ID传入,随后安装钩子:
m_hInstance = ::LoadLibrary(_T("AvoidSpyLib.dll"));
if ( m_hInstance == NULL )
{
::MessageBox(NULL,_T("LoadLibrary Failed"),_T(""),MB_OK);
}
if( m_hInstance == NULL )
return 0;
typedef void (*PSetValidProcessID)( DWORD dwProcessID );
PSetValidProcessID pSetFunc;
pSetFunc = (PSetValidProcessID)::GetProcAddress( m_hInstance , "SetValidProcessID");
if ( pSetFunc != NULL )
{
(*pSetFunc)( ::GetCurrentProcessId() );
}
typedef void (*PInstallHook)( );
PInstallHook pInstallFunc;
pInstallFunc = (PInstallHook)::GetProcAddress( m_hInstance , "InstallHook");
if ( pInstallFunc != NULL )
{
(*pInstallFunc)();
}
//卸载钩子
if( m_hInstance != NULL )
{
typedef void (*PUninstallHook)( );
PUninstallHook pFunc;
pFunc = (PUninstallHook)::GetProcAddress( m_hInstance , "UninstallHook");
if ( pFunc != NULL )
{
(*pFunc)();
}
::FreeLibrary( m_hInstance );
}
全部完工,运行了一下,呵呵,和360软件的效果一样,Spy++再也捕捉不到界面的任何东西了.
- 阻止Spy++之类的工具捕捉软件窗口
- 阻止Spy++之类的工具捕捉软件窗口
- 阻止Spy++之类的工具捕捉软件窗口
- 阻止SPY++类似的程序捕捉软件窗口
- Spy++的搜索窗口程序
- spy++捕捉进程消息
- 捕捉桌面上的窗口信息
- 捕捉桌面上的窗口信息
- VC自带的工具SPY++使用
- VC自带的工具SPY++使用
- Flying 模仿Spy++的一个工具
- JavaScript捕捉事件和阻止冒泡事件的探索
- Qt捕捉窗口关闭事件与信号的捕捉
- Qt捕捉窗口关闭事件与信号的捕捉
- Qt捕捉窗口关闭事件与信号的捕捉
- Qt捕捉窗口关闭事件与信号的捕捉
- 捕捉窗口的关闭与刷新
- 捕捉窗口句柄的API函数
- LeetCode数据库题解&&sql相关知识总结
- rails常用验证方法
- 操作系统(十)——设备管理
- 浅谈Android平台物理内存读写漏洞
- thinkphp+ajax+jquery异步实现加载更多
- 阻止Spy++之类的工具捕捉软件窗口
- 杭州电子科技大学ACM-1001
- Node.JS及JS de一些语法
- 【算法题】一次遍历单向链表找到中间节点
- CSDN-markdown使用说明
- iOS Provisioning Profile(Certificate)与Code Signing详解
- 什么是Liferay
- 嵌入式软件开发培训笔记——Java第一天(开发环境搭建、入门引导)
- JAVA Swing 如何自定义Tooltip