WIN2000和WINXP下如何屏蔽系统热键

atm008 2003-09-03 09:56:07
例如屏蔽ALT+TAB和CTRL+ALT+DEL
...全文
75 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
okgxs 2003-09-05
  • 打赏
  • 举报
回复
(******************************************************************************
* CopyRight (c) By GanHuaXin 2002
* All Right Reserved
* Email : huiyugan@263.net
* Date :
* New Develop : 2002-x-x
* Modified : 2001-05-26
******************************************************************************)

unit privilege;

interface
uses
Windows, Dialogs;

////////////////////////////////////////////////////////////////////////
// //
// NT Defined Privileges //
// //
////////////////////////////////////////////////////////////////////////
const
SE_CREATE_TOKEN_NAME : PChar = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME : PChar = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME : PChar = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME : PChar = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME : PChar = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME : PChar = 'SeMachineAccountPrivilege';
SE_TCB_NAME : PChar = 'SeTcbPrivilege';
SE_SECURITY_NAME : PChar = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME : PChar = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME : PChar = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME : PChar = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME : PChar = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME : PChar = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME : PChar = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME : PChar = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME : PChar = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME : PChar = 'SeBackupPrivilege';
SE_RESTORE_NAME : PChar = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME : PChar = 'SeShutdownPrivilege';
SE_DEBUG_NAME : PChar = 'SeDebugPrivilege';
SE_AUDIT_NAME : PChar = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME : PChar = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME : PChar = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME : PChar = 'SeRemoteShutdownPrivilege';

function SetPrivilege(hToken : THandle; strPrivilege : PChar; bEnable:BOOL):BOOL;
function SetCurProcessDbgPrivilege:BOOL;
function UnSetCurProcessDbgPrivilege:BOOL;

implementation

function SetPrivilege(hToken : THandle; strPrivilege : PChar; bEnable:BOOL):BOOL;
var
tp : TOKEN_PRIVILEGES;
luid : TLargeInteger;
tpPrevious : TOKEN_PRIVILEGES;
cbPrevious : DWORD;
cbRtn : DWORD;
begin
cbPrevious := sizeof(TOKEN_PRIVILEGES);

if not LookupPrivilegeValue(nil, strPrivilege, luid) then begin
result := FALSE;
exit;
end;

tp.PrivilegeCount := 1;
tp.Privileges[0].Luid := luid;
tp.Privileges[0].Attributes := 0;

AdjustTokenPrivileges(hToken, FALSE, tp,
sizeof(TOKEN_PRIVILEGES),
tpPrevious,
cbPrevious);
if (GetLastError() <> ERROR_SUCCESS) then begin
result := FALSE;
exit;
end;

tpPrevious.PrivilegeCount := 1;
tpPrevious.Privileges[0].Luid := luid;

if (bEnable) then begin
tpPrevious.Privileges[0].Attributes :=
tpPrevious.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED;
end
else begin
tpPrevious.Privileges[0].Attributes :=
tpPrevious.Privileges[0].Attributes and (not SE_PRIVILEGE_ENABLED)
end;

AdjustTokenPrivileges(
hToken,
FALSE,
tpPrevious,
cbPrevious,
nil,
cbRtn);
if (GetLastError() <> ERROR_SUCCESS) then
result := FALSE;
result := TRUE;
end;

function SetCurProcessDbgPrivilege:BOOL;
var
hToken : THandle;
begin
result := TRUE;
if (not OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
hToken ))
then begin
ShowMessage('Can not get the Process Token!');
result := FALSE;
exit;
end;

if (not SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)) then begin
result := FALSE;
CloseHandle(hToken);
exit;
end;

CloseHandle(hToken);
end;

function UnSetCurProcessDbgPrivilege:BOOL;
var
hToken : THandle;
begin
result := TRUE;
if (not OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
hToken ))
then begin
ShowMessage('Can not get the Process Token!');
result := FALSE;
exit;
end;

if (not SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)) then begin
result := FALSE;
CloseHandle(hToken);
exit;
end;

CloseHandle(hToken);
end;

end.
okgxs 2003-09-05
  • 打赏
  • 举报
回复
(******************************************************************************
* CopyRight (c) By GanHuaXin 2002
* All Right Reserved
* Email : huiyugan@263.net
* Date :
* New Develop : 2002-x-x
* Modified : 2001-05-26
******************************************************************************)
unit OpenThread;

interface

uses
Windows,
TlHelp32,
SysUtils;

function OpenThread2(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
function GetProcessID(strProcessName : string):DWORD;
function GetThreadID(dwOwnerProcessID : DWORD):DWORD;

implementation

const
THREAD_TERMINATE = $0001;
THREAD_SUSPEND_RESUME = $0002;
THREAD_GET_CONTEXT = $0008;
THREAD_SET_CONTEXT = $0010;
THREAD_SET_INFORMATION = $0020;
THREAD_QUERY_INFORMATION = $0040;
THREAD_SET_THREAD_TOKEN = $0080;
THREAD_IMPERSONATE = $0100;
THREAD_DIRECT_IMPERSONATION = $0200;
THREAD_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3FF;

type
PPDB = ^T_PDB;
T_PDB = record
mType : WORD;
Refcount : WORD;
Unk0 : DWORD;
Unk1 : DWORD;
Unk2 : DWORD;
TermStatus : DWORD;
Unk3 : DWORD;
DefaultHeap : DWORD;
MemContext : DWORD;
Flags : DWORD;
pPsp : DWORD;
psSelector : WORD;
METIndex : WORD;
nThreads : WORD;
nThreadsNotTerm : WORD;
Unk5 : WORD;
nR0Threads : WORD;
HeapHandle : DWORD;
K16TDBSel : WORD;
Unk6 : WORD;
Unk7 : DWORD;
pEDB : DWORD;
pHandleTable : DWORD;
ParentPDB : PPDB;
ModRefList : DWORD;
ThreadList : DWORD;
DebugeeCB : DWORD;
LHFreeHead : DWORD;
InitialR0ID : DWORD;
end;
PDB = T_PDB;


T_TCB = record
mType : WORD;
RefCount : WORD;
Unk1 : DWORD;
pvExcept : DWORD;
TopOfStack : DWORD;
BaseOfStace : DWORD;
K16TDB : WORD;
StackSel16 : WORD;
Unk2 : DWORD;
UserPointer : DWORD;
pTIB : DWORD;
TIBFlags : WORD;
Win16MutxCnt : WORD;
DebugContext : DWORD;
PtrToCurPri : DWORD;
MsgQueue : DWORD;
pTLSarray : DWORD;
pParentPDB : PPDB;
SelmanList : DWORD;
Unk3 : DWORD;
Flags : DWORD;
status : DWORD;
TibSel : WORD;
EmulatorSel : WORD;
HandleCount : DWORD;
WaitNodeList : DWORD;
R0hThread : DWORD;
ptdbx : DWORD;
end;
TCB = T_TCB;
PTCB = ^T_TCB;

OBFUNC = function(dwPTID : DWORD):pointer;stdcall;
OTFUNC = function(pH : PHandle; dwVal : DWORD; var var1; var var2):DWORD;stdcall;

function GetTrueProcAddress(lpMod : PChar; lpFunc : PChar):pointer;stdcall;forward;
function OpenThreadNT(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;forward;


function XORProcessThreadID(dwPTID : DWORD):pointer;stdcall;
var
obfuscate : OBFUNC;
dwMain : DWORD;
lpdw : PDWORD;
dw1 : DWORD;
begin
dwMain := DWORD(GetTrueProcAddress('Kernel32.dll', 'GetCurrentThreadId'));
// if dwMain = nil then begin result := nil; exit; end;
lpdw := PDWORD(dwMain+8);
dw1 := dwMain + 12;
obfuscate := OBFUNC(dw1 + lpdw^);
result := obfuscate(dwPTID);
end;

function OpenThread2(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
var
hThread, hPrc : THandle;
lp1 : PDWORD;
dwProcessID , dwWhere, dwTable : DWORD;
b1 : BOOL;
lpThreadObj : PTCB;
procpPdb : PPDB;
osvi : OSVERSIONINFO;
begin
osvi.dwOSVersionInfoSize := sizeof(osvi);
GetVersionEX(osvi);

SetLastError(50);

if osvi.dwPlatformId = VER_PLATFORM_WIN32_NT then
result := OpenThreadNT(dwThreadID, bInherit)
else begin
procpPdb := PPDB(XORProcessThreadID(GetCurrentProcessID()));
lpThreadObj := PTCB (XORProcessThreadID(dwThreadID));

if IsBadReadPtr(lpThreadObj, sizeof(TCB)) then begin
result := 0;
exit;
end;

if PBYTE(lpThreadObj)^ <> 7 then begin
result := 0;
exit;
end;

dwProcessID := DWORD(XORProcessThreadID(DWORD(lpThreadObj^.pParentPDB)));

if (dwProcessID = GetCurrentProcessID()) then
hPrc := GetCurrentProcess()
else begin
hPrc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (hPrc = 0) then begin
result := 0;
exit;
end;
end;

// 4 is the lowest handle in the table
// all proceses have this handle
b1 := DuplicateHandle(hPrc,
THandle(4),
GetCurrentProcess(),
@hThread,
THREAD_ALL_ACCESS,
bInherit, 0);

if (hPrc <> GetCurrentProcess()) then CloseHandle(hPrc);

if (b1=FALSE) then begin
result := 0;
exit;
end;

dwWhere := DWORD(hThread) shr 2;
dwTable := procpPdb^.pHandleTable;
lp1 := PDWORD (dwTable + dwWhere*8 + 8);

lp1^ := DWORD(lpThreadObj);

result := hThread;

end;

end;

{$J+}
function OpenThreadNT(dwThreadID : DWORD; bInherit : BOOL):THandle;stdcall;
const
hThread : THandle = 0;
struct1 : array [0..5] of DWORD = ($18, 0, 0, 0, 0, 0);
struct2 : array [0..1] of DWORD = (0, 0);
hLib : HModule = 0;
OpenThatNTThread : OTFUNC = nil;

begin

hLib := LoadLibrary('ntdll.dll');
OpenThatNTThread := OTFUNC(GetProcAddress(hLib, 'NtOpenThread'));

struct2[1] := dwThreadID;
struct1[3] := DWORD(bInherit);

OpenThatNtThread(@hThread, THREAD_ALL_ACCESS, struct1, struct2);

FreeLibrary(hLib);

result := hThread;
end;
{$J-}

function GetTrueProcAddress(lpMod : PChar; lpFunc : PChar):pointer;stdcall;
var
bla : pointer;
hMod : HModule;
begin
hMod := GetModuleHandle(lpMod);

if hMod=0 then begin
result := nil;
exit;
end;

bla := Pointer(GetProcAddress(hMod, lpFunc));
if (DWORD(bla) = 0) then begin
result := nil;
exit;
end;

if PByte(bla)^ = $68 then
bla := Pointer(PDWORD(DWORD(bla) + 1)^);

result := bla;
end;

function GetProcessID(strProcessName : string):DWORD;
var
dwRet : DWORD;
hSnapShot : THandle;
ProcessEntry : PROCESSENTRY32;
bFlag : BOOL;
begin
dwRet := 0;
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hSnapshot <> INVALID_HANDLE_VALUE) then
begin
FillChar(ProcessEntry,sizeof(PROCESSENTRY32),0);
ProcessEntry.dwSize := sizeof(PROCESSENTRY32);
bFlag := Process32First(hSnapshot,ProcessEntry);
while (bFlag) do
begin
if Pos(UpperCase(strProcessName), UpperCase(ProcessEntry.szExeFile)) <> 0 then
begin
dwRet := ProcessEntry.th32ProcessID;
break;
end;
ProcessEntry.dwSize := sizeof(PROCESSENTRY32);
bFlag := Process32Next(hSnapshot,ProcessEntry);
end;
CloseHandle(hSnapshot);
end;
result := dwRet;
end;

function GetThreadID(dwOwnerProcessID : DWORD):DWORD;
var
dwRet : DWORD;
hThreadSnap : THandle;
te32 : THREADENTRY32;
begin
dwRet := 0;
FillChar(te32, SizeOf(te32), 0);
hThreadSnap := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap <> INVALID_HANDLE_VALUE) then begin
te32.dwSize := sizeof(THREADENTRY32);
if (Thread32First(hThreadSnap, te32)) then
repeat
if (te32.th32OwnerProcessID = dwOwnerProcessID) then begin
dwRet := te32.th32ThreadID;
break;
end;
until not (Thread32Next(hThreadSnap, te32));
CloseHandle (hThreadSnap);
end;
result := dwRet;
end;

end.
okgxs 2003-09-05
  • 打赏
  • 举报
回复
unit untFrmDll;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
TfrmDll = class(TForm)
Label1: TLabel;
Label2: TLabel;
Timer1: TTimer;
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
procedure SetTimeLabel;
public
{ Public declarations }
procedure DoMessageProcess;
end;

{
var
frmDll: TfrmDll;
}

implementation

{$R *.DFM}

procedure TfrmDll.FormShow(Sender: TObject);
begin
ShowWindow( Application.Handle, SW_HIDE );
SetWindowPos(handle, HWND_TOPMOST, 0, 0,
0, 0, SWP_NOMOVE or SWP_NOSIZE);
SetTimeLabel;
end;

procedure TfrmDll.SetTimeLabel;
var
szTextOut : array [0..255] of char;
SystemTime : _SYSTEMTIME;
begin
GetLocalTime(SystemTime);

StrLFmt(szTextOut, 255,
'Current Time is %d:%d:%d',
[SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond]);
label1.Caption := szTextOut;
if not Visible then begin
ShowWindow(Handle, SW_SHOW);
end;
end;

procedure TfrmDll.DoMessageProcess;
begin
while true do
Application.HandleMessage;
end;

procedure TfrmDll.Timer1Timer(Sender: TObject);
begin
SetTimeLabel;
end;

end.
//=====================================================================
noil0125 2003-09-05
  • 打赏
  • 举报
回复
学习
atm008 2003-09-05
  • 打赏
  • 举报
回复
TO:IORILI(眼镜@_@)
请问你知道怎么实现吗?能给我个代码吗?
IORILI 2003-09-05
  • 打赏
  • 举报
回复
一群牛人
atm008 2003-09-05
  • 打赏
  • 举报
回复
没有更简单的方法吗?
Drate 2003-09-04
  • 打赏
  • 举报
回复
5.实现接口函数。由于本应用仍然保持msgina.dll的大部分操作,所以MyGina.dll的接口函数的实现较为简单。重点需要注意的是WlxLoggedOnSAS函数的实现。当在成功登录状态下,不管接收到什么SAS事件,该函数直接返回WLX_SAS_ACTION_NONE而不做其他处理。由于实现的函数较多(必须的18个),笔者仅列出代表性的五个,其余的依理类推。
// Winlogon.exe调用的gina dll中的第一个函数
// 使gina dll确认是否支持当前版本的Winlogon.exe
// 传递给winlogon.exe需要那个版本的接口函数
BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
{
// 直接调用从msgina.dll中导入的函数
return theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);
}
// 初始化,winlogon.exe向gina dll传递需要版本的接口函数分配表
BOOL WINAPI WlxInitialize(LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID * pWlxContext
)
{
// 直接调用从msgina.dll中导入的函数
return theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
}
// 当系统处于锁定状态时,Winlogon.exe调用该函数
// 显示一些信息,如锁定者、锁定时间等
VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
theApp.MyWlxDisplayLockedNotice(pWlxContext);
}
// 在系统关闭之前,Winlogon.exe调用该函数
// 允许gina dll处理一些系统关闭前的处理
VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
{
theApp.MyWlxShutdown(pWlxContext,ShutdownType);
}
// 当系统处于登陆成功,没有锁定的状态下
// Winlogon接收到SAS事件,于是调用该函数
// 现屏蔽所有事件,直接返回
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
return WLX_SAS_ACTION_NONE;
}
6.将MyGina.dll中实现的所有接口函数,在MyGina.def中定义导出。






前言
在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)就可进入了,或者进入
安全模式,删除掉那个键值。
Drate 2003-09-04
  • 打赏
  • 举报
回复

Win2K/NT下屏蔽Ctrl+Alt+Del的响应

大家知道,Ctrl+Alt+Del是Win2k/NT操作系统默认的系统登录/注销组合键序列,系统级别很高。在应用程序中,想要屏蔽掉该键序列的响应或得到这个"按下"事件,难度是相当大的。本文介绍了一种简单易行的方法,实现在用户登录成功后,按下Ctrl+Alt+Del不再弹出"Windows安全"对话框。

关键词:GINA(Graphical Identification aNd Authentication)
SAS(Secure Attention Sequence)

一. 开发原理
首先介绍一下Winlogon。Windows 2000/NT有三种系统状态:没有用户登录状态、用户成功登录状态以及工作站锁定状态。Winlogon是Windows 2000/NT操作系统提供交互式登录支持的组件。Winlogon有三个组成部分:可执行文件winlogon.exe,提供图形界面认证功能的动态库Gina Dll,以及一些网络服务提供动态库Network Provider Dll。参考模型如下:

winlogon.exe处理一些下层导出的接口函数,而认证策略是在Gina Dll中是独立设计的。在系统启动时,Gina Dll被winlogon.exe装载。Microsoft提供了一个默认的Gina Dll--Winnt\system32\msgina.dll,提供了标准的用户名、密码认证模式。Gina Dll是可替换的,用户可以设计自己的Gina Dll,以提供其他如智能卡、视网膜、指纹或其他一些认证机制。
开发自定义的Gina Dll。必须实现并导出与winlogon.exe交互的18个标准函数接口,包括WlxNegotiate、WlxInitialize、WlxLoggedOnSAS等(其他函数接口请参考Msdn)。其中WlxNegotiate是winlogon.exe调用的第一个接口函数,进行必要的版本判断,随后调用的是WlxInitialize,主要完成winlogon.exe特定版本的函数分派表向Gina Dll的传递。笔者还要说明的是WlxLoggedOnSAS函数,这个函数主要的功能是,当winlogon在登录成功状态下,接收到SAS事件,于是调用这个函数进行SAS事件的识别以及进行各事件的相应处理。
自定义Gina Dll的使用。比如开发的Gina Dll文件名为MyGina.dll。将该文件放到以下路径:Winnt\system32。并修改注册表,如下:
Key Name: \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ Winlogon
Value Name: GinaDLL
Value Type: [REG_SZ]
Value: MyGina.dll
重新启动计算机MyGina.dll即投入使用。

二. 应用实例
应用要求:在用户登录成功状态下,按下Ctrl+Alt+Del时系统不再弹出"Widows安全"对话框。由于并不需要改变用户名、密码这种标准的认证模式,所以可以仍然使用msgina.dll中导出的函数接口,而对WlxLoggedOnSAS函数的实现进行必要的改变。
开发环境:Windows 2000,PII 400
开发工具:Microsoft Visual C++ 6.0
开发步骤:
1.新建项目,选择MFC AppWizard(dll),项目名输入为MyGina。按下"OK"后,选择Regular DLL with MFC statically linked,按下"Finish"。
2.使用View->ClassWizard为CmyGinaApp增加InitInstance和ExitInstance两个函数的覆盖。注意在Stdafx.h中加入#include <Winwlx.h>。
3.由于要导入msgina.dll的接口函数,所以在MyGina.h中定义接口函数变量类型,如下:
typedef (WINAPI * NEGOTIATE) (DWORD,PDWORD);
typedef (WINAPI * INITIALIZE) (LPWSTR,HANDLE,PVOID,PVOID,PVOID *);
typedef (WINAPI * ACTIVATE_USHELL) (PVOID,PWSTR,PWSTR,PVOID);
typedef (WINAPI * PARAM_PVOID) (PVOID);
typedef (WINAPI * DISP_STATUS) (PVOID,HDESK,DWORD,PWSTR,PWSTR);
typedef (WINAPI * GET_STATUS) (PVOID,DWORD *,PWSTR,DWORD);
typedef (WINAPI * LOGON_SAS) (PVOID,DWORD,PVOID);
typedef (WINAPI * LOGOUT_SAS) (PVOID,DWORD,PLUID,PSID,PDWORD, PHANDLE,WLX_MPR_NOTIFY_INFO,PVOID *);
typedef (WINAPI * NETWORK_LOAD) (PVOID,PWLX_MPR_NOTIFY_INFO);
typedef (WINAPI * SCR_SAVER) (PVOID,BOOL *);
typedef (WINAPI * SHUT_DOWN) (PVOID,DWORD);
typedef (WINAPI * START_APP) (PVOID,PWSTR,PVOID,PWSTR);
typedef (WINAPI * LOCKED_SAS) (PVOID,DWORD);
并在类CmyGinaApp中定义成员变量,如下:
private:
HMODULE hMsDll;
public:
NEGOTIATE MyWlxNegotiate;
INITIALIZE MyWlxInitialize;
ACTIVATE_USHELL MyWlxActivateUserShell;
PARAM_PVOID MyWlxDisplayLockedNotice;
PARAM_PVOID MyWlxDisplaySASNotice;
DISP_STATUS MyWlxDisplayStatusMessage;
GET_STATUS MyWlxGetStatusMessage;
PARAM_PVOID MyWlxIsLockOk;
PARAM_PVOID MyWlxIsLogoffOk;
LOGON_SAS MyWlxLoggedOnSAS;
LOGOUT_SAS MyWlxLoggedOutSAS;
PARAM_PVOID MyWlxLogoff;
NETWORK_LOAD MyWlxNetworkProviderLoad;
PARAM_PVOID MyWlxRemoveStatusMessage;
SCR_SAVER MyWlxScreenSaverNotify;
SHUT_DOWN MyWlxShutdown;
START_APP MyWlxStartApplication;
LOCKED_SAS MyWlxWkstaLockedSAS;
注意在MyGina.h中说明extern CMyGinaApp theApp;以便于程序其他地方对theApp的引用。
4.在MyGina.cpp中,实现InitInstance如下:
// 得到默认的gina dll
if (hMsDll == NULL)
{
hMsDll = ::LoadLibrary("msgina.dll");
}
// 导入各个接口函数
if (hMsDll != NULL)
{
MyWlxNegotiate = (NEGOTIATE) GetProcAddress(hMsDll,"WlxNegotiate");
MyWlxInitialize = (INITIALIZE) GetProcAddress(hMsDll,"WlxInitialize");
MyWlxActivateUserShell=(ACTIVATE_USHELL) GetProcAddress(hMsDll,"WlxActivateUserShell");
MyWlxDisplayLockedNotice=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxDisplayLockedNotice");
MyWlxDisplaySASNotice = (PARAM_PVOID) GetProcAddress(hMsDll,"WlxDisplaySASNotice");
MyWlxDisplayStatusMessage=(DISP_STATUS) GetProcAddress(hMsDll,"WlxDisplayStatusMessage");
MyWlxGetStatusMessage = (GET_STATUS) GetProcAddress(hMsDll,"WlxGetStatusMessage");
MyWlxIsLockOk = (PARAM_PVOID) GetProcAddress(hMsDll,"WlxIsLockOk");
MyWlxIsLogoffOk = (PARAM_PVOID) GetProcAddress(hMsDll,"WlxIsLogoffOk");
MyWlxLoggedOnSAS = (LOGON_SAS) GetProcAddress(hMsDll,"WlxLoggedOnSAS");
MyWlxLoggedOutSAS = (LOGOUT_SAS) GetProcAddress(hMsDll,"WlxLoggedOutSAS");
MyWlxLogoff = (PARAM_PVOID) GetProcAddress(hMsDll,"WlxLogoff");
MyWlxNetworkProviderLoad=(NETWORK_LOAD)GetProcAddress(hMsDll,"WlxNetworkProviderLoad");
MyWlxRemoveStatusMessage=(PARAM_PVOID) GetProcAddress(hMsDll,"WlxRemoveStatusMessage");
MyWlxScreenSaverNotify = (SCR_SAVER) GetProcAddress(hMsDll,"WlxScreenSaverNotify");
MyWlxShutdown = (SHUT_DOWN) GetProcAddress(hMsDll,"WlxShutdown");
MyWlxStartApplication = (START_APP) GetProcAddress(hMsDll,"WlxStartApplication");
MyWlxWkstaLockedSAS = (LOCKED_SAS) GetProcAddress(hMsDll,"WlxWkstaLockedSAS");
}
实现ExitInstance如下:
// 卸载dll
if (hMsDll != NULL)
{
::FreeLibrary(hMsDll);
hMsDll = NULL;
}
atm008 2003-09-04
  • 打赏
  • 举报
回复
TO:bluebilly(蓝色天使)
CTRL+ALT+DEL的屏蔽方法能不能具体的介绍一下,其他键的屏蔽都通过编译了
wlyx2003 2003-09-03
  • 打赏
  • 举报
回复
楼上的代码只能在瘟酒吧以下版本实现,两千跟叉屁下面是行不通的
grapegd 2003-09-03
  • 打赏
  • 举报
回复
当你不需要让用户按Alt+Enter、Ctrl+Alt+Del、Ctrl+Esc等功能键的时候加入
以下代码:
Var
temp:integer;
begin
SystemParametersInfo(Spi_screensaverrunning,1,@temp,0);
end;
  当你要恢复功能键时用以下代码:
Var
Temp:integer;
begin
SystemParametersInfo(spi_screensaverrunning,0,@temp,0);
end;
bluebilly 2003-09-03
  • 打赏
  • 举报
回复
先看一下屏蔽键的代码:
tagKBDLLHOOKSTRUCT = packed record
vkCode: DWORD;//虚拟键值
scanCode: DWORD;//扫描码值(没有用过,我也不懂^_^)
{一些扩展标志,这个值比较麻烦,MSDN上说得也不太明白,但是
根据这个程序,这个标志值的第六位数(二进制)为1时ALT键按下为0相反。}
flags: DWORD;
time: DWORD;//消息时间戳
dwExtraInfo: DWORD;//和消息相关的扩展信息
end;
KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
//这个是低级键盘钩子的索引值,Delphi中没有,必须自己定义
const WH_KEYBOARD_LL = 13;
//定义一个常量好和上面哪个结构中的flags比较而得出ALT键是否按下
const LLKHF_ALTDOWN = $20;

..........

{
功能:低级键盘钩子的回调函数,在里面过滤消息
参数:nCode 是Hook的标志
WParam 表示消息的类型
LParam 是一个指向我们在上面定义的哪个结构KBDLLHOOKSTRUCT的指针
返回值:如果不是0的话windows就把这个消息丢掉,程序就不会再收到这个消息了。
}
function LowLevelKeyboardProc(nCode: Integer;
WParam: WPARAM;LParam: LPARAM):LRESULT; stdcall;
var
fEatKeystroke: BOOL;
p: PKBDLLHOOKSTRUCT;
begin
Result := 0;
fEatKeystroke := FALSE;
p := PKBDLLHOOKSTRUCT (lParam);
//nCode值为HC_ACTION时表示WParam和LParam参数包涵了按键消息
if (nCode = HC_ACTION) then
begin
//拦截按键消息并测试是否是Ctrl+Esc、Alt+Tab、Windows键和Alt+Esc功能键。
case wParam of
WM_KEYDOWN,
WM_SYSKEYDOWN,
WM_KEYUP,
WM_SYSKEYUP:
fEatKeystroke := ((p.vkCode = VK_TAB) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0)) or
((p.vkCode = VK_LWIN) or (p.vkCode = VK_RWIN) or (p.vkCode = VK_APPS)) or
((p.vkCode = VK_DELETE) and(p.vkCode =VK_CONTROL) and(p.vkCode=KF_ALTDOWN));// or (p.vkCode = VK_DELETE);

//fEatKeystroke := (p.vkCode = VK_DELETE) and(p.vkCode =VK_CONTROL) and(p.vkCode=KF_ALTDOWN);
end;
end;
if fEatKeystroke = True then
Result := 1;
if nCode <> 0 then
Result := CallNextHookEx(0, nCode, wParam, lParam);
end;

调用键盘HOOK的代码如下:
var
hhkLowLevelKybd: THandle;
begin
if hhkLowLevelKybd = 0 then
hhkLowLevelKybd := SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc,
Hinstance, 0); //使WINDOWS系统键失效(CTRL+ESC, WINDOWS_L, WINDOWS_R)
end;
以上是屏蔽ALT+TAB键的代码

至于CTRL+ALT+DEL的键的屏蔽以下做法是将所有键下些组合键的键面变为不可用即可,如果你有更好的方法给我一份!
1.能够快速隐藏任意应用程序窗口。您可以通过设定热键,在任意时候,快速隐藏任意窗口。您可以隐藏/显示特定的一个或一组窗口。   2.能够隐藏其它程序的托盘图标。您不但可以隐藏Win2000/XP/2003以上系统中的托盘图标,更可以隐藏Win98/95下的托盘图标(WinME下的托盘图标隐藏暂不支持)。同样支持热键隐藏;可以给托盘图标发送各种鼠标消息,比如弹出右键托盘菜单等。   3. 不但可以修改窗口显示的图标和文字,还可以修改其它程序的托盘图标和提示文字。例如可以把聊天窗口伪装成Word,在Windows的任务工具栏上显示的是Word,而实际的窗口却是聊天窗口。   4.内部整合终极窗口属性修改器,比MS SPY++更强的窗口属性修改工具。您可以通过她查看、修改任意窗口或控制的属性;隐藏任意局部窗口或控制。   5.内部整合驱动器隐藏功能。   6. 超强的热键项目设置管理功能。热键分为临时热键和持久热键两种,临时热键可以随时绑定到窗口或托盘图标,持久热键可以实现隐藏/显示特定条件的窗口或托盘图标,或用来快速结束指定进程。   7. 整合进程管理器功能。可以设置任一进程优先级,可以强行结束进程,可以显示进程的详细信息,可以强行结束进程的DLL模块。   8.MagicHide除了提供了热键隐藏窗口以外,还提供了鼠标隐藏窗口的功能,同时按下鼠标的左右键即可隐藏当前窗口。   9. 难得一见的托盘图标排序功能。您可以通过她按自己的意愿调整托盘图标的排列顺序。   10.具有锁定屏幕功能,在您离开时,可以保护您的电脑不让他人操作。   11.MagicHide提供了密码保护的功能,可以使用密码禁止他人使用MagicHide。   12. 可以设置隐藏窗口或托盘图标时使系统静音。   13. 在Win2000/WinXp/Win2003等系统上可以设定任意窗口的透明度,可以设置窗口是否被穿透。   14. 可以快速关闭所有IE窗口。   15. MagicHide可以把任意窗口变成最前端显示,加强了对窗口的控制。   16. MagicHide其它的一些人性化的功能等待您的悉心发掘。
GoHide是一款可以帮助用户隐藏任何窗口的程序窗口隐藏专家,用户可以使用该隐藏任务栏程序软件来隐藏任意指定要隐藏的窗口,可以在任何需要的时候按热键就可以使指定的正在运行的程序窗口隐藏起来,但是被隐藏的程序还是继续运行,不会被关闭或者终止,用户只需按下相同的热键就可以显示这些被隐藏的程序。 软件介绍 要隐藏窗口时,只要直接按下隐藏热键F12即可,不用切换到GoHide再按F12!当然F12是GoHide缺省提供的窗口隐藏/显示热键,用户可以自行定义。 要恢复显示被隐藏的窗口,只要再按一下隐藏热键F12即可。在GoHide中,隐藏和显示使用同一热键。 1) 隐藏GoHide的同时,隐藏在任务栏通知区域GoHide本身的图标 GoHide本身也能被隐藏。除了作为一般程序窗口被用户选择隐藏外,GoHide还提供了二种单独的隐藏和显示的方法: 第一种:用鼠标右键单击位于任务栏通知区域(系统托盘)的GoHide对应的图标;在出现的菜单中选择“显示/隐藏GoHide本身”; 第二种:使用热键来隐藏/显示,GoHide缺省提供的为CTRL+SHIFT+F12。 注意:当GoHide连同图标被隐藏后要再显示GoHide,只有使用热键CTRL+SHIFT+F12或用户自己定义的热键。 2) 隐藏窗口的同时,隐藏在任务栏通知区域对应的图标 选中此项后,如果被选中的程序窗口在任务栏的通知区域右对应的图标,则当窗口被隐藏/显示时,对应的图标也同时被隐藏/显示。 需要说明的是,对于QQ,可能会出现在GoHide的窗口列表中没有QQ的情况,此时只要用鼠标点击一下窗口列表上面的【刷新】按钮,QQ就会在列表中出现了。 3) 隐藏窗口的同时,控制音频设备为全部静音 选中此项,用户按下隐藏热键隐藏窗口时,GoHide自动关闭计算机的声音。在窗口被恢复显示时,GoHide自动打开计算机的声音 4) 使被隐藏的程序暂停执行 选中此项,用户按下隐藏热键隐藏程序时,GoHide将使被隐藏的程序暂时停止执行直到程序被恢复显示。本功能只在WinME/WinNT/Win2000/WinXP上适用。注意:使用本功能存在一定的风险,请勿用于非常重要的程序。 5) 隐藏/显示时,隐藏优先 GoHide使用同一个热键来隐藏/显示选中的窗口,也就是说,第一次按下热键,选中的窗口被隐藏,第二次按下热键,被隐藏的窗口恢复显示,第三次按下热键,隐藏,等等,如此往复,这样使用非常方便。但是,如果在窗口被隐藏后,用户又选择了几个其它目前时显示着的窗口,那么再次按下热键,GoHide是恢复显示被隐藏的那些窗口,还是隐藏刚被用户选中的窗口?这就要看本项的设置了。如果本项被选中,那么按下热键时GoHide将先判断是否有未被隐藏的窗口,如果有,就隐藏这些窗口,没有,则恢复显示原来被隐藏的窗口;如果本项未被选中,那么用户按下热键时,原来被隐藏的窗口将恢复显示,用户新选择的窗口将被隐藏,后者对Windows桌面上有很多程序窗口,用户需要切换显示部分窗口的情况非常有用。 6) 热键定义 GoHide缺省定义了“隐藏/显示所选程序”热键为F12,“隐藏/显示GoHide本身”热键为CTRL+SHIFT+F12,用户可以在这里自行定义热键。方法是,先选择要定义的功能,然后把输入焦点移到“对应热键”输入框(可用鼠标单击以移动输入焦点),然后用户按下想要定义的键或键的组合即可,GoHide会记住用户的定义,以后所有的操作以新的热键为准。注意:用户改变热键定义后,GoHide缺省的热键将不发生作用了,所以用户一定要记住新的热键,不然将导致GoHide被隐藏后不能恢复显示等问题。 7) 口令保护 [显示被隐藏的窗口时需要口令] 选中此项,在恢复显示被隐藏的窗口前,GoHide要求用户先输入口令。 [显示被隐藏的GoHide时需要口令] 选中此项,在恢复显示被隐藏的GoHide前,要求用户先输入口令。 [退出GoHide时需要口令] 选中此项,在退出GoHide前,要求用户先输入口令。 [口令设置] 用来设置和更改口令。GoHide只维护一个口令,也就是说,不管上述的哪个选项被选中,需要的口令都是一样的。 8) 其它 [GoHide随Windows启动而自动运行] 选中后,每次启动Windows,GoHide将自动运行。 [当双击GoHide在任务栏通知区域的图标时] 当用鼠标左键双击GoHide在任务栏通知区域的图标时,选则GoHide对应的动作,是“显示/隐藏GoHide本身”还是“隐藏/显示所选的窗口”。

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧