花了兩天的時間,終于將其“覺醒”成功。嘎嘎~~~ 當設計1.0 版本的 沒有密碼驗證,心里就一直覺得很不舒服。覺得它不是一個完整的程序,雖然可以鎖定鍵盤、鼠標、屏幕...但卻連最基本的密碼驗證都沒有。這樣的防御形同虛設,那時夠糾結的...現在就看看完善之后的 V2.0 界面吧~~ 感覺舒服多了~~~嘎嘎...先不說它的功能強不強悍 至少它的功能完整的~~
設置界面:
鎖屏界面:
實現原理: 利用HOOK 鉤子使鍵盤失效,利用ClipCursor(&rect); 函數限制鼠標移動的位置,屏蔽一些系統快捷鍵是通過修改注冊表實現的。 WIN鍵是通過結束 explorer.exe 的進程實現屏蔽。同時由于explorer.exe 進程的結束,也激活了注冊表的相關鍵值生效。 鎖定時所顯示的那張圖其實是一個隨屏幕大小而改變的對話框。對話框中加入了一個圖片控件而已。 然后將利用SetWindowPos(&wndTopMost,0,0,w,h,SWP_SHOWWINDOW);將其置頂。
功能: 鎖定【鼠標移動】、 屏蔽【鍵盤輸入】、屏蔽【注銷按鈕】、屏蔽【關機按鈕】、 屏蔽【更改密碼】、屏蔽【任務管理器】、屏蔽【鎖定計算機】、屏蔽【系統快捷鍵】 鎖屏時程序會設定開機自啟動,解屏時刪除開機自啟動,達到未輸入解屏密碼時,即使重啟之后程序仍會鎖屏! 程序附帶自校驗,在一定的程度上防范惡意修改及病毒感染。
缺點: 依靠第三方實現部分功能,不能自己實現...
密碼保存是以明文的形式保存,加密算法的缺陷,導致加密后程序可能會在某些機器上出錯。 而且由于使用了HOOK技術導致某些不負責任的安全軟件誤報為病毒程序.。這很大部分上影響用戶的使用。 沒有使用資源釋放機制,是因為怕用戶誤會本是DLL木馬。所以導致多了一個 HookDll.dll 的文件出現。 由于對MFC不太熟悉,所以密碼驗證方面的代碼寫的有點復雜...雖然這是個小程序,如果是中大型的程序在一定的程度下影響效率。 代碼還是不夠精悍!某些函數定義下顯得不夠規范。. 不能自定義圖像和其顯示的透明度。
以下是 HookDll.dll 源碼: - =========================================================================================================
- #include <windows.h>
- #include <stdio.h>
- #include <TLHELP32.H>
- #pragma comment(linker, "/OPT:NOWIN98")
- #include <shlwapi.h>// 刪除子鍵需要
- #pragma comment(lib, "shlwapi.lib")
- HHOOK g_hMouse;
- HHOOK g_hMouse1;
- #pragma data_seg("MySec")
- HWND g_hand = NULL;
- #pragma data_seg()
- #pragma comment(linker,"/section:MySec,RWS")
- void UnhHook();
- int Reg(int i);// 限制任務管理器
- DWORD Pid;// 當前進程pid
- DWORD WPid;// 激活窗口的pid
- DWORD Process(char Processname[]); // 遍歷進程
- int AUTODel(int Del)
- {
- char Key[]="鎖屏小工具";
- HKEY RegKey;
- if (Del)
- {
- if(RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
- 0, KEY_ALL_ACCESS, &RegKey) != ERROR_SUCCESS)
- return 1;
- if (!RegDeleteValue(RegKey,Key))
- {
- RegCloseKey(RegKey);
- return 1;
- }
- }
- else
- {
- if(RegOpenKeyEx(HKEY_CURRENT_USER, "密碼正確",0, KEY_ALL_ACCESS, &RegKey) == ERROR_SUCCESS)
- {
- SHDeleteKey(HKEY_CURRENT_USER,"密碼正確");
- SHDeleteKey(HKEY_CURRENT_USER,"開機啟動");
- RegCloseKey(RegKey);
- return 0;
- }
- else
- return 1;
- }
- RegCloseKey(RegKey);
- return 0;
- }
- void CALLBACK PasswordCmp(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
- {
- if (!AUTODel(0))
- {
- if (!AUTODel(1))
- MessageBox(0,"刪除自啟動失敗!重啟后可能還會被鎖屏,請用安全工具清除本開機啟動項!","注意",MB_OK|MB_SYSTEMMODAL);
- KillTimer(hWnd,1);// 結束定時
- if (Reg(0))
- MessageBox(0,"解除對windows 安全限制失敗~~~請解除安全軟件對本軟件的攔截!解除攔截后再重新鎖屏后解鎖即可~~","Error",MB_SYSTEMMODAL);
- SendMessage(g_hand,WM_CLOSE,0,0); // 關閉窗口
- UnhHook();
- }
- }
- LRESULT CALLBACK MouseProc(
- int nCode, // hook code
- WPARAM wParam, // message identifier
- LPARAM lParam // mouse coordinates
- )
- {
- return 1;
- }
- LRESULT CALLBACK KeyboardProc(
- int code, // hook code
- WPARAM wParam, // virtual-key code
- LPARAM lParam // keystroke-message information
- )
- {
- /*//調試程序時使用
- if (VK_F2== wParam)
- {
- SendMessage(g_hand,WM_CLOSE,0,0);
- UnhHook();
- if (!AUTODel(1))
- MessageBox(0,"刪除自啟動失敗!重啟后可能還會被鎖屏,請用安全工具清除本開機啟動項!","注意",MB_OK|MB_SYSTEMMODAL);
- if (Reg(0))
- MessageBox(0,"解除對windows 安全限制失敗~~~請解除安全軟件對本軟件的攔截!解除攔截后再重新鎖屏后解鎖即可~~","Error",MB_SYSTEMMODAL);
- }
- */
- // 獲取當前激活窗口的進程PID
- GetWindowThreadProcessId(GetActiveWindow(), &WPid);
- // 與自身比較
- /* VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
- * 0x40 : unassigned
- * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
- *小鍵盤 0 - 9 (0x60 - 0x69)
- *13 回車鍵 || 8 退格鍵*/
- if (WPid == Pid) // 如果當前屬于窗口是本進程 則不屏蔽這些按鍵
- {
- if (wParam >= 0x30 && wParam <=0x5A || wParam >= 0x60 && wParam <= 0x69 || wParam == 13 || wParam == 8)
- {
- if (wParam != 0x40)
- {
- return CallNextHookEx(g_hMouse1, code, wParam, lParam) ;
- }
- }
- }
- return 1;
- }
- void SetHook(HWND hwnd)
- {
- GetWindowThreadProcessId(hwnd, &Pid);
- g_hand=hwnd;// 還是不HOOK 鼠標吧 會有忙狀態~~~
- //g_hMouse = SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("HookDll"),0);
- g_hMouse1 = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("HookDll"),0);
- DWORD ProcessID = Process("explorer.exe");
- HANDLE Proceshandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);
- TerminateProcess(Proceshandle ,1);
- SetTimer(hwnd,1,1,PasswordCmp);// 設置定時器
- if (Reg(1))
- {
- MessageBox(0,"注意!無法限制windows 安全,請解除安全軟件對本軟件的限制~","Error",MB_SYSTEMMODAL);
- }
- }
- void UnhHook()
- {
- //UnhookWindowsHookEx(g_hMouse);
- UnhookWindowsHookEx(g_hMouse1);
- //ClipCursor(NULL); //釋放
- ShellExecute(NULL,"open","explorer.exe",NULL,NULL,SW_SHOW);
- }
- int Reg(int i)
- {
- char Reg[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
- char Regoff[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
- char Regz[] = "DisableTaskMgr";// 屏蔽任務管理器
- char RegLock[] = "DisableLockWorkstation";// 屏蔽鎖定計算機
- char Regnooff[] = "NoLogOff";// 屏蔽注銷
- char Regnoexit[] = "NoClose";// 屏蔽關機
- char RegnoKey[] = "NoWinKeys";// WIN+E、WIN+D、WIN+F、WIN+R等Windows快捷鍵
- //char RegnoRun[] = "RestrictRun";// 禁止允許任何程序
- char Nopassword[] = "DisableChangePassword";// 屏蔽更改密碼
- HKEY hkey,hkeyoff;
- DWORD Zhi=1;
- //if(RegCreateKeyEx(HKEY_CURRENT_USER,Reg,NULL,KEY_ALL_ACCESS ,&hkey))
- if(RegCreateKeyEx(HKEY_CURRENT_USER,Reg,0,0,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hkey,NULL))
- {
- RegCloseKey(hkey);
- return 1;// 創建失敗則 返回1 提示錯誤
- }
- //if(RegCreateKeyEx(HKEY_CURRENT_USER,Regoff,NULL,KEY_ALL_ACCESS ,&hkeyoff))
- if(RegCreateKeyEx(HKEY_CURRENT_USER,Regoff,0,0,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hkeyoff,NULL))
- {
- RegCloseKey(hkeyoff);
- return 1;// 創建失敗則 返回1 提示錯誤
- }
- if (i)
- {
- // 屏蔽任務管理器
- if (RegSetValueEx(hkey,Regz,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkey);
- return 1;//設置失敗則返回1 提示錯誤
- }
- // 屏蔽鎖定計算機
- if (RegSetValueEx(hkey,RegLock,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkey);
- return 1;//設置失敗則返回1 提示錯誤
- }
- // 屏蔽注銷
- if (RegSetValueEx(hkeyoff,Regnooff,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkeyoff);
- return 1;//設置失敗則返回1 提示錯誤
- }
- // 屏蔽關機
- if (RegSetValueEx(hkeyoff,Regnoexit,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkeyoff);
- return 1;//設置失敗則返回1 提示錯誤
- }
- // 屏蔽更改密碼
- if (RegSetValueEx(hkey,Nopassword,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkey);
- return 1;//設置失敗則返回1 提示錯誤
- }
- // 屏蔽系統快捷鍵
- if (RegSetValueEx(hkeyoff,RegnoKey,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkeyoff);
- return 1;//設置失敗則返回1 提示錯誤
- }
- RegCloseKey(hkeyoff);
- RegCloseKey(hkey);
- /*// 只修改內存 重啟后會失效 避免重啟后鎖屏程序無法運行
- if(RegCreateKeyEx(HKEY_CURRENT_USER,Regoff,0,0,REG_OPTION_VOLATILE,KEY_ALL_ACCESS,NULL,&hkeyoff,NULL))
- {
- RegCloseKey(hkeyoff);
- return 1;// 創建失敗則 返回1 提示錯誤
- }
- if (RegSetValueEx(hkeyoff,RegnoRun,0,REG_DWORD,(CONST BYTE*)&Zhi,sizeof(Zhi)))
- {
- RegCloseKey(hkeyoff);
- return 1;//設置失敗則返回1 提示錯誤
- }
- RegCloseKey(hkeyoff);
- */return 0;// 如果找到則返回0 提示成功
- }
- else// 解除限制
- {
- // 解除任務管理器限制
- if (RegDeleteValue(hkey,Regz))
- return 1;
- // 解除鎖定計算機限制
- if (RegDeleteValue(hkey,RegLock))
- return 1;
- // 解除鎖定注銷
- if (RegDeleteValue(hkeyoff,Regnooff))
- return 1;
- // 解除鎖定注銷
- if (RegDeleteValue(hkey,Nopassword))
- return 1;
- // 解除鎖定關機
- if (RegDeleteValue(hkeyoff,Regnoexit))
- return 1;
- // 解除系統快捷鍵限制
- if (RegDeleteValue(hkeyoff,RegnoKey))
- return 1;
- /*// 解除允許程序的權限
- if (RegDeleteValue(hkeyoff,RegnoRun))
- return 1;
- */return 0;
- }
- }
- DWORD Process(char Processname[])
- {
- PROCESSENTRY32 ProcessEnt = {0};
- HANDLE hPrOhandle;
- ProcessEnt.dwSize = sizeof(PROCESSENTRY32);
- hPrOhandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
- BOOL bRet = Process32First(hPrOhandle,&ProcessEnt);
- while (bRet)
- {
- if (strcmpi(Processname,ProcessEnt.szExeFile) == 0)
- {
- return ProcessEnt.th32ProcessID;
- }
- bRet = Process32Next(hPrOhandle,&ProcessEnt);
- }
- return 1;
- }
- 以下是 鎖定小工具 V2.0.exe 源碼:(由于是MFC設計的界面 代碼無法全部給出 只給出關鍵的代碼)
- =========================================================================================================
- 定義兩個全局變量
- HWND g_hwnd; // 傳遞給DLL用的
- int LockTime = 3;// 輸入密碼錯誤三次 則凍結 3 分鐘
- 程序加載時:BOOL CMyDlg::OnInitDialog()
- HKEY RegKey;
- if(RegOpenKeyEx(HKEY_CURRENT_USER, "開機啟動",0, KEY_ALL_ACCESS, &RegKey) != ERROR_SUCCESS)
- {
- CLock dlg;
- dlg.DoModal(); // 創建 設置 子窗口界面
- }
- else // 否則直接鎖屏
- RegCloseKey(RegKey);
- g_hwnd = m_hWnd; // 將本窗口的句柄傳遞給DLL
- // 創建線程 進行HOOK
- CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)HOOK,NULL,NULL,NULL);
- DWORD WINAPI HOOK()
- {// 去掉鼠標忙狀態
- GetInputState();
- PostThreadMessage(GetCurrentThreadId(),NULL,0,0);
- MSGmsg;
- GetMessage(&msg, NULL, NULL, NULL);
- SetHook(g_hwnd); // HOOK
- RECT rect; //定義個矩形
- /******鼠標只能在這個范圍內移動******/
- unsigned int w = ::GetSystemMetrics(SM_CXSCREEN);
- unsigned int h = ::GetSystemMetrics(SM_CYSCREEN);
- rect.bottom= h/3;
- rect.top= h/3;
- rect.right = w-9;
- rect.left = w-9;
- while(1)
- { // 每隔100 毫秒鎖定一次,看你吖的移動鼠標啦~~~~
- ClipCursor(&rect);
- Sleep(100);
- }
- return 0;
- }
- // 界面透明化
- SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);HINSTANCE hInst = LoadLibrary("User32.DLL");
- if(hInst)
- {
- typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
- MYFUNC fun = NULL;
- //取得SetLayeredWindowAttributes函數指針
- fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
- if(fun)fun(this->GetSafeHwnd(),RGB(255,255,255),240,2);
- FreeLibrary(hInst);
- }
- /*第二個參數是 設置透明色 第三個參數是 設置不透明度 255就是不透明 0就是全透明 第四個參數 是一個方式選擇 1表示讓第二個參數的顏色透明此時第三個參數無效 2表示全窗口透明此時第二個參數無效 */
- unsigned int w = ::GetSystemMetrics(SM_CXSCREEN); // 獲取屏幕寬
- unsigned int h = ::GetSystemMetrics(SM_CYSCREEN); // 獲取屏幕高
- SetWindowPos(&wndTopMost,0,0,w,h,SWP_SHOWWINDOW); // 進行置頂操作
- CWnd *pWnd;
- pWnd = GetDlgItem( IDC_STATIC ); //獲取控件指針,IDC_STATIC為控件ID號
- pWnd->MoveWindow( CRect(0,22,w,h) ); // 移動 重設置控件為 w寬 h高
- SetDlgItemText(IDC_Password,"");
- pWnd = GetDlgItem( IDC_Password );
- pWnd->MoveWindow( CRect(0,0,w,22) ); // 移動 重設置密碼控件為 w寬 h高
- 【鎖定】按鈕觸發的代碼:
- void CLock::OnLockPM()
- {
- CString temp;
- char Password[MAX_PATH];
- char tmp[MAX_PATH];
- int Cs = 1; // 測試使用
- GetDlgItemText(IDC_SPProssword,temp);
- strcpy(Password,temp);
- GetDlgItemText(IDC_QRProssword,temp);
- strcpy(tmp,temp);
- int len = strlen(Password)-1;
- for (int i=0; i<=len; i++)
- {
- if (Password[i] >= 0x30 && Password[i] <=0x5A || Password[i] >= 0x60 && Password[i] <= 0x69)
- {
- if (Password[i]!= 0x40)
- {
- Cs = 1;
- }
- }
- else
- Cs = 0;
- }
- if (Cs)
- {
- if ( strcmp(Password,tmp) == 0 && strlen(Password)!=0 && strlen(tmp)!=0)
- {
- if (!AUTO(1,NULL))// 開機啟動
- AfxMessageBox("由于權限原因,添加開機啟動項失敗!重啟后將無法鎖屏!請解除安全軟件對本程序的攔截");
- if(!AUTO(2,Password))// 存儲密碼
- {
- AfxMessageBox("無法驗證密碼~ 程序將退出~");
- exit(1);
- }
- PostMessage(WM_CLOSE);
- }
- else
- {
- if ( strlen(Password)==0 && strlen(tmp)==0 )
- AfxMessageBox("密碼不允許為空!");
- else
- AfxMessageBox("兩次輸入的密碼不匹配!");
- SetDlgItemText(IDC_SPProssword,"");// 清空
- SetDlgItemText(IDC_QRProssword,"");// 清空
- GetDlgItem(IDC_SPProssword)-> SetFocus(); // 設置光標在第一個文本框里
- }
- }
- else
- AfxMessageBox("鎖屏密碼只允許是 數字 或 字母 ~不允許包含其他的字符!");
- }
- 【使用上一次設置的密碼】按鈕觸發的代碼:
- void CLock::onPassword()
- {
- if (!AUTO(1,NULL))// 開機啟動
- AfxMessageBox("由于權限原因,添加開機啟動項失敗!重啟后將無法鎖屏!請解除安全軟件對本程序的攔截");
- PostMessage(WM_CLOSE);
- }
- 【刪除上一次設置的密碼】按鈕觸發的代碼:
- void CLock::OnDelPassword()
- {
- // TODO: Add your control notification handler code here
- if (!SHDeleteKey(HKEY_CURRENT_USER,"鎖屏小工具"))
- {
- GetDlgItem(IDC_Password)->ShowWindow(SW_HIDE);// 顯示按鈕
- GetDlgItem(IDC_DelPassword)->ShowWindow(SW_HIDE);// 顯示按鈕
- GetDlgItem(IDC_TS)->ShowWindow(SW_SHOW);
- AfxMessageBox("清除成功!");
- }
- }
- 解鎖時 回車觸發的代碼
- void CMyDlg::OnLand()
- {
- // TODO: Add your control notification handler code here
- char Ts[]="敖菜像焙涕扎救蜜昂睜到廢墻臍兆狹瘟幼敖菜像---";
- if (Scan(Ts))
- MessageBox(Ts,NULL,MB_OK|MB_SYSTEMMODAL);
- CString tmp;
- char Password[MAX_PATH]={0};
- char WBPassword[MAX_PATH]={0};
- GetDlgItemText(IDC_Password,tmp);
- strcpy(WBPassword,tmp);
- HKEY RegKey;
- LPBYTE Size=new BYTE [MAX_PATH]; // 要足夠大
- DWORD type=REG_BINARY;
- DWORD cbData=256;
- if(RegOpenKeyEx(HKEY_CURRENT_USER, "鎖屏小工具",
- 0, KEY_ALL_ACCESS, &RegKey) == ERROR_SUCCESS)
- {
- if ( RegQueryValueEx(RegKey,"password",NULL,&type,Size,&cbData) == ERROR_SUCCESS)
- {
- strcpy(Password,(char *)Size);// 利用DQCDEXE 全局變量通知
- delete []Size;
- }
- else
- AfxMessageBox("讀取密碼失敗!");
- }
- else
- AfxMessageBox("打開指定的注冊表失敗!");
- if (strlen(WBPassword)==0)
- AfxMessageBox("請輸入解屏密碼!");
- else
- {
- if (strcmp(WBPassword,Password) == 0)
- {
- if (RegCreateKeyEx(HKEY_CURRENT_USER,"密碼正確",0,0,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&RegKey,NULL) == ERROR_SUCCESS)
- {
- RegCloseKey(RegKey);
- }
- else
- AfxMessageBox("修改注冊表失敗,暫時無法解鎖");
- }
- else
- {
- char Test[35];
- LockTime--;
- if (LockTime == 0)
- {
- CEdit *pEdit = (CEdit *)GetDlgItem(IDC_Password);
- pEdit-> SetPasswordChar(0);// 去除密碼屬性
- GetDlgItem(IDC_Password)->EnableWindow(0);
- GetDlgItem(IDC_BUTTON1)->EnableWindow(0);
- SetDlgItemText(IDC_Password,"對不起,由于您連續輸入密碼錯誤 3 次,三分鐘內不允許輸入密碼!");
- AfxMessageBox("對不起,由于您連續輸入密碼錯誤 3 次,三分鐘內不允許輸入密碼!");
- Sleep(180000);// 掛起三分鐘
- GetDlgItem(IDC_Password)->EnableWindow(1);
- GetDlgItem(IDC_BUTTON1)->EnableWindow(1);
- GetDlgItem(IDC_Password)-> SetFocus(); // 設置光標在第一個文本框里
- pEdit-> SetPasswordChar('*');// 設置密碼屬性
- LockTime=3;
- }
- else
- {
- sprintf(Test,"輸入密碼錯誤!您還有 %d 次機會",LockTime);
- AfxMessageBox(Test);
- }
- SetDlgItemText(IDC_Password,"");
- }
- }
- }
復制代碼
|