process username OpenProcess -> OpenProcessToken access denied

C

chupper

Hi, I've seen lots of posts about this on line, but it appears that no
one ever gets it to work.
I'm trying to open a process, other than mine, and get the username
the process is running as.

I've found .net code which does this via
System.Management.ManagementObject, but it's slow, apparently runs via
WMI, and I'd just rather do it natively.
Taskmanager does it fine.
I'm running as local admin and trying to view the owner of a process
that was spawned with the runas cmd.

Yet I can't. I get access denied no matter what I do. What am I
missing? Why does the wmi work? It's got to be just using winapi
down below anyway, perhaps it's because of the privileges the wmi
service is running as?

Here's my code, mostly copied, I believe via a MS page.
Can someone tell me what I need to do?
I've tried adjusting my token and the other processes.

Would it be easier to just ::CreateRemoteThread and do it the hard
way?

I can't get past the OpenProcessToken when the proc handle is the
handle to the remote process.
I've tried many combinations of access rights.

Here's the current code.


void sysLog( LPTSTR lpFrom )
{
WCHAR s[512]
DWORD dwErr = ::GetLastError()
::ZeroMemory( s, 512 )

if( (FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwErr,
0,
s,
512,
NULL ) ) == 0 )
{
::std::wcout << lpFrom << L" FormatMessage error ::GetLastError()
was " << dwErr << std::endl
}
else
{
::std::wcout << lpFrom << L" Error: " << dwErr << L" " << s <<
std::endl
}
}


BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp
LUID luid

if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() )
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

// Enable the privilege or disable all privileges.

if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() )
return FALSE
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

{
printf("The token does not have the specified privilege. \n")
return FALSE
}

return TRUE
}

BOOL GetCurrentUserAndDomain( DWORD dwPID,
PTSTR szUser, PDWORD pcchUser,
PTSTR szDomain, PDWORD pcchDomain)
{

BOOL fSuccess = FALSE
HANDLE hToken = NULL
PTOKEN_USER ptiUser = NULL
DWORD cbti = 0
SID_NAME_USE snu
HANDLE hProc = NULL

HANDLE hProcSelf = NULL
HANDLE hTokenSelf = NULL

__try
{



// not needed if dwPID is the id of this process
hProcSelf = ::OpenProcess( PROCESS_ALL_ACCESS,
FALSE,
::GetCurrentProcessId() )

::OpenProcessToken( hProcSelf,
TOKEN_ADJUST_PRIVILEGES,
&hTokenSelf)

SetPrivilege( hTokenSelf, SE_DEBUG_NAME, TRUE )

// always fails
//SetPrivilege( hTokenSelf, SE_TCB_NAME, TRUE )
//SetPrivilege( hTokenSelf, SE_IMPERSONATE_NAME, TRUE )


hProc = ::OpenProcess( PROCESS_QUERY_INFORMATION,
FALSE,
dwPID )

if( NULL == hProc )
{
sysLog( L"OpenProcess" )
__leave
}

// fails here always
if( 0 == ::OpenProcessToken( hProc,
TOKEN_QUERY,
&hToken))
{
sysLog( L"OpenProcessToken" )
__leave
}

// always fails
//SetPrivilege( hToken, SE_DEBUG_NAME, TRUE )
//SetPrivilege( hTokenSelf, SE_TCB_NAME, TRUE )
//SetPrivilege( hToken, SE_IMPERSONATE_NAME, TRUE )

// Obtain the size of the user information in the token.
if (GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti))
{
sysLog( L"GetTokenInformation" )
// Call should have failed due to zero-length buffer.
__leave

}
else
{
// Call should have failed due to zero-length buffer.
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
sysLog( L"GetTokenInformation" )
__leave
}
}

// Allocate buffer for user information in the token.
ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbti)
if (!ptiUser)
{
sysLog( L"GetTokenInformation" )
__leave
}

// Retrieve the user information from the token.
if (!GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
{
sysLog( L"GetTokenInformation" )
__leave
}

// Retrieve user name and domain name based on user's SID.
if (!LookupAccountSid( NULL, ptiUser->User.Sid, szUser, pcchUser,
szDomain, pcchDomain, &snu))
{
sysLog( L"GetTokenInformation" )
__leave
}

fSuccess = TRUE
}
__finally
{
if( hTokenSelf )
::CloseHandle( hTokenSelf )

// Free resources.
if( hProcSelf )
::CloseHandle( hProcSelf )

if (hToken)
::CloseHandle(hToken)

if (ptiUser)
::HeapFree:):GetProcessHeap(), 0, ptiUser)

if( hProc )
::CloseHandle( hProc )
}

return fSuccess
}
// http://win32.mvps.org/
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szUN[64]
TCHAR szD[64]

DWORD dwUNSize = 64
DWORD dwDSize = 64

DWORD dwPID = 0

BOOL bStatus = FALSE

if( argc == 2 )
{
dwPID = (DWORD)_ttoi( argv[1] )
std::wcout << "Looking up user account for pid: " << dwPID <<
std::endl
bStatus = GetCurrentUserAndDomain( dwPID, szUN, &dwUNSize, szD,
&dwDSize )
}
else
{
dwPID = ::GetCurrentProcessId()
std::wcout << "Looking up user account for current process pid: " <<
dwPID << std::endl
bStatus = GetCurrentUserAndDomain( dwPID, szUN, &dwUNSize, szD,
&dwDSize )
}

if( bStatus )
std::wcout << L"User: " << szUN << " Domain: " << szD << std::endl
}
 
Back
Top Bottom