花了两天的时间,终于将其“觉醒”成功。嘎嘎~~~ 当设计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,"");
- }
- }
- }
复制代码
|