文章編號: 131065 - 上次校閱: 2006年11月21日 - 版次: 5.4
如何取得與 SeDebugPrivilege 任何處理序的控制代碼
系統提示 本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。
在 Microsoft Windows NT、 Microsoft Windows 2000 和 Microsoft Windows Server 2003,您可以藉由啟用 SeDebugPrivilege 呼叫的程序中的任何處理序的控制代碼擷取系統中。呼叫處理程序可以再呼叫 OpenProcess() Win32 API 來取得 PROCESS_ALL_ACCESS 的控制代碼。
這項功能被提供給系統層級偵錯。偵錯非系統處理程序,它並不需要授與或啟用這項特殊權限。
此特殊權限可讓呼叫端處理程序包括能力上目標處理序呼叫 TerminateProcess()、 CreateRemoteThread() 及其他潛在危險的 Win32 API 的所有存取。
SeDebugPrivilege 授與給使用者或群組時,要花很棒的照顧。
範例程式碼 下列的原始程式碼會說明如何取得 SeDebugPrivilege 才能取得 PROCESS_ALL_ACCESS 與處理程序的控制代碼。範例程式碼接著會呼叫 TerminateProcess 上結果的處理序控制代碼。
--*/
#define RTN_OK 0
#define RTN_USAGE 1
#define RTN_ERROR 13
#include <windows.h>
#include <stdio.h>
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
);
void DisplayError(LPTSTR szAPI);
int main(int argc, char *argv[])
{
HANDLE hProcess;
HANDLE hToken;
int dwRetVal=RTN_OK; // assume success from main()
// show correct usage for kill
if (argc != 2)
{
fprintf(stderr,"Usage: %s [ProcessId]\n", argv[0]);
return RTN_USAGE;
}
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
if (!ImpersonateSelf(SecurityImpersonation))
return RTN_ERROR;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
DisplayError("OpenThreadToken");
return RTN_ERROR;
}
}
else
return RTN_ERROR;
}
// enable SeDebugPrivilege
if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
{
DisplayError("SetPrivilege");
// close token handle
CloseHandle(hToken);
// indicate failure
return RTN_ERROR;
}
// open the process
if((hProcess = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
atoi(argv[1]) // PID from commandline
)) == NULL)
{
DisplayError("OpenProcess");
return RTN_ERROR;
}
// disable SeDebugPrivilege
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
if(!TerminateProcess(hProcess, 0xffffffff))
{
DisplayError("TerminateProcess");
dwRetVal=RTN_ERROR;
}
// close handles
CloseHandle(hToken);
CloseHandle(hProcess);
return dwRetVal;
}
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
//
// first pass. get current privilege setting
//
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) return FALSE;
//
// second pass. set privilege based on previous setting
//
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}
AdjustTokenPrivileges(
hToken,
FALSE,
&tpPrevious,
cbPrevious,
NULL,
NULL
);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
}
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp = { 0 };
// Initialize everything to zero
LUID luid;
DWORD cb=sizeof(TOKEN_PRIVILEGES);
if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
} else {
tp.Privileges[0].Attributes = 0;
}
AdjustTokenPrivileges( hToken, FALSE, &tp, cb, NULL, NULL );
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
void DisplayError(
LPTSTR szAPI // pointer to failed API name
)
{
LPTSTR MessageBuffer;
DWORD dwBufferLength;
fprintf(stderr,"%s() error!\n", szAPI);
if(dwBufferLength=FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
GetSystemDefaultLangID(),
(LPTSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten;
//
// Output message string on stderr
//
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
//
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}
}
這篇文章中的資訊適用於: Microsoft Win32 Application Programming Interface?應用於: Microsoft Windows Server 2003, Standard Edition (32-bit x86) Microsoft Windows Server 2003, Enterprise Edition (32-bit x86) Microsoft Windows 2000 Advanced Server Microsoft Windows 2000 Server Microsoft Windows 2000 Professional Edition Microsoft Windows NT Advanced Server 3.1 Microsoft Windows NT Server 3.5 Microsoft Windows NT Server 3.51 Microsoft Windows NT Server 4.0 Standard Edition Microsoft Windows NT Workstation 3.1 Microsoft Windows NT Workstation 3.5 Microsoft Windows NT Workstation 3.51 Microsoft Windows NT Workstation 4.0 Developer Edition kbmt kbbug kbdebug kbhowto kbkernbase kbsecurity KB131065 KbMtzh
機器翻譯 重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:
131065 ?
(http://support.microsoft.com/kb/131065/en-us/
)
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。
請說明您希望我們對本篇文章進行什麼改善及需要改善的原因
謝謝您!您的意見將協助我們改進支援內容。如需更多協助選項,請造訪
說明及支援首頁 。