我在写一套网吧管理系统,为了不让上网者退出管理程序,必须把Ctrl+Alt+Del热键屏闭,防止把管理程序的进程结束!
我用的方法是每0.5秒检查一下是否有任务管理器的窗口句柄,如果有则关闭。这样的方法用了好一阵,但此方法只能蒙一些菜鸟,对于高手还是无用武之地!
希望高手们看到此贴后不论有没有更好的方法都请回个贴,相互学习!回贴一律给分!

解决方案 »

  1.   


    var HkNTWinKey: HHOOK;
    const
      WH_KEYBOARD = 13; function LockWinKey(nCode: Integer; wParam: wParam; lParam: lParam): LRESULT; stdcall;
    type
      PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
      KBDLLHOOKSTRUCT = record
        vkCode: DWORD;
        ScanCode: DWORD;
        Flags: DWORD;
        Time: DWORD;
        dwExtraInfo: DWORD;
      end;
    var
      p: PKBDLLHOOKSTRUCT;
    begin
      if not (nCode = HC_ACTION) then
      begin
        result := CallNextHookEx(0, nCode, wParam, lParam);
        Exit;
      end;
      case wParam of
        $0100,
          $0104,
          $0101,
          $0105:
          begin
            p := PKBDLLHOOKSTRUCT(lParam);
            if (((GetKeyState(VK_CONTROL) and $8000) <> 0) and (p^.vkCode = VK_ESCAPE)) or
              (p^.vkCode = VK_LWIN) or (p^.vkCode = VK_RWIN) then
            begin
              result := 1;
              Exit;
            end;
          end;
      end;
      result := CallNextHookEx(0, nCode, wParam, lParam);
    end;
    SetWindowsHookEx(WH_KEYBOARD, LockWinKey, HInstance, 0);UnhookWindowsHookEx(HkNTWinKey);
      

  2.   

    http://www.delphibbs.com/keylife/iblog_show.asp?xid=5548
      

  3.   

    哦,忘了提了,此软件是运行在winXP上!谢谢两位的答复!
      

  4.   

    用远程线程注入技术,目标进程是 winlogon,
    具体的你可以到网上去搜一下,参考一下以前的win2k下面的做法。
      

  5.   

    这个基本上很难,必须取得ring0级权限。
    收藏,顶一下!
      

  6.   

    这个问题要解决,的确有点困难,但像《万象网管》 等一些管理软件就已经做到了!而且感觉挺好!我相信看过此贴的必定有高手,只是不想出手而已!我在Google中搜索了很久也没有什么重大发现!希望高手们多多指点,也肯定有很多路过的兄弟想知道答案!
    想知道答案的兄弟都签个名吧!!!UP
      

  7.   

    网上好多代码,都已经解决了
    如果你还找不到,到这里:http://lysoft.lz169.com/kingron/index.asp
    找找,或问问
      

  8.   

    http://dev.csdn.net/develop/article/15/15645.shtm
      

  9.   

    就算屏蔽了ctrl alt del 任务管理其还是会出来,
    郁闷
      

  10.   

    把当前用户提升到debug权限
    其实也不是很难
      

  11.   

    只是要屏蔽Ctrl+Alt+Del的对话框改注册表就可以了,但是这样做不好,实际上就算你用其他方法屏蔽了也是不好,现在有很多可以结束进程的程序,他网上下一个就行了
    最好把进程也隐藏掉,可以用插入其他进程的方法,或是在进程的链表删除自己的进程方法比较多...
      

  12.   

    总结已有的方法:
       替换Gina.dll
       键盘钩子
       定时关闭任务管理器
       winlogon线程注入如果仅仅是屏蔽一下Ctrl+alt+del,键盘钩子完全可以应付了.
    最优方案当然是替换Gina.dll,是彻底解决方案.
      

  13.   

    键盘钩子是不行D……我在http://dev.csdn.net/develop/article/15/15645.shtm里面有说
      

  14.   

    利用GINA实现Ctrl+Alt+Del的拦截
    WINDOWS NT/2000下如何屏蔽CTRL+ALT+DEL
    作者:ac952_z_cn前言
    在WINDOWS 9X环境中我们可以使用SystemParametersInfo (SPI_SCREENSAVERRUNNING, 1,NULL, 0);来屏蔽CTRL+ALT+DEL,但在NT/2000环境下却行不通,即使使用WH_KEYBOARD_LL这个低级的键盘hook也无法拦截!笔者通过替换GINA DLL的方式很好地实现了在NT/2000下屏蔽CTRL+ALT+DEL的功能。下载源代码 6K一、原理
    在NT/2000中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。在WinLogon初始化时,就向系统注册截获CTRL+ALT+DEL消息,所以其他程序就无法得到CTRL+ALT+DEL的消息。
    WinLogon会和GINA DLL进行交互,缺省是MSGINA.DLL(在System32目录下)。微软同时也为我们提供的接口,自己
    可以编GINA DLL来代替MSGINA.DLL。WinLogon初始化时会创建3个桌面:
    (1)、winlogon桌面:主要显示window 安全等界面,如你按下CTRL+ALT+DEL,登陆的界面等
    (2)、应用程序桌面:我们平时见到的那个有我的电脑的界面
    (3)、屏幕保护桌面:屏幕保护显示界面。在用户登陆以后,按下CTRL+ALT+DEL键的时候,WinLogon回调用GINA DLL的输出函数:WlxLoggedOnSAS,
    这时正处于winlogon桌面,我们只要直接将他转向应用程序桌面,系统就不会显示Windows安全那个界面,换一种说法
    也就是用户按下CTRL+ALT+DEL后,不会起什么作用。当是我们在切换桌面的时候会出现屏幕闪动!二、程序实现
    GINA DLL要输出下列函数(winlogon会调用)
    WlxActivateUserShell
    WlxDisplayLockedNotice
    WlxDisplaySASNotice
    WlxDisplayStatusMessage
    WlxGetStatusMessage
    WlxInitialize
    WlxIsLockOk
    WlxIsLogoffOk
    WlxLoggedOnSAS
    WlxLoggedOutSAS
    WlxLogoff
    WlxNegotiate
    WlxNetworkProviderLoad
    WlxRemoveStatusMessage
    WlxScreenSaverNotify
    WlxShutdown
    WlxStartApplication
    WlxWkstaLockedSAS
    为了简化编程,我们从MSGINA.DLL中动态获取上诉函数,在自定义的DLL中(以下称为NoReboot.DLL)中直接调用MSGINA.DLL
    的函数即可。现在我们要处理的就是WlxLoggedOnSAS函数:
    int WINAPI WlxLoggedOnSAS (
            PVOID pWlxContext,
            DWORD dwSasType,
            PVOID pReserved)
            { 
            HANDLE hMutex;
            WriteInfo("WlxLoggedOnSAS \r\n"); //用于记录信息
     if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL){ //屏蔽CTRL_ALT_DEL,也可以根据特定条件来决定是否要屏蔽
            //我采用了Mutex来控制是否屏蔽,(注意:要用unicode)
            hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"_ac952_z_cn_CTRL_ALT_DEL");
            if (hMutex){
            CloseHandle(hMutex);
            WriteInfo("disble CTRL+ALT+DEL \r\n");
            return WLX_SAS_ACTION_NONE; //将屏幕切换到应用程序桌面,屏蔽掉CTRL+ALT+DEL
            }
            else
            WriteInfo("not disble CTRL+ALT+DEL \r\n");
            }
            return prcWlxLoggedOnSAS ( //这是我从MSGINA.DLL中获取的函数。
            pWlxContext,
            dwSasType,
            pReserved);
            }我们要在自己的程序中调用hMutex = CreateMutex(NULL, FALSE, "_ac952_z_cn_CTRL_ALT_DEL");就可屏蔽CTRL+ALT+DEL。三、安装和注意事项:在编写GIAN DLL中要注意,GINA DLL使用的是unicode。GINA DLL的安装:
    键名 : \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon 
    变量名 : GinaDLL 
    变量类型 : [REG_SZ] 
    内容 : "你的GINA DLL的名称" 如:"NoReboot.DLL:将你的GINA DLL(NoReboot.dll)拷贝到系统目录下(system32),重启机器,你的GINA DLL(NoReboot.dll)就会运行。
    如果出现进不了你的系统,那你进入DOS后,将msgina.dll拷贝成你的GINA DLL(NoReboot.dll)就可进入了,或者进入
    安全模式,删除掉那个键值。
      

  15.   


    http://www.consult.sx.cn/DisableCtrlAltDel.rar只能屏蔽这三个键,任务管理器,需要在组策略中屏蔽,或者写注册表
      

  16.   

    直接用注册热键的方法可以吗?我也是猜想,没有具体试验。
    我注册过Alt+F4,再用此二键组就关不掉当前窗口了。
    给你段程序,改改试试
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        HotKeyId:smallint;
        procedure HotKeyDown(var Msg: Tmessage);
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
       HotKeyId:= GlobalAddAtom('MyHotKey') - $C000;
       RegisterHotKey(Handle,hotkeyid,MOD_ALT,VK_F4);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
       UnRegisterHotKey(handle,HotKeyId); //×&cent;&Iuml;úHotKey&pound;&not; &Ecirc;&Iacute;·&Aring;×&Ecirc;&Ocirc;&acute;&iexcl;&pound;
    end;
    procedure Tform1.HotKeyDown(var Msg: Tmessage);
    begin
    end;end.
      

  17.   

    告诉你一个最简单的办法,自己创建一个desktop,然后让explorer在这个桌面上跑,保证taskmgr出来不了
      

  18.   

    向 jiangsheng(蒋晟.Net)  大哥问声好。 2年多前,读过你和名捕的那个程序,很谢谢。
      

  19.   

    到我的站点LYSoft上找吧
    有现成的代码下载,呵呵
    就是ARI所说的那里:)
    http://lysoft.lz169.com/projects/No Ctrl+Alt+Del.rar
      

  20.   

    元旦,哪里也没去
    送你一个代码吧,LY可不是轻易给人写代码的
    下面的方法适合任何Windows NT平台(4.0以上)(至少目前的WinNT都能支持)
    NT4,2000,XP,2003全部OK的,而且没有窗口闪烁,呵呵,编译后的DLL才16K,好用得很的别问我怎么Inject DLL到EXE呀,嘻嘻:)元旦快乐,新年新气象~~~library SASWinHook;{
      SASWinHook
      copyrights by Liu Yang LYSoft http://lysoft.7u7.net 2006.1.1  usage: only need to inject this dll to WinLogon.exe
    }uses Windows, Messages;{$R *.res}var
      FHandle: THandle;
      OldAppProc: Pointer;function HookProc(hHandle: THandle; uMsg: Cardinal;
      wParam, lParam: Integer): LRESULT; stdcall;
    var K, C: Word;  // wndproc
    begin
      if uMsg = WM_HOTKEY then
         begin
            K := HIWORD(lParam);
            C := LOWORD(lParam);
            // press Ctrl + Alt + Del
            if (C and VK_CONTROL<>0) and (C and VK_MENU <>0) and ( K = VK_DELETE)
               then Exit;   // disable Ctrl + Alt + Del
         end;
      Result := CallWindowProc(OldAppProc, hHandle,
        uMsg, wParam, lParam);
    end;procedure EntryPointProc(Reason: Integer);
    begin
      case reason of
        DLL_PROCESS_ATTACH:
          begin  // hook SAS window wndproc
            FHandle := FindWindow('SAS window class', 'SAS window');
            if not IsWindow(FHandle) then Exit;  // is window found?
            // save old wndproc
            OldAppProc := Pointer(GetWindowLong(FHandle, GWL_WNDPROC));
            // set new wndproc
            SetWindowLong(FHandle, GWL_WNDPROC, Cardinal(@HookProc));
          end;
        DLL_PROCESS_DETACH:
          begin
            if FHandle > 0 then
               begin  // unhook
                 if Assigned(OldAppProc) then
                    SetWindowLong(FHandle, GWL_WNDPROC, LongInt(OldAppProc));
                 OldAppProc := nil;
               end;
          end;
        end;
    end;begin
      OldAppProc := nil;
      FHandle := 0;
      DllProc := @EntryPointProc;
      EntryPointProc(DLL_PROCESS_ATTACH);
    end.
      

  21.   

    procedure DisableTaskmgr(Key: Boolean);
    var
      Reg:TRegistry;
    begin
      Reg:=TRegistry.Create;
      try
        Reg.RootKey := HKEY_CURRENT_USER;
        if Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\System', True) then
        begin
          if Key then
            Reg.WriteString('DisableTaskMgr','1')//可以打开任务管理器
          else
            Reg.WriteInteger('DisableTaskMgr',0);//屏蔽任务管理器
          Reg.CloseKey;
        end;
      except
        Reg.Free;
      end;
    end;
      

  22.   

    ly_liuyang(Liu Yang LYSoft http://lysoft.7u7.net)
    的方法不错,等我试先!
    Dll怎样注入EXE呢,我给大家一个例子
    在Delphi中利用CreateRemoteThread远程注入例子 
    用Delphi建了个什么也没有作的程序prjzzhost.exe,将它用作被注入的宿主进程.
    写了一个TestDll.Dll,里面只有一个Log函数,用来在文件Test.Txt中输出信息.最重要的一个程序project1.exe是用来注入的.
    测试环境: windows server 2003 + delphi 7.0
    程序很简单,高手就不用看了.废话不说了,看代码吧!测试用的TestDll.Dll源代码(它将被注入到prjzzhost.exe中去): 程序代码library TestDll;uses
      SysUtils,
      System,
      windows,
      Classes;  procedure Log( s : PChar);stdcall;
      var
        F : TextFile;
      begin
        assignfile(f,'Test.txt');
        if fileexists('Test.txt') then append(f)
        else rewrite(f);
        writeln(f,s);
        closefile(f);
      end;  procedure DllEntryPoint(dwReason:DWord);
      begin
          case dwReason of
          DLL_PROCESS_ATTACH:
            Log('dll process Attach');
          DLL_PROCESS_DETACH:
          Log('dll process Detach');
          DLL_THREAD_ATTACH:
            Log('dll thread Attach');
          DLL_THREAD_DETACH:
            Log('dll thread Detach');
          end;  end;  exports
        Log;begin
      DllProc := @DllEntryPoint;
      DllEntryPoint(DLL_PROCESS_ATTACH);
    end.
    被注入的宿主进程prjzzhost.exe(它什么也没有作,好无辜哦:),这里就不给出代码了,因为太简单了,哈哈.
    最后,最重要的来了:
    project1.exe的源代码: 程序代码unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,tlhelp32;type  TLog = procedure(s : PChar);stdcall;
      TServiceMain = procedure(argc : Integer; VAR argv : pchar);stdcall;  EDLLLoadError = class(Exception);  TForm1 = class(TForm)
        Button3: TButton;
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;implementation{$R *.dfm}{ 列举进程 }
    procedure GetMyProcessID(const AFilename: string; const PathMatch: Boolean; var ProcessID: DWORD);
    var
      lppe: TProcessEntry32;
      SsHandle: Thandle;
      FoundAProc, FoundOK: boolean;
    begin
      ProcessID :=0;
      { 创建系统快照 }
      SsHandle := CreateToolHelp32SnapShot(TH32CS_SnapProcess, 0);  { 取得快照中的第一个进程 }
      { 一定要设置结构的大小,否则将返回False }
      lppe.dwSize := sizeof(TProcessEntry32);
      FoundAProc := Process32First(Sshandle, lppe);
      while FoundAProc do
      begin
        { 进行匹配 }
        if PathMatch then
          FoundOK := AnsiStricomp(lppe.szExefile, PChar(AFilename)) = 0
        else
          FoundOK := AnsiStricomp(PChar(ExtractFilename(lppe.szExefile)), PChar(ExtractFilename(AFilename))) = 0;
        if FoundOK then
        begin
          ProcessID := lppe.th32ProcessID;
          break;
        end;
        { 未找到,继续下一个进程 }
        FoundAProc := Process32Next(SsHandle, lppe);
      end;
      CloseHandle(SsHandle);
    end;
    { 设置权限 }
    function EnabledDebugPrivilege(const Enabled : Boolean) : Boolean;
    var
      hTk : THandle; { 打开令牌句柄 }
      rtnTemp : Dword; { 调整权限时返回的值 }
      TokenPri : TOKEN_PRIVILEGES;
    const
      SE_DEBUG = 'SeDebugPrivilege'; { 查询值 }
    begin
      Result := False;
      { 获取进程令牌句柄,设置权限 }
      if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,hTk)) then
      begin
        TokenPri.PrivilegeCount := 1;
        { 获取Luid值 }
        LookupPrivilegeValue(nil,SE_DEBUG,TokenPri.Privileges[0].Luid);    if Enabled then
          TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
        else
          TokenPri.Privileges[0].Attributes := 0;    rtnTemp := 0;
        { 设置新的权限 }
        AdjustTokenPrivileges(hTk,False,TokenPri,sizeof(TokenPri),nil,rtnTemp);    Result := GetLastError = ERROR_SUCCESS;
        CloseHandle(hTk);  end;
    end;
    { 调试函数 }
    procedure OutPutText(var CH:PChar);
    var
      FileHandle: TextFile;
    Begin
      AssignFile(FileHandle,'zztest.txt');
      Append(FileHandle);
      Writeln(FileHandle,CH);
      Flush(FileHandle);
      CloseFile(FileHandle);
    END;{ 注入远程进程 }
    function InjectTo(const Host, Guest: string; const PID: DWORD = 0): DWORD;
    var
      { 被注入的进程句柄,进程ID}
      hRemoteProcess: THandle;
      dwRemoteProcessId: DWORD;  { 写入远程进程的内容大小 }
      memSize: DWORD;  { 写入到远程进程后的地址 }
      pszLibFileRemote: Pointer;  iReturnCode: Boolean;
      TempVar: DWORD;  { 指向函数LoadLibraryW的地址 }
      pfnStartAddr: TFNThreadStartRoutine;  { dll全路径,需要写到远程进程的内存中去 }
      pszLibAFilename: PwideChar;
    begin
      Result := 0;
      { 设置权限 }
      EnabledDebugPrivilege(True);  { 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 }
      Getmem(pszLibAFilename, Length(Guest) * 2 + 1);
      StringToWideChar(Guest, pszLibAFilename, Length(Guest) * 2 + 1);  { 获取进程ID }
      if PID > 0 then
         dwRemoteProcessID := PID
      else
         GetMyProcessID(Host, False, dwRemoteProcessID);  { 取得远程进程句柄,具有写入权限}
      hRemoteProcess := OpenProcess(PROCESS_CREATE_THREAD + {允许远程创建线程}
          PROCESS_VM_OPERATION + {允许远程VM操作}
          PROCESS_VM_WRITE, {允许远程VM写}
          FALSE, dwRemoteProcessId);  { 用函数VirtualAllocex在远程进程分配空间,并用WriteProcessMemory中写入dll路径 }
      memSize := (1 + lstrlenW(pszLibAFilename)) * sizeof(WCHAR);
      pszLibFileRemote := PWIDESTRING(VirtualAllocEx(hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE));
      TempVar := 0;
      iReturnCode := WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, memSize, TempVar);  if iReturnCode then
      begin
        pfnStartAddr := GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW');
        TempVar := 0;
        { 在远程进程中启动dll }
        Result := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, TempVar);
      end;  { 释放内存空间 }
      Freemem(pszLibAFilename);
    end;  { 测试 }
    procedure TForm1.Button3Click(Sender: TObject);
    begin  InjectTo('prjzzhost.exe', extractfilepath(paramstr(0))+'TestDll.dll');
    end;end.
      

  23.   

    回复人: jiangsheng(蒋晟.Net[MVP]) ( ) 信誉:105  2005-12-29 9:21:29  得分: 0  
     
     
       
    键盘钩子是不行D……我在http://dev.csdn.net/develop/article/15/15645.shtm里面有说  
     
    --------------------------------------------------------------------------尝试了一下这个例子.在hRemoteThread = CreateRemoteThread(hRemoteProcess,0,0,(DWORD(__stdcall *)(VOID*))pRemoteThread,(INJECTLIBINFO*)pRemoteParam,0,&dwWriten);崩溃了.
    提示是:拒绝访问.系统环境: XP+sp2
      

  24.   

    在LYSoft下载Demo吧
    含DLL的源码的
    用Wintask工具加载SASWinHook.DLL到WinLogon.Exe,马上有效果该是揭帖了