在編寫程式的過程中,我們有時需要實現遮蔽作業系統一些熱鍵的功能,如(ctrl+delete+alt,ctrl+shift+esc等)。網路上有很多關於這方面的資料,總結了一下,一般有如下兩個方法:
1. 通重載入低階鍵盤鉤子(wh_keyboard_ll)截獲大部分的系統熱鍵,並遮蔽它。這個方法比較簡單,但有個缺陷,那就是對ctrl+alt+delete沒有辦法。
2. 通過遠端注入dll到winlogon程序,修改winlogon桌面下sas視窗的**函式,從而捕獲該視窗的wm_hotkey訊息,並遮蔽它,可以實現遮蔽ctrl+delete+alt。這個方法相對複雜,可以解決第一點中存在的問題,但是也有缺陷,那就是除了ctrl+delete+alt外,大多數的其它系統熱鍵,(包括alt+tab,ctrl+esc及左右兩個windows鍵)都無法遮蔽。
所以如果我們的程式需要遮蔽大量的系統熱鍵,就應當將以上兩個方法結合起來使用。dll注入有很多好處,包括可以實現對我們所執行程序的隱藏,這非常有用。當我們的程序執行後,遮蔽掉了系統熱鍵,當然不想使用者隨便在程序管理器裡面就kill掉,因此將以上兩個方法結合的辦法就是把**通通寫到dll裡面,然後再一起注入到winlogon程序中。
對於上面所講的第二點,注入到winlogon程序,沒問題,可以很好的完成功能(網上有很多相關的文章及**)。但對於第一點,如果在乙個gui程式中載入鉤子,也沒有問題。但現在載入的物件是winlogin程序,這個程序很特殊,它不是gui程序,也不在系統應用程式所處的default桌面下,因此在這個程序中載入鉤子,需要注意以下幾點:
1. 在需要注入的dll**中的dll_process_attach後面開啟乙個新執行緒,並在該執行緒中實現修改sas視窗**函式的**以及設定低階鍵盤鉤子。
2. 由於鉤子所在的執行緒為非gui執行緒,因此,
必須在該執行緒成功設定鉤子以後主動接收並分發收到的訊息,否則鉤子將不會鉤到任何訊息:
msg msg;
while(getmessage(&msg, null, 0, 0))
3. 由於該執行緒建立時預設與winlogon同屬乙個桌面(winlogon桌面),而其它包括explorer.exe在內的gui程式都處在default桌面,在windows中規定程式只能獲得針對同一桌面上建立的視窗訊息。所以,要讓該執行緒能接收到使用者在default桌面下操作所產生的訊息,必須在該執行緒中使用如下**將它的桌面設定為default桌面:
hdesk hdesk = opendesktop("default",0,false,maximum_allowed);
setthreaddesktop(hdesk);
closehandle(hdesk);
#define _win32_winnt 0x0500 //use wh_keyboard_ll
#include
#include
//sas window控制代碼
hwnd hsaswnd = null;
//原有sas window**函式位址
farproc foldproc = null;
//起遮蔽作用的新sas window**函式
lresult callback saswindowproc(hwnd hwnd,uint umsg,wparam wparam,lparam lparam);
//列舉所有窗體控制代碼的**函式
bool callback enumwindowsproc(hwnd hwnd,lparam lparam);
//dll所建立執行緒的控制代碼
handle hthread = null;
//dll所建立執行緒的id
dword dwthreadid = 0;
//dll所建立執行緒的執行緒函式
dword winapi threadfunc();
//_h鉤子控制代碼
hhook hhook = null;
//_h低階鍵盤鉤子**函式
lresult callback keyboardproc(int,wparam,lparam);
//對外輸出字串
char szoutput[36];
bool apientry dllmain(handle hmoudle, dword dwreason, lpvoid lpreserved)
outputdebugstring("鍵盤鉤子成功取消");
}terminatethread(hthread,1);
closehandle(hthread);
break;
case dll_thread_attach:
break;
case dll_thread_detach:
break;
}return true;}
//dll所建立執行緒的執行緒函式
dword winapi threadfunc()
closehandle(hdesk);
//_h同一桌面上程序之間只能傳送視窗訊息。無法跨程序與其他桌面傳送它們。
//_h同樣,windows訊息是限制應用程式定義掛鉤。
//_h特定桌面中執行的程序掛鉤過程將〈〈只獲得針對同一桌面上建立視窗訊息。〉〉
//_h詳見
//_h設定低階鍵盤鉤子,遮蔽非sas window的熱鍵
//_h需要#define _win32_winnt 0x0500
hhook = setwindowshookex(wh_keyboard_ll,keyboardproc,getmodulehandle(null),0);
if (hhook == null)
outputdebugstring("鍵盤鉤子成功設定");
//_h在非gui執行緒中使用訊息鉤子必須主動接收並分發收到的訊息
msg msg;
while(getmessage(&msg, null, 0, 0))
return 1;}
//列舉所有窗體控制代碼的**函式
bool callback enumwindowsproc(hwnd hwnd,lparam lparam)
return true;}
//起遮蔽作用的新sas window**函式
lresult callback saswindowproc(hwnd hwnd,uint umsg,wparam wparam,lparam lparam)
//ctrl + shift + esc組合鍵,這個組合鍵將顯示任務管理器,可根據需要是否遮蔽。
else if(isctrldown && isshiftdown && wkey == vk_escape)}
return callwindowproc((wndproc)foldproc,hwnd,umsg,wparam,lparam);}
//_h低階鍵盤鉤子**函式
lresult callback keyboardproc(int ncode,wparam wparam,lparam lparam)
//遮蔽alt+tab
else if ((p->vkcode == vk_tab) && ((p->flags & llkhf_altdown) != 0))
//遮蔽alt+esc
else if ((p->vkcode == vk_escape) && ((p->flags & llkhf_altdown) != 0))
//遮蔽ctrl+esc
else if ((p->vkcode == vk_escape) && ((getkeystate(vk_control) & 0x8000) != 0))
//遮蔽ctrl+shift+esc,(sas window中也已遮蔽)
else if ((p->vkcode == vk_escape) &&
((getkeystate(vk_control) & 0x8000) != 0) &&
((getkeystate(vk_shift) & 0x8000) != 0))
//遮蔽左右windows鍵
else if (p->vkcode == vk_lwin || p->vkcode == vk_rwin)
//此處無法遮蔽ctrl+alt+del,已在sas window中遮蔽
else if ((p->vkcode == vk_delete) &&
((getkeystate(vk_control) & 0x8000) != 0) &&
((getkeystate(vk_menu) & 0x8000) != 0 ))
return 1;
break;}}
return callnexthookex(hhook,ncode,wparam,lparam);
}
C 遮蔽系統熱鍵
一般來說會用到hook 鉤子 即獲取系統的按鍵或者滑鼠動作,然後在系統響應之前執行自定義動作,或者直接截斷這個訊息,這就是遮蔽系統熱鍵的原理了。首先要呼叫作業系統的dll檔案,先引入命名空間 using system.runtime.interopservices 呼叫作業系統動態鏈結庫的方法 dl...
關於遮蔽右鍵的方法總結
1 stage.showdefaultcontextmenu false 可以減少選單,只是顯示重繪 除錯 設定 全域性 關於 2 11.2右鍵選單可以遮蔽,只需監聽right click然後什麼都不做即可 3 自定義右鍵 只剩兩項 var menu contextmenu new contextm...
PHP遮蔽錯誤的方法總結
1 遮蔽法 在php中乙個抑制錯誤的符號,即便是你開啟了報錯功能,只要在錯誤語句之前加上 符號,便可遮蔽了錯誤資訊。使用 抑制錯誤之前,會出現乙個警告錯誤。2 error reporting遮蔽法 在php檔案開始之前,我們可以加上這樣一句話errosjkfnkor reporting 0 這個函式...