GetProcessName in C++

7.5k views Asked by At

I have a function with blow detail.

typedef part

   typedef DWORD (WINAPI *GETMODULEFILENAMEEX)(HANDLE hProcess, HMODULE hModule, LPTSTR   lpBaseName,DWORD nSize); 

   typedef BOOL (WINAPI *PFNTERMINATEPROCESS)(HANDLE hProcess,UINT uExitCode);

/// GetProcessName function

void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize)
{

    HMODULE lib=LoadLibrary(TEXT("Psapi.dll"));
    GetModuleFileNameEx=(GETMODULEFILENAMEEX)GetProcAddress
    (lib,"GetModuleFileNameExW");
    _tcscpy_s(szProcessName, cchSize, TEXT("---"));


    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
    FALSE,PID);

   if (hProcess == NULL) {
      _tcscpy_s(szProcessName, cchSize, TEXT("???"));
      return;
   }

   if (GetModuleFileNameEx(hProcess,(HMODULE)0, szProcessName, cchSize) 
       == 0) {
     if (!GetProcessImageFileName(hProcess, szProcessName, cchSize)) {
         _tcscpy_s(szProcessName, cchSize, TEXT("???"));
      }
   }
   CloseHandle(hProcess);
}

I want use this function in below function

BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess,UINT uExitCode) {
  BOOL nResult=false;
  TCHAR szProcessName[MAX_PATH];


 nResult = ((PFNTERMINATEPROCESS)(PROC) g_TerminateProcess)(hProcess,uExitCode);

 GetProcessName(HandleToULong(hProcess),szProcessName,MAX_PATH); //my question here


    MessageBox(0, szProcessName  ,TEXT("My MessageBox Info"),MB_OK | MB_ICONERROR);

   return(nResult);
}

When I call function GetProcessName, this must return process name but it ??? str always. I call this function directly by PID, for example GetProcessName(2018,szProcessName,MAX_PATH);. 2018 for example is a pid and it work. I don't know why HandleToULong(hProcess) doesn't work. My hProcess must be a handle type certainly now how I fix this problem?

4

There are 4 answers

2
Anthony Williams On

You must call GetProcessId rather than HandleToULong. You need a process ID, not a handle-converted-to-an-unsigned-long

3
Chris Schmich On

In Windows, a process ID is different from a process handle. You are taking the process handle in Hook_TerminateProcess and passing it into GetProcessName as a process ID. This will never work.

You should refactor GetProcessName to take a handle and then have an overload that takes a process ID. The process ID overload does the OpenProcess work to convert it into a handle and the CloseHandle work to clean it up.

After the refactoring, you'll have two methods:

void GetProcessName(HANDLE hProcess, PTSTR szProcessName, size_t cchSize);
void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize);
1
Necrolis On
  1. How can you terminate the process then expect the handle to still be valid? cause if any clean up is performed, all data is lost(you don't explicitly copy the handle, so this can happen)
  2. your error seems to stem from where your retrieving hProcess, in which case you should check GetLastError to see why its failing
1
pannne On

char name[MAX_PATH * 2 ] = "\0", *p;

GetModuleFileName(GetModuleHandle(NULL),name,MAX_PATH);

p = name + strlen(name) - 1;

while (isalnum(*p) || ('.' == *p) || ('_' == *p)) p--;

p++;

std::cout << p << std::endl;