首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows NT 取得處理序完整路徑(補充版):以 SE_DEBUG_NAME 權限突破系統程序限制

     編輯:關於VC++

問題背景

先前發表的《如何在 NT 下獲取進程的路徑》一文中,使用 PSAPI 枚舉處理序並取得模組路徑,但無法存取受保護的系統程序(如 csrss.exe、smss.exe、winlogon.exe)。VCKbase 網友 rovershen 指出:為枚舉處理序授予 SE_DEBUG_NAME 特權即可解決。經查證與實作,確認此法有效,特此補充完善。

核心解法:提升程序權限

自訂函式 EnablePrivilege 用於為目前程序授予指定特權(本例為 SE_DEBUG_NAME):

BOOL EnablePrivilege(HANDLE hToken, LPCSTR szPrivName)
{
    TOKEN_PRIVILEGES tkp;
    // 查詢特權 LUID
    LookupPrivilegeValue(NULL, szPrivName, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    // 通知系統修改權限
    AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL);
    return (GetLastError() == ERROR_SUCCESS);
}

流程:以 OpenProcessToken 取得目前程序存取權杖,呼叫 EnablePrivilege 啟用 SE_DEBUG_NAME,即可用 OpenProcess 開啟系統程序並取得路徑。

完整範例程式碼

////////////////////////////////////////////////
// ShowProcessPath 2.0
// 版權所有 (C) 2005 趙春生
// 2005.09.02
// https://timw.yeah.net / https://timw.126.com
// 適用環境:WinNT 系列
// 測試環境:Win2000 Pro + SP4 + VC6 + SP6
////////////////////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include "PSAPI.H"
#pragma comment(lib, "PSAPI.LIB")

// 自訂函式:授予指定特權
BOOL EnablePrivilege(HANDLE hToken, LPCSTR szPrivName);

int main(void)
{
    DWORD processId[1024], needed, processCount, i;
    HANDLE hProcess;
    HMODULE hModule;
    char path[MAX_PATH] = "", temp[256];
    HANDLE hToken;

    printf("ShowProcessPath 2.0 with [Process Status API]\n\n");

    // 取得目前程序權杖並提升權限
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
    {
        if (EnablePrivilege(hToken, SE_DEBUG_NAME))
        {
            // 列舉所有處理序 ID
            EnumProcesses(processId, sizeof(processId), &needed);
            processCount = needed / sizeof(DWORD);

            for (i = 0; i < processCount; i++)
            {
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId[i]);
                if (hProcess)
                {
                    EnumProcessModules(hProcess, &hModule, sizeof(hModule), &needed);
                    GetModuleFileNameEx(hProcess, hModule, path, sizeof(path));
                    GetShortPathName(path, path, 256);
                    itoa(processId[i], temp, 10);
                    printf("%s --- %s\n", path, temp);
                    CloseHandle(hProcess);
                }
                else
                {
                    printf("Failed!!! (PID: %lu)\n", processId[i]);
                }
            }
        }
    }

    itoa(processCount, temp, 10);
    printf("\nProcess Count: %s\n\n", temp);
    return 0;
}

//////////////////////////////////////////////////////////////////////
BOOL EnablePrivilege(HANDLE hToken, LPCSTR szPrivName)
{
    TOKEN_PRIVILEGES tkp;
    LookupPrivilegeValue(NULL, szPrivName, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL);
    return (GetLastError() == ERROR_SUCCESS);
}

執行結果驗證

加入 SE_DEBUG_NAME 特權後,程式成功列出 csrss.exe、smss.exe、winlogon.exe 等系統程序的完整路徑,解決了原版本無法存取受保護程序的問題。

測試環境

  • 作業系統:Windows 2000 Professional + SP4
  • 開發工具:Visual C++ 6.0 + SP6

本文配套原始碼可供下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved