关于屏闭系统Ctrl+Alt+Del问题 高手们进来交流交流想法 回贴必给分

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

36 个解决方案

#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


上面的代码经测试,好像不行哦!这位高手请在适当的地方作些说明,以使大家都看得深入!谢谢你的回答!

#3


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

#4


FAQ上有讨论,可以去看看

#5


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

#6


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

#7


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

#8


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

#9


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

#10


楼上的兄弟能否总结一个出来,有很多人都期望解决此问题!我也看过很多相关方面的资料,但没有一个说得比较详细,而且我到目前为止还没有找到一个通过了测试的!谢谢楼上的兄弟回帖!

#11


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

#12


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

#13


你可以让用户以普通用户的身份登陆,而用管理员身份来运行程序。

#14


不是,要删除一些东西
我见一个网吧里只在时间旁边出现图表,却没有任务管理器窗口

#15


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

#16


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

#17


总结已有的方法:
   替换Gina.dll
   键盘钩子
   定时关闭任务管理器
   winlogon线程注入

如果仅仅是屏蔽一下Ctrl+alt+del,键盘钩子完全可以应付了.
最优方案当然是替换Gina.dll,是彻底解决方案.

#18


以前也做过这样的,当时是想把三个键都屏蔽掉,但是不成功,
关注中,UP

#19


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

#20


利用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)就可进入了,或者进入
安全模式,删除掉那个键值。

#21



http://www.consult.sx.cn/DisableCtrlAltDel.rar

只能屏蔽这三个键,任务管理器,需要在组策略中屏蔽,或者写注册表

#22


直接用注册热键的方法可以吗?我也是猜想,没有具体试验。
我注册过Alt+F4,再用此二键组就关不掉当前窗口了。
给你段程序,改改试试
unit Unit1;

interface

uses
  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.

#23


组策略,研究一下那里吧。。。

#24


学习

#25


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

#26


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

#27


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

#28


学习

#29


大家还有什么好方法或想法都请贴上,2006年01月11日结贴!

#30


nb
1月11日
楼主 单身吧?

#31


元旦,哪里也没去
送你一个代码吧,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.

#32


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;

#33


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;

interface

uses
  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.

#34


回复人: 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

#35


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

该是揭帖了

#36


谢谢各位兄台的捧场,给分啦!

#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


上面的代码经测试,好像不行哦!这位高手请在适当的地方作些说明,以使大家都看得深入!谢谢你的回答!

#3


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

#4


FAQ上有讨论,可以去看看

#5


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

#6


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

#7


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

#8


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

#9


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

#10


楼上的兄弟能否总结一个出来,有很多人都期望解决此问题!我也看过很多相关方面的资料,但没有一个说得比较详细,而且我到目前为止还没有找到一个通过了测试的!谢谢楼上的兄弟回帖!

#11


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

#12


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

#13


你可以让用户以普通用户的身份登陆,而用管理员身份来运行程序。

#14


不是,要删除一些东西
我见一个网吧里只在时间旁边出现图表,却没有任务管理器窗口

#15


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

#16


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

#17


总结已有的方法:
   替换Gina.dll
   键盘钩子
   定时关闭任务管理器
   winlogon线程注入

如果仅仅是屏蔽一下Ctrl+alt+del,键盘钩子完全可以应付了.
最优方案当然是替换Gina.dll,是彻底解决方案.

#18


以前也做过这样的,当时是想把三个键都屏蔽掉,但是不成功,
关注中,UP

#19


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

#20


利用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)就可进入了,或者进入
安全模式,删除掉那个键值。

#21



http://www.consult.sx.cn/DisableCtrlAltDel.rar

只能屏蔽这三个键,任务管理器,需要在组策略中屏蔽,或者写注册表

#22


直接用注册热键的方法可以吗?我也是猜想,没有具体试验。
我注册过Alt+F4,再用此二键组就关不掉当前窗口了。
给你段程序,改改试试
unit Unit1;

interface

uses
  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.

#23


组策略,研究一下那里吧。。。

#24


学习

#25


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

#26


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

#27


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

#28


学习

#29


大家还有什么好方法或想法都请贴上,2006年01月11日结贴!

#30


nb
1月11日
楼主 单身吧?

#31


元旦,哪里也没去
送你一个代码吧,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.

#32


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;

#33


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;

interface

uses
  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.

#34


回复人: 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

#35


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

该是揭帖了

#36


谢谢各位兄台的捧场,给分啦!