日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

令人头痛的WH_CBT钩子,使窗口前置——泪水+汗水的赞歌

發布時間:2024/1/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 令人头痛的WH_CBT钩子,使窗口前置——泪水+汗水的赞歌 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、工作中遇到一個問題:

1、需要讓某個特定的窗口不被最小化、不被阻擋、不失去焦點(因為有輸入);

2、由某個服務或進程來自動篩選和控制。

本來覺得用幾個windows API就OK了,誰知道弄了好長好長的時間,崩潰了N次,直到現在..............依舊不敢100%確定,唉!

二、思路

1、FindWindow而后前置SetForegroundWindow

——總感覺似乎不妥,野蠻暴力,還得檢索window句柄列表

2、插個全局鉤子,自行判斷是否前置

——感覺好一點,沒那么暴力了,不過問題來了:用什么鉤子?

三、實踐

1、找啊找,找遍了整個屋子,終于找著了這本《阿里波特》——HCBT_CREATEWND,可以監視窗口創建——心花怒放!

——于是開始了一周的調試——注定要燒腦到死——跑偏了。

2、失敗!失敗!失敗.........!

3、終于在崩潰前夕,不經意間發現了有個叫HCBT_ACTIVATE的家伙——她居然在燈火闌珊處好久了!小試一下,居然比那個桀驁不馴的HCBT_CREATEWND乖巧多了!不會分辨不清窗口和菜單、不會去分辨對話框窗口........,愛死你了!

好吧,就你了!

4、天真地認為花兩小時調試一下就OK了..............圖樣圖森破

5、要么找不到句柄1428,要么126、193.............

6、又一次在崩潰的邊緣發現她還有一閨蜜——LoadLibraryEx,那個LoadLibrary已經被Win7封印了!(開發環境win10卻好好的)好吧,有新歡就新歡吧,聽你的!

噢,差點忘了#pragma data_seg,也如影隨形,照顧不周,她就會搗亂,好吧,咱倆不熟,先學習研究下.......

7、啊?程序不能移植?這沒有道理啊?肯定是目標機缺少運行庫環境!我裝——

8、VC++運行庫合集——利刃吶!

——什么!還不行?!

9、...................................我還是程序員嗎?

10、再去崩潰的邊緣溜達溜達吧..............3、4天了,怎么跟人交差啊!

11、傳說中有個叫“Release版本”的朋友,可我一直沒有聯系過!不經意間,他似乎.............

12、試試看吧,也許呢?...............朋友就是朋友啊,夠意思!

13、哈哈,鉤子跑起來了,貌似成功了!

14、..................怎么?鉤子使性子?一會管用一會不管用?

15、家法伺候中.....................

16、我知道了不是你的錯,你是32位的,還得有64位的,還得有32和64位的注入程序——好吧,給你倆克隆個雙胞胎兄弟!——等等,我先研究下clone技術.................

17、什么?克隆了還不老實?...............................

——一會讓我的VS窗口前置,一會讓我的瀏覽器前置,當我的strstr函數不存在啊?

18、這下百度幫不了了,怎么回事?宣告是系統bug嗎?

19、找bug,找bug,找bug,找bug,找bug,找bug,找bug,找bug,找bug,找......................

20、天道酬勤啊,原來是你——局部變量const,真不明白strstr函數就那么矯情,非要const參數干嗎,可傳個非const似乎也行........

21、于是經過很久很久的多次崩潰,鉤子就成了下面這個樣子——

#include <windows.h> #include <iostream> #include <Psapi.h> #include <string> //#define _WIN32_WINNT 0x500using namespace std; #pragma data_seg("SharedDataName") HHOOK hooker=NULL; HWND ghwnd = NULL; DWORD pid = -1; //string TargetName = "AppFiles"; const char* target = "AppFiles";//TargetName.c_str(); #pragma data_seg() #pragma comment(linker,"/section:SharedDataName,rws")HWND privateHwnd;extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam); extern "C" __declspec(dllexport) HHOOK setHookDll(); extern "C" __declspec(dllexport) BOOL unHookDll(); extern "C" __declspec(dllexport) void getPid(DWORD id); extern "C" __declspec(dllexport) void getPName(string name);BOOL APIENTRY DllMain(HMODULE hModule/* hModule */, DWORD ul_reason_for_call, LPVOID /* lpReserved */lpReserved) {switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:privateHwnd = NULL;break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE; }void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime);extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {if (nCode<0)return CallNextHookEx(hooker, nCode, wParam, lParam);tagMSG* msg;msg = (tagMSG*)lParam;switch (nCode){case HC_ACTION:break;case HCBT_CREATEWND:break;case HCBT_ACTIVATE:{HWND currentHwnd = (HWND)wParam;DWORD processID = NULL;GetWindowThreadProcessId(currentHwnd, &processID);HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);//LPSTR procName;TCHAR procName[MAX_PATH] = { 0 };GetProcessImageFileName(hProcess, procName, MAX_PATH);char* source = procName;if (strstr(source, target) != NULL){ghwnd = currentHwnd;privateHwnd = currentHwnd;KillTimer(currentHwnd, 1);//MessageBox(currentHwnd, source, target, MB_OK);SetTimer(currentHwnd, 1, 1000, (TIMERPROC)TimerProc);}break;}default:break;}return CallNextHookEx(hooker, nCode, wParam, lParam); }extern "C" __declspec(dllexport) HHOOK setHookDll() {hooker = SetWindowsHookEx(WH_CBT, HookProc, (HINSTANCE)GetModuleHandle("winhook.dll"), 0);//64位 用winhook64.dllreturn hooker; }extern "C" __declspec(dllexport) BOOL unHookDll() {KillTimer(privateHwnd, 1);bool unHk = UnhookWindowsHookEx(hooker);return unHk; }extern "C" __declspec(dllexport) void getPid(DWORD id) {pid = id; }extern "C" __declspec(dllexport) void getPName(string name) {//TargetName = name; }void _stdcall CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime) {SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOMOVE);//BringWindowToTop(currentHwnd);//SetFocus(currentHwnd);//SetActiveWindow(currentHwnd);PostMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, NULL);HWND hForeWnd = ::GetForegroundWindow();DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd, NULL);DWORD dwCurID = ::GetCurrentThreadId();::AttachThreadInput(dwCurID, dwForeID, TRUE);SetForegroundWindow(hWnd);PostMessage(hWnd, WM_SETFOCUS, NULL, NULL);return; }
22、不過在前置窗口并獲取焦點的問題上倒數第三行的postmessage,以及前面的SetFocus似乎不怎么管用,在實際體驗中感覺還是有小問題,我是沒著了。

四、小記

1、微軟前置個窗口怎么就那么累呢?

2、指定窗口獲取個焦點怎么就那么費勁呢?死活就是不認。

3、非共享代碼段似乎也會出問題,但不確認。

總結

以上是生活随笔為你收集整理的令人头痛的WH_CBT钩子,使窗口前置——泪水+汗水的赞歌的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。