GetProcessName в C++
У меня есть функция с детализацией удара.
typedef part
typedef DWORD (WINAPI *GETMODULEFILENAMEEX)(HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName,DWORD nSize);
typedef BOOL (WINAPI *PFNTERMINATEPROCESS)(HANDLE hProcess,UINT uExitCode);
/// функция GetProcessName
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);
}
Я хочу использовать эту функцию в функции ниже
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);
}
Когда я вызываю функцию GetProcessName
, это должно вернуть имя процесса, но это??? ул всегда. Я называю эту функцию напрямую по PID, например GetProcessName(2018,szProcessName,MAX_PATH);
, 2018 к примеру это пид и все работает. Я не знаю, почему HandleToULong(hProcess) не работает. мой hProcess
должен быть тип ручки, конечно, теперь, как я могу исправить эту проблему?
4 ответа
char name [MAX_PATH * 2] = "\ 0", * p;
GetModuleFileName (GetModuleHandle (NULL), имя,MAX_PATH);
р = имя + стрлен (имя) - 1;
while (isalnum (* p) || ('.' == * p) || ('_' == * p)) p--;
р ++;
std:: cout << p << std:: endl;
Вы должны позвонить GetProcessId
скорее, чем HandleToULong
, Вам нужен идентификатор процесса, а не дескриптор, преобразованный в unsigned-long
- Как вы можете завершить процесс и ожидать, что дескриптор все еще будет действителен? причина, если выполняется какая-либо очистка, все данные потеряны (вы не копируете дескриптор явно, так что это может произойти)
- кажется, ваша ошибка происходит из-за того, где вы извлекаете hProcess, и в этом случае вы должны проверить GetLastError, чтобы понять, почему он не работает.
В Windows идентификатор процесса отличается от дескриптора процесса. Вы принимаете ручку процесса в Hook_TerminateProcess
и передать его в GetProcessName
как идентификатор процесса. Это никогда не сработает.
Вы должны рефакторинг GetProcessName
взять ручку, а затем иметь перегрузку, которая принимает идентификатор процесса. Перегрузка ID процесса делает OpenProcess
работать, чтобы превратить его в ручку и тому CloseHandle
работать, чтобы очистить его.
После рефакторинга у вас будет два метода:
void GetProcessName(HANDLE hProcess, PTSTR szProcessName, size_t cchSize);
void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize);