Win2000/XP下屏蔽CTRL+ALT+DEL的一种方法
思路:修改Winlogon进程中Msgina.dll导出的WlxLoggedOnSAS函数里的一个跳转指令。
跳转指令的偏移可以反汇编Msgina.dll的WlxLoggedOnSAS或用SoftIce跟踪出来。
以下源码在WinXP Professional SP1, Win2000 Professional SP3,SP4 运行通过:
Option Explicit
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Const SE_DEBUG_NAME = "SeDebugPrivilege"
Private Type LUID
UsedPart As Long
IgnoredForNowHigh32BitPart As Long
End Type
Private Type LUID_AND_ATTRIBUTES
TheLuid As LUID
Attributes As Long
End Type
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
TheLuid As LUID
Attributes As Long
End Type
Private Declare Function GetLastError Lib "kernel32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long
Private Declare Sub SetLastError Lib "kernel32" (ByVal dwErrCode As Long)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private m_BuildNumber As Long
Private Sub AdjustToken()
‘********************************************************************
‘* This procedure sets the proper privileges to allow a log off or a
‘* shut down to occur under Windows NT.
‘********************************************************************
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
Dim hdlProcessHandle As Long
Dim hdlTokenHandle As Long
Dim tmpLuid As LUID
Dim tkp As TOKEN_PRIVILEGES
Dim tkpNewButIgnored As TOKEN_PRIVILEGES
Dim lBufferNeeded As Long
‘Set the error code of the last thread to zero using the
‘SetLast Error function. Do this so that the GetLastError
‘function does not return a value other than zero for no
‘apparent reason.
SetLastError 0
‘Use the GetCurrentProcess function to set the hdlProcessHandle
‘variable.
hdlProcessHandle = GetCurrentProcess()
If GetLastError <> 0 Then
MsgBox "GetCurrentProcess error==" & GetLastError
End If
OpenProcessToken hdlProcessHandle, _
(TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle
If GetLastError <> 0 Then
MsgBox "OpenProcessToken error==" & GetLastError
End If
‘Get the LUID for shutdown privilege
LookupPrivilegeValue "", SE_DEBUG_NAME, tmpLuid
If GetLastError <> 0 Then
MsgBox "LookupPrivilegeValue error==" & GetLastError
End If
tkp.PrivilegeCount = 1 ‘ One privilege to set
tkp.TheLuid = tmpLuid
tkp.Attributes = SE_PRIVILEGE_ENABLED
‘Enable the shutdown privilege in the access token of this process
AdjustTokenPrivileges hdlTokenHandle, _
False, _
tkp, _
Len(tkpNewButIgnored), _
tkpNewButIgnored, _
lBufferNeeded
If GetLastError <> 0 Then
MsgBox "AdjustTokenPrivileges error==" & GetLastError
End If
End Sub
Private Sub DisableHotKey(PId As Long, Optional bDisabled As Boolean = True)
Dim hHandle As Long, hFunAddr As Long
Dim hTagAddr As Long
Dim lpBuffer(1) As Byte
Dim hProcess As Long
On Error GoTo errhandle
hHandle = GetModuleHandle("msgina.dll")
If hHandle = 0 Then
hHandle = LoadLibrary("msgina.dll")
If hHandle = 0 Then Exit Sub
End If
hFunAddr = GetProcAddress(hHandle, "WlxLoggedOnSAS")
If hFunAddr = 0 Then
FreeLibrary hHandle
Exit Sub
End If
If m_BuildNumber = 2195 Then
hTagAddr = hFunAddr + &HDE&
ElseIf m_BuildNumber = 2600 Then
hTagAddr = hFunAddr + &HE6&
End If
Debug.Print Hex(hHandle), Hex(hFunAddr), Hex(hTagAddr)
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, PId)
If hProcess = 0 Then
Call AdjustToken
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, PId)
End If
ReadProcessMemory hProcess, ByVal hTagAddr, lpBuffer(0), 2, 0
If bDisabled Then
lpBuffer(0) = &H74 ‘JE
Else
lpBuffer(0) = &H75 ‘JNE
End If
WriteProcessMemory hProcess, ByVal hTagAddr, lpBuffer(0), 2, 0
CloseHandle hProcess
Exit Sub
errhandle:
MsgBox Err.Description
End Sub
Private Sub Command1_Click()
On Error GoTo errhandle
If m_BuildNumber <> 0 Then
DisableHotKey CLng(Text1.Text), CBool(Check1.Value)
End If
Exit Sub
errhandle:
MsgBox Err.Description
End Sub
Private Sub GetWinVersion()
Dim OSInfo As OSVERSIONINFO, PId As String
Dim Ret As Long, strRet As String
OSInfo.dwOSVersionInfoSize = Len(OSInfo)
Ret = GetVersionEx(OSInfo)
If Ret = 0 Then MsgBox "Error Getting Version Information": Exit Sub
If OSInfo.dwPlatformId = 2 Then
m_BuildNumber = OSInfo.dwBuildNumber
End If
End Sub
Private Sub Form_Load()
GetWinVersion
End Sub