文章編號: 185215 - 上次校閱: 2004年7月13日 - 版次: 2.1

如何使用 [SeDebugPrivilege 來取得任何處理序控制代碼

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

藉由在執行中的處理序上設定 SeDebugPrivilege 權限,您可以取得處理序控制代碼的任何執行中的應用程式。取得處理序控制代碼時, 您可以指定 PROCESS_ALL_ACCESS 旗標可讓您通常無法執行該處理序控制代碼時的各種 Win32 API 呼叫。可以成功地呼叫 Win32 API 包括下列:
  • TerminateProcess
  • CreateRemoteThread
本文包含如何您可以根據您的應用程式處理序語彙基元,設定 [SeDebugPrivilege 和用它來終止另一個應用程式上的深入的範例。這是進階的主題,強烈建議您具有強式的處理序安全性知識。

何種處理程序存取、 處理序語彙基元和語彙基元的權限未涵蓋範圍內的這篇文章的討論。本文假設讀者已經了解這些進階的主題。

其他相關資訊

這個範例牽涉到建立三個不同的 Visual Basic 應用程式。 每個應用程式會建置一次一個,並再一起用來示範 SeDebugPrivilege 程序權限的能力。

應用程式 # 1 (Term01.exe)

  1. 建立新的標準 EXE 專案在 Visual Basic 5.0 時。
  2. 專案名稱改 Term01。
  3. 重新命名 frmTerm01 Form1。
  4. 新增 frmTerm01 指令按鈕。
  5. 設定標號的 Command1 終止記事本。
  6. 將下列程式碼加入至 frmTerm01:
          Option Explicit
    
          Private Sub Command1_Click()
    
             ' This is a simple application that attempts
             ' to shut down any process that is passed in through
             ' the command line.
    
             Call TerminateProcess(CLng(Command$), 0)
    
          End Sub
    
    						
  7. 將標準模組新增到專案,並將其重新命名以 MdlApi01。
  8. 將下列程式碼加入至 MdlApi01:
          Option Explicit
    
          Declare Function TerminateProcess Lib "kernel32" _
             (ByVal hProcess As Long, _
             ByVal uExitCode As Long) As Long
    
    						
  9. 儲存專案,並進行 exe 檔案 (Term01.exe)。

應用程式 # 2 (Term02.exe)

  1. 在 Visual Basic 5.0 中建立新的標準執行檔。
  2. 專案名稱改 Term02。
  3. 重新命名 frmTerm02 Form1。
  4. 新增 frmTerm02 指令按鈕。
  5. 設定標號的 Command1 終止記事本。
  6. 加入 frmTerm02 清單方塊。
  7. 設定的 ListBox1 寬度至 3735。
  8. 將下列程式碼加入至 frmTerm02:
          Private Sub Command1_Click()
    
             ' The PID of the application you want to kill will be received
             ' through the command line. Convert it to a long so it can be
             ' used with the various API calls.
    
             SeDebugSample CLng(Command$)
    
          End Sub
    
    						
  9. 將標準模組新增到專案,並將其重新命名以 mdlAPI02。
  10. 將下列程式碼加入至模組 mdlApi02:
          Option Explicit
    
          ' Constants used for various API calls. Refer to MSDN for detailed
          ' information about what these constants mean.
    
          Public Const TOKEN_ADJUST_PRIVILEGES = &H20
          Public Const TOKEN_QUERY = &H8
          Public Const ANYSIZE_ARRAY = 1
          Public Const PROCESS_ALL_ACCESS = &H1F0FFF
          Public Const SE_DEBUG_NAME = "SeDebugPrivilege"
          Public Const SE_PRIVILEGE_ENABLED = &H2
    
          ' Structures used with various API calls.
          ' Refer to MSDN for detailed information
          ' about what these structures are, and how they are used.
    
          Type LARGE_INTEGER
             lowpart As Long
             highpart As Long
          End Type
    
          Type Luid
             lowpart As Long
             highpart As Long
          End Type
    
          Type LUID_AND_ATTRIBUTES
             pLuid As Luid
             Attributes As Long
          End Type
    
          Type TOKEN_PRIVILEGES
             PrivilegeCount As Long
             Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
          End Type
    
          ' Refer to the MSDN for detailed information on
          ' all of these API calls.
    
          Declare Function CloseHandle Lib "kernel32" _
             (ByVal hObject As Long)As Long
          Declare Function GetCurrentProcess Lib "kernel32" () As Long
          Declare Function OpenProcessToken Lib "advapi32.dll" _
             (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, _
          TokenHandle As Long) As Long
          Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias _
             "LookupPrivilegeValueA" (ByVal lpSystemName As String, _
             ByVal lpName As String, lpLuid As Luid) As Long
          Declare Function AdjustTokenPrivileges Lib "advapi32.dll" _
             (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
          Declare Function OpenProcess Lib "kernel32" _
             (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
             ByVal dwProcessId As Long) As Long
          Declare Function TerminateProcess Lib "kernel32" _
             (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
    
          ' SeDebugSample shows how to grab the Process Handle of any running
          ' Application, and then use the SeDebug privilege to shut it down.
    
          Public Sub SeDebugSample(ApplicationPID As Long)
             Dim hProcessID As Long         ' Handle to your sample
                                            ' process you are going to
                                            ' terminate.
             Dim hProcess As Long           ' Handle to your current process
                                            ' (Term02.exe).
             Dim hToken As Long             ' Handle to your process token.
             Dim lPrivilege As Long         ' Privilege to enable/disable
             Dim iPrivilegeflag As Boolean  ' Flag whether to enable/disable
                                            ' the privilege of concern.
             Dim lResult As Long            ' Result call of various APIs.
    
             ' clear the list box first
             frmTerm02.List1.Clear
             frmTerm02.List1.AddItem "Start SeDebug Sample"
    
             ' set the incoming PID to our internal variable
             hProcessID = ApplicationPID
    
             ' get our current process handle
             hProcess = GetCurrentProcess
    
             ' show our handle just for fun
             frmTerm02.List1.AddItem "Current (Pseudo) Process Handle : " & _
                                     Hex(hProcess)
    
             ' open the tokens for this process (Term02.exe)
             lResult = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES Or _
                                       TOKEN_QUERY, hToken)
    
             ' if OpenProcessToken fails, the return result is zero, test for
             ' success here
    
             If (lResult = 0) Then
             frmTerm02.List1.AddItem "Error: _
                                     Unable To Open Process Token : " _
                                     & Err.LastDllError
                CloseHandle (hToken)
                Exit Sub
             Else
                ' show success
                frmTerm02.List1.AddItem "Opened Process Token : " & hToken
             End If
    
             ' Now that you have the token for this process, you want to set
             ' the SE_DEBUG_NAME privilege.
    
             lResult = SetPrivilege(hToken, SE_DEBUG_NAME, True)
    
             ' Make sure you could set the privilege on this token.
    
             If (lResult = False) Then
                frmTerm02.List1.AddItem _
                   "Error : Could Not Set SeDebug Privilege on Token Handle"
                CloseHandle (hToken)
                Exit Sub
             Else
                frmTerm02.List1.AddItem "Set SeDebug Privilege On Token Handle"
             End If
    
             ' Now that you have changed the privileges on the token,
             ' have some fun. You can now get a process handle to the
             ' process ID that you passed into this program, and
             ' demand whatever access you want on it!
    
             hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, hProcessID)
    
             ' Make sure you opened the process so you can do stuff with it
             If (hProcess = Null) Then
                frmTerm02.List1.AddItem _
                   "Error : Unable To Open Process : " & Err.LastDllError
                CloseHandle (hToken)
                Exit Sub
             Else
                frmTerm02.List1.AddItem "Opened Process : " & hProcess
             End If
    
             ' Now turn the SE_DEBUG_PRIV back off,
             lResult = SetPrivilege(hToken, SE_DEBUG_NAME, False)
    
             ' Make sure you succeeded in reversing the privilege!
             If (lResult = False) Then
                frmTerm02.List1.AddItem _
                  "Error : Unable To Disable SeDebug Privilege On Token Handle"
                CloseHandle (hProcess)
                CloseHandle (hToken)
                Exit Sub
             Else
                frmTerm02.List1.AddItem _
                   "Disabled SeDebug Privilege On Token Handle"
             End If
    
             ' Now you want to kill the application, which you can do since
             ' your process handle to the application includes full access to
             ' romp and roam - you got the process handle when you had the
             ' SE_DEBUG_NAME privilege enabled!
             lResult = TerminateProcess(hProcess, 0)
    
             ' Let's see the result, and go from there.
             If (lResult = 0) Then
                frmTerm02.List1.AddItem _
                "Error : Unable To Terminate Application : " & Err.LastDllError
                CloseHandle (hProcess)
                CloseHandle (hToken)
                Exit Sub
             Else
                frmTerm02.List1.AddItem "Terminated Application"
             End If
    
             ' Close our handles and get out of here.
             CloseHandle (hProcess)
             CloseHandle (hToken)
    
             ' Finally, let the user know that you have completed the
             ' SeDebug Sample.
             frmTerm02.List1.AddItem "SeDebug Sample Completed"
    
          End Sub
    
          ' The SetPrivilege function will accept a handle to a token, a
          ' privilege, and a flag to either enable/disable that privilege. The
          ' function will attempt to perform the desired action upon the token
          ' returning TRUE if it succeeded, or FALSE if it failed.
    
          Private Function SetPrivilege(hToken As Long, Privilege As String, _
                                        bSetFlag As Boolean) As Boolean
    
             Dim TP As TOKEN_PRIVILEGES          ' Used in getting the current
                                                 ' token privileges
             Dim TPPrevious As TOKEN_PRIVILEGES  ' Used in setting the new
                                                 ' token privileges
             Dim Luid As Luid                    ' Stores the Local Unique
                                                 ' Identifier - refer to MSDN
             Dim cbPrevious As Long              ' Previous size of the
                                                 ' TOKEN_PRIVILEGES structure
             Dim lResult As Long                 ' Result of various API calls
    
             ' Grab the size of the TOKEN_PRIVILEGES structure,
             ' used in making the API calls.
             cbPrevious = Len(TP)
    
             ' Grab the LUID for the request privilege.
             lResult = LookupPrivilegeValue("", Privilege, Luid)
    
             ' If LoopupPrivilegeValue fails, the return result will be zero.
             ' Test to make sure that the call succeeded.
             If (lResult = 0) Then
                SetPrivilege = False
             End If
    
             ' Set up basic information for a call.
             ' You want to retrieve the current privileges
             ' of the token under concern before you can modify them.
             TP.PrivilegeCount = 1
             TP.Privileges(0).pLuid = Luid
             TP.Privileges(0).Attributes = 0
             SetPrivilege = lResult
    
             ' You need to acquire the current privileges first
             lResult = AdjustTokenPrivileges(hToken, -1, TP, Len(TP), _
                                            TPPrevious, cbPrevious)
    
             ' If AdjustTokenPrivileges fails, the return result is zero,
             ' test for success.
             If (lResult = 0) Then
                SetPrivilege = False
             End If
    
             ' Now you can set the token privilege information
             ' to what the user is requesting.
             TPPrevious.PrivilegeCount = 1
             TPPrevious.Privileges(0).pLuid = Luid
    
             ' either enable or disable the privilege,
             ' depending on what the user wants.
             Select Case bSetFlag
                Case True: TPPrevious.Privileges(0).Attributes = _
                           TPPrevious.Privileges(0).Attributes Or _
                           (SE_PRIVILEGE_ENABLED)
                Case False: TPPrevious.Privileges(0).Attributes = _
                            TPPrevious.Privileges(0).Attributes Xor _
                            (SE_PRIVILEGE_ENABLED And _
                            TPPrevious.Privileges(0).Attributes)
             End Select
    
             ' Call adjust the token privilege information.
             lResult = AdjustTokenPrivileges(hToken, -1, TPPrevious, _
                                            cbPrevious, TP, cbPrevious)
    
             ' Determine your final result of this function.
             If (lResult = 0) Then
                ' You were not able to set the privilege on this token.
                SetPrivilege = False
             Else
                ' You managed to modify the token privilege
                SetPrivilege = True
             End If
    
          End Function
    
    						
  11. 將專案儲存到相同 Term01] 專案的目錄,並進行.exe 檔案 (Term02.exe)。

應用程式 # 3 (MainTest.exe)

  1. 在 Visual Basic 5.0 中建立新的標準 EXE 專案。
  2. 重新命名專案至 MainTest。
  3. 重新命名 Form1 收 frmTest。
  4. 將三個命令按鈕加入至表單。
  5. 設定標號的 Command1 啟動記事本。
  6. 設定標號的 Command2 開始 Term01。
  7. 設定標號的 Command3 開始 Term02。
  8. 將下列程式碼加入至 frmTest:
          Option Explicit
    
          ' You want to keep the process ID of the NotePad instance
          ' that you create
          Private iAppPID As Long
    
          Private Sub Command1_Click()
    
             ' Create an instance of the NotePad.exe application.
             iAppPID = Shell("Notepad.exe", vbNormalFocus)
    
          End Sub
    
          Private Sub Command2_Click()
    
             ' You will try to terminate the NotePad application by another
             ' application, which is running in its own process space.
             ' This will FAIL.
    
             Call Shell(App.Path & "\Term01.Exe " & iAppPID, vbNormalFocus)
    
          End Sub
    
          Private Sub Command3_Click()
    
             ' You will try to terminate the NotePad application by another
             ' application, which is running in its own process space.
             ' However, this application is going to use the SeDebugPrivilege,
             ' and will be able to terminate the application without a fuss.
    
             Call Shell(App.Path & "\Term02.Exe " & iAppPID, vbNormalFocus)
    
          End Sub
    
    						
  9. 將專案儲存到相同 Term01] 專案的目錄,並進行.exe 檔案 (MainTest.exe)。

執行範例

當您建置並編譯三個應用程式時,您可以看到動作中的示範。第二個應用 (Term02.exe) 中, 程式碼會假設 [記事本] 應用程式 (Notepad.exe) 是位於在路徑中。
  1. 執行 MainTest.exe 程式。這是為示範我們"控制板 」。
  2. 按一下 [啟動 [記事本] 按鈕。這會啟動 [記事本]。
  3. 按一下 [開始] Term01] 按鈕。這會啟動 [Term01 應用程式。
  4. 按一下 [結束] 記事本按鈕 Term01 應用程式上]。它用來關閉 [記事本],但不會成功。
  5. 關閉 Term01 應用程式。
  6. 按一下 MainTest 應用程式上的 [開始 Term02] 按鈕。這會啟動 Term02 應用程式。
  7. 按一下 Term02 應用程式上的 [結束 [記事本]] 按鈕。這會啟動 SeDebugPrivilege 示範將導致 「 記事本 」 被終止。清單方塊提供視覺回饋以什麼程序中進行。

這篇文章中的資訊適用於:
  • Microsoft Visual Basic Control Creation Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
關鍵字:?
kbmt kbcode kbhowto KB185215 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:185215? (http://support.microsoft.com/kb/185215/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。
Retired KB Article依現狀不再更新的知識庫內容免責聲明
本文旨在說明 Microsoft 不再提供支援的產品。因此,本文係依「現狀」提供,不會再更新。