//Main.pas
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button2: TButton;
cbTaskList: TCheckBox;
cbCAD: TCheckBox;
cbTaskMgr: TCheckBox;
cbTaskKey: TCheckBox;
cbTaskBar: TCheckBox;
procedure cbTaskListClick(Sender: TObject);
private
FRemoteDLL: string;
FTaskList: Boolean;
FTaskKey: Boolean;
FCtrlAltDel: Boolean;
FTaskBar: Boolean;
FTaskMgr: Boolean;
procedure Disable(dwFlags: DWORD; Disabled, Beep: Boolean);
procedure SetTaskBar(const Value: Boolean);
procedure SetTaskKey(const Value: Boolean);
procedure SetTaskList(const Value: Boolean);
procedure SetTaskMgr(const Value: Boolean);
procedure SetCtrlAltDel(const Value: Boolean);
protected
property TaskBar: Boolean read FTaskBar write SetTaskBar;
property TaskMgr: Boolean read FTaskMgr write SetTaskMgr;
property TaskKey: Boolean read FTaskKey write SetTaskKey;
property TaskList: Boolean read FTaskList write SetTaskList;
property CtrlAltDel: Boolean read FCtrlAltDel write SetCtrlAltDel;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
var
Form1: TForm1;
implementation
uses PSAPI, ImageHlp, TlHelp32, CommonFunc, Registry;
{$R *.dfm}
const
TASK_MGR = $01; // disable task manager (Ctrl+Alt+Del)
TASK_KEYS = $02; // disable task keys (Alt-TAB, etc)
TASK_BAR = $04; // disable task bar
TASK_LIST = $08; // disable listing process list
CTRL_ALT_DEL = $10; // disable Ctrl+Alt+Del
TASK_ALL = TASK_MGR or TASK_KEYS or TASK_BAR or TASK_LIST or CTRL_ALT_DEL;
function IsWin2k: Boolean;
begin
Result := (Win32MajorVersion >= 5) and (Win32Platform =
VER_PLATFORM_WIN32_NT);
end;
{ Finally, the following example tests whether Terminal Services is installed. }
function IsTerminalServices: Boolean;
var
OS: TOSVersionInfoEx;
dwlConditionMask: Int64;
begin
FillChar(OS, SizeOf(OS), 0);
OS.dwOSVersionInfoSize := SizeOf(OS);
OS.wSuiteMask := VER_SUITE_TERMINAL;
dwlConditionMask := 0;
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_SUITENAME, VER_AND);
Result := VerifyVersionInfo(@OS, VER_SUITENAME, dwlConditionMask);
end;
function ThreadFuncAttach(pInfo: PInjectLibInfo): DWORD; stdcall;
begin
pInfo^.dwReturnValue := 0;
Result := pInfo^.pfnLoadLibrary(pInfo^.szDllName);
if Result = 0 then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
end;
procedure AfterThreadFuncAttach;
begin
end;
{ 远程线程,用来卸载DLL }
function ThreadFuncDetach(pInfo: PDeinjectLibInfo): DWORD; stdcall;
var
Handle: THandle;
FoundModule: Boolean;
begin
Result := 1;
pInfo^.dwReturnValue := 0; { 意味成功,如果这个值不是0,则是一个错误代码。}
Handle := pInfo^.pfnGetModuleHandle(pInfo^.szDllName);
FoundModule := Handle <> 0;
if FoundModule and not pInfo^.pfnFreeLibrary(Handle) then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
if (pInfo^.dwReturnValue = 0) and not FoundModule then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
end;
procedure AfterThreadFuncDetach;
begin
end;
function EnablePrivilege(lpszPrivilegeName: PChar; Enabled: Boolean): Boolean;
var
luid: Int64;
Token: THandle;
RetLen: Cardinal;
Privileges: TTokenPrivileges;
begin
Result := False;
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or
TOKEN_QUERY or TOKEN_READ, Token) then Exit;
try
Result := not LookupPrivilegeValue(nil, lpszPrivilegeName, luid);
if Result then Exit;
FillChar(Privileges, SizeOf(Privileges), 0);
Privileges.PrivilegeCount := 1;
Privileges.Privileges[0].Luid := luid;
if Enabled then
Privileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(Token, False, Privileges, 0, nil, RetLen);
Result := GetLastError = ERROR_SUCCESS
finally
CloseHandle(Token);
end;
end;
{ 通过进程名称得到进程的ID(这里使用方法Toolhelp函数,因此在NT上无法使用,当然也
可以PSAPI函数,这样就可以在NT上使用了)}
function GetPIDFromName(lpszProcName: PChar): DWORD;
function QueryWithWTS(const ProcName: string): THandle;
var
pSessionInfo: PChar;
dwCurSessionID, dwBytes: DWORD;
I, ProcessCount: DWORD;
ProcessInfo: PWTSProcessInfo;
S: string;
begin
Result := PROCESS_ERROR;
pSessionInfo := nil;
if WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
WTSSessionId, pSessionInfo, dwBytes) then
begin
dwCurSessionID := PDWORD(pSessionInfo)^;
if WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, @ProcessInfo, ProcessCount) then
for I := 0 to ProcessCount - 1 do
begin
S := LowerCase(ProcessInfo^.pProcessName);
if (Pos(ProcName, S) > 0) and (dwCurSessionID = ProcessInfo^.SessionId) then
begin
Result := ProcessInfo^.ProcessId;
break;
end;
Inc(ProcessInfo);
end;
WTSFreeMemory(pSessionInfo);
end;
end;
{ added by jiangsheng 2002-11-8 }
function QueryWithTool(const ProcName: string): THandle;
var
S: string;
Next: Boolean;
SnapShot: THandle;
ProcessEntry: TProcessEntry32;
begin
Result := PROCESS_ERROR;
SnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
FillChar(ProcessEntry, SizeOf(ProcessEntry), 0);
ProcessEntry.dwSize := SizeOf(ProcessEntry);
Next := Process32First(SnapShot, ProcessEntry);
while Next do
begin
S := LowerCase(ProcessEntry.szExeFile);
if Pos(ProcName, S) > 0 then
begin
Result := ProcessEntry.th32ProcessID;
break;
end;
Next := Process32Next(SnapShot, ProcessEntry);
end;
CloseHandle(SnapShot);
end;
var
S: string;
begin
S := LowerCase(lpszProcName);
if IsTerminalServices then
Result := QueryWithWTS(S)
else
Result := QueryWithTool(S);
end;
procedure RaiseError(const S: string);
begin
raise Exception.CreateFmt(S, [SysErrorMessage(GetLastError)]);
end;
var
RemoteParam: Pointer = nil;
pRemoteThread: Pointer = nil;
dwRemoteProcess: DWORD = PROCESS_ERROR;
procedure SetCtrlAltDel(ThreadBuffer: Pointer; ThreadSize: DWORD;
LibInfo: Pointer; LibInfoCount: Integer; Inject: Boolean);
var
hRemoteThread: THandle;
Writen, RemoteProcess: DWORD;
begin
if dwRemoteProcess = PROCESS_ERROR then
dwRemoteProcess := GetPIDFromName(RemoteProcessName);
if dwRemoteProcess = PROCESS_ERROR then
RaiseError('Failed to query process ID.');
RemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, False, dwRemoteProcess);
if RemoteProcess = 0 then
RaiseError('Failed to open process: %s');
{ 在远程线程分配内存来存放参数 }
if Assigned(RemoteParam) then
VirtualFreeEx(RemoteProcess, RemoteParam, 0, MEM_RELEASE);
RemoteParam := VirtualAllocEx(RemoteProcess, nil, LibInfoCount,
MEM_COMMIT, PAGE_READWRITE);
if not Assigned(RemoteParam) then
RaiseError('Failed to allocate memory at remote process for param,Err=%s');
if not WriteProcessMemory(RemoteProcess, RemoteParam, LibInfo,
LibInfoCount, Writen) then
RaiseError('Failed to write param to remote process, msg: %s');
{ 拷贝线程体 }
if Assigned(pRemoteThread) then
VirtualFreeEx(RemoteProcess, pRemoteThread, 0, MEM_RELEASE);
pRemoteThread := VirtualAllocEx(RemoteProcess, nil, ThreadSize,
MEM_COMMIT, PAGE_READWRITE);
if not Assigned(pRemoteThread) then
RaiseError('Failed to allocate memory at remote process for thread, code.Err: %s');
if not WriteProcessMemory(RemoteProcess, pRemoteThread, ThreadBuffer,
ThreadSize, Writen) then
RaiseError('Failed to write thread code to remote process code.Err: %s');
{ 启动远程线程 }
hRemoteThread := CreateRemoteThread(RemoteProcess, nil, 0, pRemoteThread,
RemoteParam, 0, Writen);
if hRemoteThread = 0 then
RaiseError('Failed to create unload thread.Err=%s');
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);
{ 读卸载返回值 }
if not ReadProcessMemory(RemoteProcess, RemoteParam, LibInfo,
LibInfoCount, Writen) then
RaiseError('Unable to read load return value.Err=%s')
else
begin
if (Inject and (PInjectLibInfo(LibInfo)^.dwReturnValue <> 0)) or
(not Inject and (PDeinjectLibInfo(LibInfo)^.dwReturnValue <> 0)) then
RaiseError('Failed to load library to Winlogon.Err=%s');
end;
end;
//---------------------------------------------------------------------------
// 插入代码
//---------------------------------------------------------------------------
procedure InjectFunc(const RemoteDllName: string);
procedure InitParam(Param: Pointer; const RemoteDllName: string);
var
Info: PInjectLibInfo;
begin
Info := PInjectLibInfo(Param);
FillChar(Info^, SizeOf(Info^), 0);
Move(RemoteDLLName[1], Info.szDllName[0], Length(RemoteDllName));
Info.pfnLoadLibrary := GetProcAddress(GetModuleHandle(Kernel32),
LoadLibraryFuncStr);
Info.pfnGetLastError := GetProcAddress(GetModuleHandle(Kernel32),
GetLastErrorFuncStr);
end;
var
InjectLibInfo: TInjectLibInfo;
ThreadSize: DWORD;
begin
{ 提升本进程权限然后打开目的进程 }
EnablePrivilege(SE_DEBUG_NAME, True);
try
InitParam(@InjectLibInfo, RemoteDllName);
ThreadSize := DWORD(@AfterThreadFuncAttach) - DWORD(@ThreadFuncAttach) +
1024 + SizeOf(InjectLibInfo);
SetCtrlAltDel(@ThreadFuncAttach, ThreadSize, @InjectLibInfo,
SizeOf(InjectLibInfo), True);
finally
{ 恢复权限 }
EnablePrivilege(SE_DEBUG_NAME, False);
end;
end;
//---------------------------------------------------------------------------
// 卸载线程
//---------------------------------------------------------------------------
procedure DeinjectFunc(const RemoteDllName: string);
procedure InitParam(Param: Pointer; const RemoteDllName: string);
var
Info: PDeinjectLibInfo;
begin
Info := PDeinjectLibInfo(Param);
FillChar(Info^, SizeOf(Info^), 0);
Info.pfnFreeLibrary := GetProcAddress(GetModuleHandle(Kernel32),
FreeLibraryFuncStr);
Info.pfnGetModuleHandle := GetProcAddress(GetModuleHandle(Kernel32),
GetModuleHandleFuncStr);
Info.pfnGetLastError := GetProcAddress(GetModuleHandle(Kernel32),
GetLastErrorFuncStr);
Move(RemoteDLLName[1], Info.szDllName, Length(RemoteDllName));
end;
var
DeinjectLibInfo: TDeinjectLibInfo;
ThreadSize: DWORD;
begin
{ 提升本进程权限然后打开目的进程 }
EnablePrivilege(SE_DEBUG_NAME, True);
try
InitParam(@DeinjectLibInfo, RemoteDllName);
ThreadSize := DWORD(@AfterThreadFuncDetach) - DWORD(@ThreadFuncDetach) +
1024 + SizeOf(DeinjectLibInfo);
SetCtrlAltDel(@ThreadFuncDetach, ThreadSize, @DeinjectLibInfo,
SizeOf(DeinjectLibInfo), False);
finally
{ 恢复权限 }
EnablePrivilege(SE_DEBUG_NAME, False);
end;
end;
{ TForm1 }
constructor TForm1.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
cbTaskList.Tag := TASK_LIST;
cbCAD.Tag := CTRL_ALT_DEL;
cbTaskMgr.Tag := TASK_MGR;
cbTaskKey.Tag := TASK_KEYS;
cbTaskBar.Tag := TASK_BAR;
FTaskList := False;
FTaskKey := False;
FCtrlAltDel := False;
FTaskBar := False;
FTaskMgr := False;
FRemoteDLL := ExtractFilePath(ParamStr(0)) + 'RemoteDll.Dll';
end;
destructor TForm1.Destroy;
begin
Disable(TASK_ALL, False, False);
if Assigned(RemoteParam) then
begin
VirtualFreeEx(dwRemoteProcess, RemoteParam, 0, MEM_RELEASE);
RemoteParam := nil;
end;
if Assigned(pRemoteThread) then
begin
VirtualFreeEx(dwRemoteProcess, pRemoteThread, 0, MEM_RELEASE);
pRemoteThread := nil;
end;
if dwRemoteProcess <> PROCESS_ERROR then
CloseHandle(dwRemoteProcess);
inherited Destroy;
end;
procedure TForm1.Disable(dwFlags: DWORD; Disabled, Beep: Boolean);
begin
if not IsWin2K then
raise Exception.Create('Work in W2K');
if (dwFlags and TASK_MGR) = TASK_MGR then
TaskMgr := Disabled;
if (dwFlags and TASK_KEYS) = TASK_KEYS then
TaskKey := Disabled;
if (dwFlags and TASK_BAR) = TASK_BAR then
TaskBar := Disabled;
if (dwFlags and TASK_List) = TASK_LIST then
TaskList := Disabled;
if (dwFlags and CTRL_ALT_DEL) = CTRL_ALT_DEL then
CtrlAltDel := Disabled;
end;
procedure TForm1.cbTaskListClick(Sender: TObject);
var
CheckBox: TCheckBox;
begin
CheckBox := TCheckBox(Sender);
Disable(CheckBox.Tag, CheckBox.Checked, False);
end;
procedure TForm1.SetTaskBar(const Value: Boolean);
var
Handle: THandle;
begin
if Value = FTaskBar then Exit;
Handle := FindWindow('Shell_traywnd', nil);
EnableWindow(Handle, not Value);
FTaskBar := Value;
end;
procedure TForm1.SetTaskKey(const Value: Boolean);
begin
if FTaskKey = Value then Exit;
FTaskKey := Value;
{ TaskKeyHook.dsw }
end;
procedure TForm1.SetTaskList(const Value: Boolean);
begin
if FTaskList = Value then Exit;
FTaskList := Value;
{ HookApi.dsw }
end;
procedure TForm1.SetTaskMgr(const Value: Boolean);
const
KEY_DisableTaskMgr = 'Software/Microsoft/Windows/CurrentVersion/Policies/System';
VAL_DisableTaskMgr = 'DisableTaskMgr';
begin
if FTaskMgr = Value then Exit;
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey(KEY_DisableTaskMgr, False) then
WriteInteger(VAL_DisableTaskMgr, Integer(Value));
CloseKey;
FTaskMgr := Value;
finally
Free;
end;
end;
procedure TForm1.SetCtrlAltDel(const Value: Boolean);
begin
if FCtrlAltDel = Value then Exit;
if not FileExists(FRemoteDll) then
raise Exception.CreateFmt('file not find: %s', [FRemoteDll]);
if Value then
InjectFunc(FRemoteDll)
else
DeinjectFunc(FRemoteDll);
FCtrlAltDel := Value;
end;
end.
//Main.dfm
object Form1: TForm1
Left = 222
Top = 171
Width = 485
Height = 278
Caption = 'Form1'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 12
object Button2: TButton
Left = 32
Top = 216
Width = 75
Height = 25
Caption = 'E&xit'
TabOrder = 0
end
object cbTaskList: TCheckBox
Left = 32
Top = 56
Width = 401
Height = 25
Caption = 'Disable listing in Process List'
TabOrder = 1
OnClick = cbTaskListClick
end
object cbCAD: TCheckBox
Left = 32
Top = 88
Width = 409
Height = 17
Caption = 'Disable Ctrl+Alt+Delete'
TabOrder = 2
OnClick = cbTaskListClick
end
object cbTaskMgr: TCheckBox
Left = 32
Top = 112
Width = 401
Height = 25
Caption = 'Disable Task &Manager (winnt//system32//taskmgr.exe)'
TabOrder = 3
OnClick = cbTaskListClick
end
object cbTaskKey: TCheckBox
Left = 32
Top = 144
Width = 401
Height = 17
Caption = 'Disable Task &Keys (Alt-TAB, Ctl-Esc, Alt-Esc), Start Menu'
TabOrder = 4
OnClick = cbTaskListClick
end
object cbTaskBar: TCheckBox
Left = 32
Top = 168
Width = 409
Height = 25
Caption = 'Disable Task&bar'
TabOrder = 5
OnClick = cbTaskListClick
end
end
//////////////////////////////////////////////////////////////
CommonFunc.pas应该没改。
应该可以了。