0

OpenInputDesktop() にアクセスして必要なことを実行できるように、プライマリ トークンを取得したいと考えています。

ヘルプを求めてサイト全体を閲覧したところ、以下のような決定的なコードが見つかりましたが、DuplicateTokenEx () の呼び出しでエラーが発生しました。これは、メモリ ロケーションへの無効なアクセスを意味します。

 HANDLE GetCurrentUserToken()
{
    HANDLE currentToken = 0;
    PHANDLE primaryToken = 0;

    unsigned int winlogonPid = 0;

    int dwSessionId = 0;
    PHANDLE hUserToken = 0;
    PHANDLE hTokenDup = 0;

    PWTS_SESSION_INFO pSessionInfo = 0;
    DWORD dwCount = 0;

    WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, 
                         &pSessionInfo, &dwCount);

    //TestLog("Error on WTSEnumerateSessions(): %d",GetLastError());

    int dataSize = sizeof(WTS_SESSION_INFO);

    for (DWORD i = 0; i < dwCount; ++i)
    {
        WTS_SESSION_INFO si = pSessionInfo[i];
        if (WTSActive == si.State)
        {
            dwSessionId = si.SessionId;
            break;
        }
    }

    WTSFreeMemory(pSessionInfo);

    array<Process^>^localByName = Process::GetProcessesByName( "winlogon" );


    for (int i=0;i<localByName->Length;i++)
    {
        Process ^ p1 = (Process^)(localByName->GetValue(i));

        if ((unsigned int)p1->SessionId == dwSessionId)
        {
            winlogonPid = (unsigned int)p1->Id;
        }
    }

    // obtain a handle to the winlogon process
    HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
    TestLog("Error on OpenProcess():",GetLastError());

    // obtain a handle to the access token of the winlogon process
    if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, &currentToken))
    {
        TestLog("Error on OpenProcessToken():",GetLastError());
        CloseHandle(hProcess);
        return false;
    }

    BOOL bRet ;
    // bRet = DuplicateTokenEx(currentToken,
    //         MAXIMUM_ALLOWED /*TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS*/, 
    //         NULL/*0*/, 
    //         SecurityImpersonation, TokenImpersonation, primaryToken);

    bRet = DuplicateTokenEx(currentToken, 
                            TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 
                            NULL, SecurityImpersonation, 
                            TokenPrimary, primaryToken);

    TestLog("Error on DuplicateTokenEx():",GetLastError());
    TestLog("return value of DuplicateTokenEx()",bRet);

    int errorcode = GetLastError();
    if (bRet == false)
    {
        return 0;
    }

    return primaryToken;
}

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");

    TestLog("**Start TestLaunchExeOneTime**",0);
    HANDLE hTokenNew = NULL, hTokenDup = NULL;
    HMODULE  hmod = LoadLibrary(L"kernel32.dll");

    hTokenDup = GetCurrentUserToken();

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    memset(&si,0,sizeof(STARTUPINFO));
    si.cb = sizeof( STARTUPINFO );
    si.lpDesktop = L"winsta0\\default";

    LPVOID  pEnv = NULL;
    DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
    HMODULE hModule = LoadLibrary(L"Userenv.dll");
    if(hModule )
    {
        if(CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE))
        {
            //WriteToLog("CreateEnvironmentBlock Ok");
            dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;    
        }
        else
        {
            TestLog("Error on CreateEnvironmentBlock():",GetLastError());
            pEnv = NULL;
        }
    }

    //

    if ( !CreateProcessAsUser( hTokenDup,
        NULL,
        L"C:\\temp\\DesktopDuplicationmilliseconds.exe",  
        NULL,
        NULL,
        FALSE,
        dwCreationFlag,
        pEnv,
        NULL,
        &si,
        &pi
        ))
    {

    }
    else
    {
        TestLog("Error on CreateProcessAsUser():",GetLastError());
        // printf("error : %d",GetLastError());
    }

    return 0;
}
4

1 に答える 1

1

プライマリ トークンにメモリを割り当てていません。primaryToken 変数はハンドルへのポインターですが、実際には何も指していません。(ハンドルを返す関数としても宣言GetCurrentUserTokenしましたが、実際にはハンドルへのポインターを返しています。)

ハンドルにメモリを明示的に割り当てる必要があります。

primaryToken = malloc(sizeof(HANDLE));

[...]

return *primaryToken;

または、より賢明には、primaryToken をポインターではなく HANDLE として定義し、適切な場所でそれへの参照を渡します。

HANDLE primaryToken;

[...]

bRet = DuplicateTokenEx(currentToken, 
                        TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 
                        NULL, SecurityImpersonation, 
                        TokenPrimary, &primaryToken);
于 2012-11-01T20:27:02.270 に答える