【问题标题】:Get Process Username c++获取进程用户名 c++
【发布时间】:2011-06-15 14:45:20
【问题描述】:

我正在制作一个类似 app 的任务管理器。对于windows,我可以得到所有的系统进程,现在我想得到进程的用户名。我从网上得到了代码。

void enableDebugPrivileges()
{
    HANDLE hcurrent=GetCurrentProcess();
    HANDLE hToken;
    BOOL bret=OpenProcessToken(hcurrent,40,&hToken);
    LUID luid;
    bret=LookupPrivilegeValue(NULL,SE_LOAD_DRIVER_NAME, &luid);
    TOKEN_PRIVILEGES NewState,PreviousState;
    DWORD ReturnLength;
    NewState.PrivilegeCount =1;
    NewState.Privileges[0].Luid =luid;
    NewState.Privileges[0].Attributes=2;
    AdjustTokenPrivileges(hToken,FALSE,&NewState,28,&PreviousState,&ReturnLength);
}

char *GetProcessUsername(HANDLE *phProcess, BOOL bIncDomain) 
{
    static char sname[300];
    HANDLE tok = 0;
    HANDLE hProcess;
    TOKEN_USER *ptu;
    DWORD nlen, dlen;
    char name[300], dom[300], tubuf[300], *pret = 0;
    int iUse;

    //if phProcess is NULL we get process handle of this
    //process.
    hProcess = phProcess?*phProcess:GetCurrentProcess();

    //open the processes token
    if (!OpenProcessToken(hProcess,TOKEN_QUERY,&tok)) goto ert;

    //get the SID of the token
    ptu = (TOKEN_USER*)tubuf;
    if (!GetTokenInformation(tok,(TOKEN_INFORMATION_CLASS)1,ptu,300,&nlen)) goto ert;

    //get the account/domain name of the SID
    dlen = 300;
    nlen = 300;
    if (!LookupAccountSidA(0, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto ert;


    //copy info to our static buffer
    if (dlen && bIncDomain) {
    strcpy(sname,dom);
    strcat(sname,"");
    strcat(sname,name);
    } else {
    strcpy(sname,name);
    }
    //set our return variable
    pret = sname;

    ert:
    if (tok) CloseHandle(tok);
    return pret;
}
int main(){
    enableDebugPrivileges();
    DWORD dwPID=3436;        
    HANDLE  hProcess_i = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPID);
    printf("%s",GetProcessUsername(&hProcess_i,0));
}

它适用于系统和当前。用户进程,但不适用于 NETWORK SERVICE 和 LOCAL SERVICES,我得到了空字符串。请告诉我如何获得这些进程的用户名。 谢谢。

【问题讨论】:

    标签: c++ visual-studio visual-c++ process


    【解决方案1】:

    IIRC 有一个名为 LocalService 的单独伪帐户,但它不在正常的安全系统中(因此你得到一个空字符串)。还有一个 NetworkService 帐户。

    【讨论】:

    • 特别是,这些具有所谓的“知名 SID”。您将从进程令牌中找到的 SID 与众所周知的 SID 列表进行比较,如果有任何匹配,则打印众所周知的名称并跳过在目录中进行查找(域的 Active Directory 或本地帐户的 SAM)。
    • 在此处查看预定义(“知名”)SID 的字典:support.microsoft.com/en-us/help/243330/…
    【解决方案2】:

    我还使用了从网上获得的代码并使用了您的 GetUserName() 部分(感谢分享),它运行良好。我用的是VS2019。我正在一行中打印进程、PID 和用户名。

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    #include <psapi.h>
    
    void enableDebugPrivileges()
    {
        HANDLE hcurrent = GetCurrentProcess();
        HANDLE hToken;
        BOOL bret = OpenProcessToken(hcurrent, 40, &hToken);
        LUID luid;
        bret = LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &luid);
        TOKEN_PRIVILEGES NewState, PreviousState;
        DWORD ReturnLength;
        NewState.PrivilegeCount = 1;
        NewState.Privileges[0].Luid = luid;
        NewState.Privileges[0].Attributes = 2;
        AdjustTokenPrivileges(hToken, FALSE, &NewState, 28, &PreviousState, &ReturnLength);
    }
    
    char* GetProcessUsername(HANDLE* phProcess, BOOL bIncDomain)
    {
        static char sname[300];
        HANDLE tok = 0;
        HANDLE hProcess;
        TOKEN_USER* ptu;
        DWORD nlen, dlen;
        char name[300], dom[300], tubuf[300], * pret = 0;
        int iUse;
    
        //if phProcess is NULL we get process handle of this
        //process.
        hProcess = phProcess ? *phProcess : GetCurrentProcess();
    
        //open the processes token
        if (!OpenProcessToken(hProcess, TOKEN_QUERY, &tok)) goto ert;
    
        //get the SID of the token
        ptu = (TOKEN_USER*)tubuf;
        if (!GetTokenInformation(tok, (TOKEN_INFORMATION_CLASS)1, ptu, 300, &nlen)) goto ert;
    
        //get the account/domain name of the SID
        dlen = 300;
        nlen = 300;
        if (!LookupAccountSidA(0, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto ert;
    
    
        //copy info to our static buffer
        if (dlen && bIncDomain) {
            strcpy_s(sname, dom);
            strcat_s(sname, "");
            strcat_s(sname, name);
        }
        else {
            strcpy_s(sname, name);
        }
        //set our return variable
        pret = sname;
    
    ert:
        if (tok) CloseHandle(tok);
        return pret;
    }
    
    // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
    // and compile with -DPSAPI_VERSION=1
    
    void PrintProcessNameAndID( DWORD processID )
    {
        TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
        HMODULE hMod;
        DWORD cbNeeded;
    
        // Get a handle to the process.
    
        HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                       PROCESS_VM_READ,
                                       FALSE, processID );
    
        // Get the process name.
    
        if (NULL != hProcess )
        {
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
                 &cbNeeded) )
            {
                GetModuleBaseName( hProcess, hMod, szProcessName, 
                                   sizeof(szProcessName)/sizeof(TCHAR) );
            }
        }
    
        if (!_tcscmp(szProcessName, _T("svchost.exe"))) {
             _tprintf(TEXT("%s  PID: %u "), szProcessName, processID);
             printf("User Name: %s\n", GetProcessUsername(&hProcess, 0));
        }
    
        // Release the handle to the process.
    
        if (NULL != hProcess) 
        {
            CloseHandle(hProcess);
        }
    }
    
    int main()
    {
        enableDebugPrivileges();
        // Get the list of process identifiers.
    
        DWORD aProcesses[1024], cbNeeded, cProcesses;
        UINT32 i;
    
        if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        {
            return 1;
        }
    
    
        // Calculate how many process identifiers were returned.
    
        cProcesses = cbNeeded / sizeof(DWORD);
    
        // Print the name and process identifier for each process.
    
        for ( i = 0; i < cProcesses; i++ )
        {
            if( aProcesses[i] != 0 )
            {
                PrintProcessNameAndID( aProcesses[i] );
            }
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-10
      • 2017-10-15
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多