4

GetUserName() METHOD を使用しましたが、返されたユーザー名は SYSTEM プロセスでは 'SYSTEM' です。SYSTEM プロセスでアクティブなユーザー名を取得するにはどうすればよいですか? これは私のコードです:

void getComputerUsername(char * username,char * domainname)
{
 HANDLE hp , htoken;
 char buff[1024];
 unsigned long size = 1024;

 TOKEN_USER *tuser;
 PSID sid;
 TCHAR * user = new TCHAR[256];
 TCHAR * domain=new TCHAR[256];
 SID_NAME_USE snu;

 hp = htoken = INVALID_HANDLE_VALUE;
 hp = GetCurrentProcess();
 if(OpenProcessToken(hp, TOKEN_QUERY, &htoken))
 {
     if(GetTokenInformation(htoken, TokenUser, (void*)buff, size, &size))
 {
     tuser = (TOKEN_USER*)buff;
     sid = tuser->User.Sid;
     size = 256;
     if(LookupAccountSid(NULL, sid, user, &size, domain, &size, &snu))
     {
    int iLength = WideCharToMultiByte(CP_ACP, 0, user, -1, NULL, 0, NULL, NULL);  
    WideCharToMultiByte(CP_ACP, 0, user, -1, username, iLength, NULL, NULL);   

    iLength = WideCharToMultiByte(CP_ACP, 0, domain, -1, NULL, 0, NULL, NULL);  
    WideCharToMultiByte(CP_ACP, 0, domain, -1, domainname, iLength, NULL, NULL);  
           //strcpy( user,username);
     }
 }
 }

}

4

5 に答える 5

5

物理コンソールにログオンしているユーザーを知りたい場合は、呼び出しWTSGetActiveConsoleSessionIdて、現在アクティブなターミナル サービス (別名 "ユーザーの簡易切り替え" または "リモート デスクトップ") のセッション ID を取得できます。

WTSQuerySessionInformationその後、 withを呼び出しWTSUserNameてユーザー名を取得できます。

(関心のあるユーザーがリモート デスクトップ経由でログオンしている可能性がある場合、このアプローチは機能しません。)

于 2013-09-27T04:43:48.717 に答える
4

以下のアプローチは、物理コンソール セッションと仮想 (リモート デスクトップ) コンソール セッションの両方で機能します。

ユーザーが物理コンソールを使用しているか、リモート セッション経由でログインしているかに関係なく、すべてのプロセスを列挙する方法がありますが、次のような問題があります。

1) ドキュメント化された Windows API を使用して、同じサービス プロセスで x86 プロセスと x64 プロセスの両方を列挙することはできません。x86 サービスは x86 プロセスのみを列挙でき、x64 サービスは x64 プロセスのみを列挙できます。これを回避する方法は、x86 サービスに x64 ヘルパー プロセスを起動させ (逆も同様)、残りの列挙タスクを実行させることです。

2) 異なる Windows バージョン (Vista から Windows 10 など) にログオンしているユーザーに常に存在する唯一のプロセスは explorer.exe ですが、そのプロセスは x64 OS プラットフォームでは x64 であり、x32 OS プラットフォームでは x32 であり、その存在は意味しません。ユーザーがアクティブにログインしていること。

より良い方法は、セッションを列挙し、アクティブなインタラクティブ セッションまたは接続されているセッションを見つけて、そのセッションのユーザー名を取得することです。

以下のコードは、そのユーザーの偽装や、Windows サービスからのそのユーザーとしてのプロセスの実行など、それ以上のことを行いますが、ユーザー名だけに関心がある場合は、WTSQuerySessionInformation() 関数が呼び出される 2 番目のインスタンスを探してください。 .

//Function to run a process as active user from windows service
void ImpersonateActiveUserAndRun(WCHAR* path, WCHAR* args)
{
    DWORD session_id = -1;
    DWORD session_count = 0;

    WTS_SESSION_INFOA *pSession = NULL;


    if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
    {
        //log success
    }
    else
    {
        //log error
        return;
    }

    for (int i = 0; i < session_count; i++)
    {
        session_id = pSession[i].SessionId;

        WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected;
        WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL;

        DWORD bytes_returned = 0;
        if (::WTSQuerySessionInformation(
            WTS_CURRENT_SERVER_HANDLE,
            session_id,
            WTSConnectState,
            reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state),
            &bytes_returned))
        {
            wts_connect_state = *ptr_wts_connect_state;
            ::WTSFreeMemory(ptr_wts_connect_state);
            if (wts_connect_state != WTSActive) continue;
        }
        else
        {
            //log error
            continue;
        }

        HANDLE hImpersonationToken;

        if (!WTSQueryUserToken(session_id, &hImpersonationToken))
        {
            //log error
            continue;
        }


        //Get real token from impersonation token
        DWORD neededSize1 = 0;
        HANDLE *realToken = new HANDLE;
        if (GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize1))
        {
            CloseHandle(hImpersonationToken);
            hImpersonationToken = *realToken;
        }
        else
        {
            //log error
            continue;
        }


        HANDLE hUserToken;

        if (!DuplicateTokenEx(hImpersonationToken,
            //0,
            //MAXIMUM_ALLOWED,
            TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS | MAXIMUM_ALLOWED,
            NULL,
            SecurityImpersonation,
            TokenPrimary,
            &hUserToken))
        {
            //log error
            continue;
        }

        // Get user name of this process
        //LPTSTR pUserName = NULL;
        WCHAR* pUserName;
        DWORD user_name_len = 0;

        if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session_id, WTSUserName, &pUserName, &user_name_len))
        {
            //log username contained in pUserName WCHAR string
        }

        //Free memory                         
        if (pUserName) WTSFreeMemory(pUserName);

        ImpersonateLoggedOnUser(hUserToken);

        STARTUPINFOW StartupInfo;
        GetStartupInfoW(&StartupInfo);
        StartupInfo.cb = sizeof(STARTUPINFOW);
        //StartupInfo.lpDesktop = "winsta0\\default";

        PROCESS_INFORMATION processInfo;

        SECURITY_ATTRIBUTES Security1;
        Security1.nLength = sizeof SECURITY_ATTRIBUTES;

        SECURITY_ATTRIBUTES Security2;
        Security2.nLength = sizeof SECURITY_ATTRIBUTES;

        void* lpEnvironment = NULL;

        // Get all necessary environment variables of logged in user
        // to pass them to the new process
        BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE);
        if (!resultEnv)
        {
            //log error
            continue;
        }

        WCHAR PP[1024]; //path and parameters
        ZeroMemory(PP, 1024 * sizeof WCHAR);
        wcscpy(PP, path);
        wcscat(PP, L" ");
        wcscat(PP, args);

        // Start the process on behalf of the current user 
        BOOL result = CreateProcessAsUserW(hUserToken, 
            NULL,
            PP,
            //&Security1,
            //&Security2,
            NULL,
            NULL,
            FALSE, 
            NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
            //lpEnvironment,
            NULL,
            //"C:\\ProgramData\\some_dir",
            NULL,
            &StartupInfo,
            &processInfo);

        if (!result)
        {
            //log error
        }
        else
        {
            //log success
        }

        DestroyEnvironmentBlock(lpEnvironment);

        CloseHandle(hImpersonationToken);
        CloseHandle(hUserToken);
        CloseHandle(realToken);

        RevertToSelf();
    }

    WTSFreeMemory(pSession);
}
于 2016-02-09T16:47:28.543 に答える
2

EnumProcessesを使用して、実行中のすべてのプロセスを列挙する必要があります。

次に、この回答を参照して、プロセスからユーザー名を取得します。

https://stackoverflow.com/a/2686150/203244

于 2013-09-25T06:30:05.470 に答える
0

デスクトップを列挙し、「デフォルト」デスクトップを見つけます。そのデスクトップからユーザー SID を取得します。正しいアクセス権を見つけようとする必要があるかもしれません。インタラクティブなプロセスからのみコードを試しました。

BOOL CALLBACK EnumDesktopProc(_In_  LPTSTR lpszDesktop, _In_  LPARAM lParam)
{
    // todo: check if desktop is "Default"
    char info[1000];
    auto hd = OpenDesktop(lpszDesktop, NULL, FALSE, DESKTOP_READOBJECTS);
    GetUserObjectInformation(hd, UOI_USER_SID, info, 1000, NULL);
    return TRUE;
}

BOOL CALLBACK EnumWindowStationProc(_In_  LPTSTR lpszWindowStation, _In_  LPARAM lParam)
{
    auto hs = OpenWindowStation(lpszWindowStation, FALSE, WINSTA_ENUMDESKTOPS);
    EnumDesktops(hs, &EnumDesktopProc, NULL);
    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    EnumWindowStations(&EnumWindowStationProc, NULL);
    return 0;
}
于 2013-09-25T07:50:18.743 に答える