0

I'm trying to get the list of processes running in the system using C++. I use the functions available in the Windows API (like OpenProcess & CreateToolhelp32Snapshot ) to get it done.

The problem is that the code works fine for most of the processes, but couldn't get the memory info for crucial system processes alone, I have given the seDebugPrivilege also and have run the program as administrator only.

I get the output like

File Name PID Memory Used

winlogon.exe 1248 2432 KB

fontdrvhost.exe 1308

WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)

dwm.exe 1384

WARNING: GetProcessMemoryInfo failed with error 6 (The handle is invalid)

svchost.exe 1448 4744 KB

My code is :

BOOL GetProcessList( )
{
    HANDLE hProcessSnap;
    HANDLE hProcess;
    HANDLE hToken;
    PROCESSENTRY32 pe32;
    DWORD dwPriorityClass;
    PROCESS_MEMORY_COUNTERS pmc;

  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {
      char err[]="CreateToolhelp32Snapshot (of processes)";
    printError( err );
    return( FALSE );
  }

  pe32.dwSize = sizeof( PROCESSENTRY32 );

  if( !Process32First( hProcessSnap, &pe32 ) )
  {
    char err[]="Process32First";
    printError( err ); // show cause of failure
    CloseHandle( hProcessSnap );          // clean the snapshot object
    return( FALSE );
  }
  if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
    {
        if (GetLastError() == ERROR_NO_TOKEN)
        {
            if (!ImpersonateSelf(SecurityImpersonation))
            return FALSE;

            if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
                char err[]="OpenThreadToken";
                printError( err );
                return FALSE;
            }
         }
        else
            return FALSE;
     }
    SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
  do
  {
    printf( "%-25s", pe32.szExeFile );
    dwPriorityClass = 0;
    SIZE_T  dwMin, dwMax;
    hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION , FALSE, pe32.th32ProcessID );
    printf("%-10d", pe32.th32ProcessID );
    if(GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS *)&pmc, sizeof(pmc)))
    {

        printf( "%-10d KB", pmc.PagefileUsage/1024); 
    } else{
        char err[]="GetProcessMemoryInfo";
        printError( err );
    }
        printf("\n");
    CloseHandle(hProcess);
  }while( Process32Next( hProcessSnap, &pe32 ) );
  CloseHandle( hProcessSnap );
  return( TRUE );
}
kowsikbabu
  • 499
  • 1
  • 6
  • 23
  • Maybe this example could be of use: https://pastebin.com/KjBzMEY0. I think you have this problem - https://stackoverflow.com/questions/28303436/openprocess-access-denied-error-only-on-windows-8-1. Also use PROCESS_QUERY_LIMITED_INFORMATION – HelpingHand Jun 25 '18 at 06:47
  • you not check result of `OpenProcess`. on some processes it fail and as result use invalid handle in call `GetProcessMemoryInfo` return to you error - invalid handle. must be – RbMm Jun 25 '18 at 07:04
  • also you not close `hToken` and look like fail assign debug privilege, only this can explain why you fail open some processes. also adjust privileges before enumerate processes – RbMm Jun 25 '18 at 07:19
  • @HelpingHand I'm using `PROCESS_QUERY_LIMITED_INFORMATION` and yeah I did see that article before posting this question – kowsikbabu Jun 25 '18 at 09:23
  • I agree with RbMm. It looks like there's a problem in `SetPrivilege`. If the thread token has debug privilege enabled, then opening a process to query only limited information shouldn't fail, not even for a protected process. – Eryk Sun Jun 25 '18 at 10:08
  • Note that this code is not only leaking `hToken` but also failing to revert the thread to self if it impersonates self. – Eryk Sun Jun 25 '18 at 10:09

1 Answers1

2

To get this code to work, you have to change:

SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)

to:

SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)

As others have commented, to get this code to work properly, you have to:

  • check for and report all possible error conditions
  • release all resources when you are done, in this case release hToken (via CloseHandle()) and call revertToSelf() if needs be.

Other than that, it's a decent effort so thumbs up for that.

Link to SetPrivilege(), in case any future visitor needs it:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa446619.aspx

Happy hacking.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48