通过服务器程序对被控端发送一个命令包,被控端接受后,锁定键盘鼠标,并黑屏。
其中鼠标锁定可以用钩子,黑屏可以弹出黑色窗口实现,这没问题。关键是锁定键盘时,按ctrl+alt+del键没用,而且按num lock时,num lock灯也不闪。请教各位,这种能把num lock灯也锁住的方式,到底是如何实现的。

解决方案 »

  1.   


    HHOOK g_kb_hook = SetWindowsHookEx (WH_KEYBOARD_LL,kb_proc,GetModuleHandle (NULL),0);
    LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)
    {
    return 1;
    }
      

  2.   

    在系统启动之后, ctrl + alt + delete 这个消息就已经被 winlogon 注册了我们的程序不管采用啥方法也拦截不到这个消息
      

  3.   

    消息钩子屏蔽不了ctrl+alt+del吧。
    处理SAS消息处理函数,要不写个驱动吧
      

  4.   

    NT之后就钩子就无法屏蔽ctrl+alt+del了。不过可以通过改组策略来屏蔽。但是最奇怪的是num lock是如何锁住的。
      

  5.   

    这个,很全了
    http://www.vckbase.com/document/viewdoc/?id=424
      

  6.   

    楼上发的这个我看过了,不能屏蔽num lock灯、win+esc
      

  7.   

    可以尝试一下BlockInput(TRUE)这个函数!哈哈,AMI刷BIOS的工具好像就用这个函数!
    但是这个也没办法屏蔽ctrl+alt+del的,不过网上有介绍如何屏蔽ctrl+alt+del的文章!楼主可以两者结合去做试试!嘿嘿,希望将结果share出来,让我们知道这样可以行不!!
      

  8.   

    黑屏的实现也可以考虑是monitor进入休眠状态!好像只是send一个message就可以了!此时monitor的开关按钮时桔黄色的!BlockInput(TRUE)后,鼠标也是不能动的!
      

  9.   

    因为黑屏需要在屏幕上显示提示信息,所以不能用monitor休眠。昨天我使用低级键盘钩子已经可以锁定除ctrl+alt+del之外的所有键与组合键。BlockInput没试。ctrl+alt+del不用屏蔽了,因为鼠标和键盘所有键都已经锁定,即使呼叫出了任务管理器,也无法操作,已经达到所需要的效果了。
      

  10.   

    屏蔽其他的键只需要做一个Low Level Keyboard Hook就可以了,不过这个hook要求安装hook的线程必须有消息循环。因为这个hook是安装hook的线程来处理的,而不是目标线程处理。屏蔽ctrl+alt+del我做过的,方法有2个
    (1)注入winlogon.exe,找到winlogon进程的标题为“SAS Window”的窗口,屏蔽它的WM_HOTKEY消息就行了。因为ctrl+alt+del就是这个窗口注册的全局hot key。推荐这个方法。
    (2)自己做一个gina.dll替换系统原来的gina.dll,不过这个方法我觉得不好。因为他要修改系统文件,而且貌似会出现闪屏幕的效果。
      

  11.   

    gina.dll确实会闪屏。
    第一个方法过会试一下,多谢楼上
      

  12.   

    找到一个很久以前的DLL,用来禁用Ctrl+Alt+Del的,VC6+WinXP做出来的。
    导出了一个BOOL DisableCAD(BOOL bEnable)函数,参数bEnable给TRUE表示禁用组合键,给FALSE启用cpp文件:
    // DisableCAD.cpp : Defines the entry point for the DLL application.
    //#include "stdafx.h"#define PROPSTRING _T("__DISABLE__CTRL__ALT__DEL__PROP__STING__")TCHAR *MyName = NULL; //保存dll自己的文件名#define TARGET_PROCESS _T("WINLOGON.EXE") //目标进程名
    #define TARGET_WINDOW  _T("SAS Window") //目标窗口标题#define MAX_PROCESS 1024 //系统中最大进程数
    #define MAX_MODULE 1024 //进程中最大模块数
    //不知道实际上windows有没有限制,这两个数随便给的//LoadLibrary的不同版本
    #if defined _UNICODE
    #define _LoadLibrary "LoadLibraryW" //_UNICODE
    #else
    #define _LoadLibrary "LoadLibraryA" //_MBCS
    #endif//获取适当的Privilege
    BOOL AdjustProcessPrivilege(HANDLE hProcess, TCHAR *Privilege)
    {
    //hProcess 目标进程的handle
    //Privilege 需要的Privilege
    //成功返回TRUE,失败返回FALSE HANDLE hToken=NULL;
    OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&hToken);
    if(NULL==hToken) 
    return FALSE; LUID luid;
    if(!LookupPrivilegeValue(NULL,Privilege,&luid))
    {
    CloseHandle(hToken);
    return FALSE;
    } TOKEN_PRIVILEGES token_privileges;
    token_privileges.PrivilegeCount =1;
    token_privileges.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
    token_privileges.Privileges[0].Luid = luid;
    if(!AdjustTokenPrivileges(hToken,FALSE,&token_privileges,NULL,NULL,NULL))
    {
    CloseHandle(hToken);
    return FALSE;
    } CloseHandle(hToken); return TRUE;}//注入winlogon or 从winlogon中卸载dll
    BOOL InjectDll(BOOL nFlag)
    {
    //nFlag == TRUE,则注入winlogon
    //nFlag == FALS,则从Winlogon中卸载DLL
    //成功返回TRUE,失败返回FALSE BOOL bSucceed = FALSE;

    //获取SeDebugPrivilege以便注入winlogon
    if(FALSE == AdjustProcessPrivilege(GetCurrentProcess(),_T("SeDebugPrivilege"))) 
    return bSucceed; //远程线程注入
    LPTHREAD_START_ROUTINE pfnThread = NULL;
    HINSTANCE hMod = GetModuleHandle(_T("kernel32.dll"));
    if (TRUE == nFlag) 
    //LoadLibrary注入
    pfnThread=(LPTHREAD_START_ROUTINE)GetProcAddress(hMod,_LoadLibrary);
    else 
    //FreeLibrary卸载
    pfnThread=(LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"FreeLibrary");
    if(NULL == pfnThread) 
    return bSucceed; DWORD *PIDs = NULL;
    DWORD ProcNum = 0;
    HANDLE hProcess = NULL;
    HANDLE hRemoteThread = NULL;
    LPVOID ModName = NULL;
    HMODULE *Modules = NULL;
    __try
    {
    PIDs = new DWORD[MAX_PROCESS];
    if(NULL == PIDs) 
    __leave;
    EnumProcesses(PIDs,MAX_PROCESS*sizeof(DWORD),&ProcNum); //枚举所有进程 //查找exe映像名查找进程
    for(DWORD i=0;i<ProcNum/sizeof(DWORD);i++)
    {
    hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,PIDs[i]);
    if(NULL == hProcess) 
    continue;
    TCHAR n[MAX_PATH];
    GetProcessImageFileName(hProcess, n, MAX_PATH);
    if(NULL != _tcsstr(_tcsupr(n),TARGET_PROCESS))  //找到目标进程
    break;
    CloseHandle(hProcess);
    hProcess = NULL;
    } if (TRUE == nFlag)
    //注入
    {
    //在winlogon中分配内存
    LPVOID ModName=VirtualAllocEx(hProcess,NULL,\
    (_tcslen(MyName)+1)*sizeof(TCHAR),MEM_COMMIT,PAGE_READWRITE);
    if(!ModName)  
    __leave;

    //在winlogon中写入dll的文件名
    if(0 == WriteProcessMemory(hProcess,ModName,MyName,\
    (_tcslen(MyName)+1)*sizeof(TCHAR),NULL)) 
    __leave; //创建远程线程
    hRemoteThread = CreateRemoteThread(hProcess,NULL,0,pfnThread,ModName,0,NULL);
    if(NULL == hRemoteThread) 
    __leave;
    WaitForSingleObject(hRemoteThread,INFINITE);
    bSucceed = TRUE; //注入OK
    }
    else
    //卸载
    {
    if(NULL == hProcess || NULL == MyName) 
    __leave;
    Modules=new HMODULE[MAX_MODULE];
    if(NULL == Modules) 
    __leave;
    HMODULE Target = NULL;
    DWORD ModNum = 0;
    EnumProcessModules(hProcess,Modules,MAX_MODULE*sizeof(HMODULE),&ModNum); //列举所有进程
    TCHAR* ModuleFileName = new TCHAR[MAX_PATH];
    if(NULL == ModuleFileName) 
    __leave; //根据文件名查找dll
    for (DWORD i = 0; i<ModNum/sizeof(HMODULE);i++)
    {
    GetModuleFileNameEx(hProcess,Modules[i],ModuleFileName,MAX_PATH);
    if(0 == lstrcmp(ModuleFileName,MyName))
    {
    Target = Modules[i];
    break;
    }
    }
    delete ModuleFileName;
    if (NULL == Target) 
    __leave; //创建远程线程
    hRemoteThread = CreateRemoteThread(hProcess,NULL,0,pfnThread,Target,0,NULL);
    if(NULL == hRemoteThread) 
    __leave;
    WaitForSingleObject(hRemoteThread,INFINITE); //
    bSucceed = TRUE;
    }
    }
    __finally
    {
    if(NULL != Modules) 
    delete Modules;
    if(NULL != PIDs) 
    delete PIDs;
    if(NULL != ModName) 
    VirtualFreeEx(hProcess,ModName,0,MEM_RELEASE);
    if(NULL != hRemoteThread) 
    CloseHandle(hRemoteThread);
    if(NULL != hProcess) 
    CloseHandle(hProcess);
    } return bSucceed;
    }
    //屏蔽SAS Window的WM_HOTKEY消息用的WndProc
    LRESULT CALLBACK CADProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    if(WM_HOTKEY == msg && 0x002e0003 == lParam) //0x002e0003就是Ctrl+Alt+Del
    return 0;  return CallWindowProc((WNDPROC)GetProp(hwnd,PROPSTRING),hwnd,msg,wParam,lParam);
    }BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
    if(DLL_PROCESS_ATTACH == ul_reason_for_call)
    {
    MyName = new TCHAR[MAX_PATH];
    if(NULL == MyName) 
    return TRUE;
    GetModuleFileName((HMODULE)hModule,MyName,MAX_PATH);
    HWND hwndSAS = FindWindow(NULL,TARGET_WINDOW);
    if(NULL != hwndSAS)
    {
    if (NULL != GetProp(hwndSAS,PROPSTRING)) //已经禁了?
    return TRUE;
    SetProp(hwndSAS,PROPSTRING,(HANDLE)SetWindowLong(hwndSAS,GWL_WNDPROC,\
    (long)CADProc));
    }
    } if(DLL_PROCESS_DETACH == ul_reason_for_call)
    {
    HWND hwndSAS = FindWindow(NULL,TARGET_WINDOW);
    if(NULL != hwndSAS)
    {
    HANDLE handle = GetProp(hwndSAS,PROPSTRING);
    if(NULL == handle) 
    return TRUE;
    SetWindowLong(hwndSAS,GWL_WNDPROC,(long)handle);
    RemoveProp(hwndSAS,PROPSTRING);
    }
    delete MyName;
    }
        return TRUE;
    }//导出的函数
    //bEnable = TRUE表示禁用,FALSE是启用。
    BOOL __stdcall DisableCAD(BOOL bEnable)
    {
    return InjectDll(bEnable);
    }预编译头文件
    // stdafx.h : include file for standard system include files,
    //  or project specific include files that are used frequently, but
    //      are changed infrequently
    //#if !defined(AFX_STDAFX_H__1F8F38F8_58D8_4A39_855C_C09F1996E922__INCLUDED_)
    #define AFX_STDAFX_H__1F8F38F8_58D8_4A39_855C_C09F1996E922__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // Insert your headers here
    #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers#include <windows.h>// TODO: reference additional headers your program requires here
    #include <TCHAR.h>
    #include <psapi.h>
    #include <stdio.h>
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_STDAFX_H__1F8F38F8_58D8_4A39_855C_C09F1996E922__INCLUDED_)
    def文件
    EXPORTS
    DisableCAD