如果想实现对windows某个窗口的操作,首先需要拿到这个窗口的窗口句柄,实际上拿到了窗口句柄以后就可以对窗口做任何修改,这里用最大化和最小化来举例子。
Windows Hook
1,《逆向工程核心原理》第三部分,Dll注入介绍了使用SetWindowsHookEx函数来拦截窗口事件,SetWindowsHookEx可以在每个进程中插入指定的Dll函数,此dll可以拿到运行程序的所有Windows事件,因此可以对Windows事件进行拦截、修改。
2,查看 微软API 可以看到(如下图)
细节
1,x86的dll只能hook住x86程序,x64的dll只能hook住x64的程序
2,调用两次SetWindowsPos函数,第一次的是设置大小,和初始位置,第二次是禁用窗口拖动。
SetWindowPos(currentHwnd, HWND_TOPMOST, 0, 0, g_screenPhysicsWidth, g_screenPhysicsHeight, SWP_SHOWWINDOW );
SetWindowPos(currentHwnd, HWND_TOPMOST, 0, 0, g_screenPhysicsWidth, g_screenPhysicsHeight, SWP_SHOWWINDOW|SWP_NOMOVE);
3,case HCBT_ACTIVATE比较稳定。
4,设置窗口样式,只能删除使用原生windows窗口的,比如 visual studio、vscode等自己开发的最大化最小化,就没法删除了。
LONG lStyle = GetWindowLong(currentHwnd, GWL_STYLE);
lStyle &= ~( WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
SetWindowLong(currentHwnd, GWL_STYLE, lStyle);
核心代码
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode<0)
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
if (nCode >= 0){
switch (nCode){
case HCBT_ACTIVATE:
{
HWND currentHwnd = (HWND)wParam;
if (isTargetProcess(currentHwnd)){
SetWindowPos(currentHwnd, HWND_TOPMOST, 0, 0, g_screenPhysicsWidth, g_screenPhysicsHeight, SWP_SHOWWINDOW );
SetWindowPos(currentHwnd, HWND_TOPMOST, 0, 0, g_screenPhysicsWidth, g_screenPhysicsHeight, SWP_SHOWWINDOW|SWP_NOMOVE);
//ShowWindow(currentHwnd, SW_MAXIMIZE);
LONG lStyle = GetWindowLong(currentHwnd, GWL_STYLE);
lStyle &= ~( WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
SetWindowLong(currentHwnd, GWL_STYLE, lStyle);
}
break;
}
case HCBT_MOVESIZE:{
HWND currentHwnd = (HWND)wParam;
if (isTargetProcess(currentHwnd)){
return 1;
}
break;
}
case HCBT_MINMAX:{
HWND currentHwnd = (HWND)wParam;
if (LOWORD(lParam) == SW_MINIMIZE || LOWORD(lParam) == SW_RESTORE) {
if (isTargetProcess(currentHwnd)){
return 1;
}
}
break;
}
default:
break;
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
参考:
令人头痛的WH_CBT钩子,使窗口前置——泪水+汗水的赞歌 https://blog.csdn.net/singshinesong/article/details/52764446