我在写一套网吧管理系统,为了不让上网者退出管理程序,必须把Ctrl+Alt+Del热键屏闭,防止把管理程序的进程结束!
我用的方法是每0.5秒检查一下是否有任务管理器的窗口句柄,如果有则关闭。这样的方法用了好一阵,但此方法只能蒙一些菜鸟,对于高手还是无用武之地!
希望高手们看到此贴后不论有没有更好的方法都请回个贴,相互学习!回贴一律给分!
我用的方法是每0.5秒检查一下是否有任务管理器的窗口句柄,如果有则关闭。这样的方法用了好一阵,但此方法只能蒙一些菜鸟,对于高手还是无用武之地!
希望高手们看到此贴后不论有没有更好的方法都请回个贴,相互学习!回贴一律给分!
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);
具体的你可以到网上去搜一下,参考一下以前的win2k下面的做法。
收藏,顶一下!
想知道答案的兄弟都签个名吧!!!UP
如果你还找不到,到这里:http://lysoft.lz169.com/kingron/index.asp
找找,或问问
郁闷
其实也不是很难
最好把进程也隐藏掉,可以用插入其他进程的方法,或是在进程的链表删除自己的进程方法比较多...
替换Gina.dll
键盘钩子
定时关闭任务管理器
winlogon线程注入如果仅仅是屏蔽一下Ctrl+alt+del,键盘钩子完全可以应付了.
最优方案当然是替换Gina.dll,是彻底解决方案.
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)就可进入了,或者进入
安全模式,删除掉那个键值。
http://www.consult.sx.cn/DisableCtrlAltDel.rar只能屏蔽这三个键,任务管理器,需要在组策略中屏蔽,或者写注册表
我注册过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); //×¢ÏúHotKey£¬ ÊÍ·Å×ÊÔ´¡£
end;
procedure Tform1.HotKeyDown(var Msg: Tmessage);
begin
end;end.
有现成的代码下载,呵呵
就是ARI所说的那里:)
http://lysoft.lz169.com/projects/No Ctrl+Alt+Del.rar
送你一个代码吧,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.
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;
的方法不错,等我试先!
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.
键盘钩子是不行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
含DLL的源码的
用Wintask工具加载SASWinHook.DLL到WinLogon.Exe,马上有效果该是揭帖了