/// <summary> /// Get current process exe file directory /// </summary> /// <returns>Exe directory</returns> std::wstring Utils::GetExeDirectory() { wchar_t imgName[MAX_PATH] = { 0 }; DWORD len = ARRAYSIZE(imgName); QueryFullProcessImageNameW( GetCurrentProcess(), 0, imgName, &len ); return GetParent( imgName ); }
std::wstring get_process_filename(HWND window) { DWORD process_id; GetWindowThreadProcessId(window, &process_id); const HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, process_id); std::wstring filename; filename.resize(1024); DWORD buffer_size = filename.size(); if (QueryFullProcessImageNameW(process, 0, &filename[0], &buffer_size) == 0) { return L"(unknown filename)"; } //QueryFullProcessImageNameW returns full path (C:\Windows\system32\cmd.exe), this strips the path. const std::tr2::sys::wpath path(filename); return path.filename(); }
/* * @implemented */ BOOL WINAPI QueryFullProcessImageNameA(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD pdwSize) { DWORD pdwSizeW = *pdwSize; BOOL Result; LPWSTR lpExeNameW; lpExeNameW = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, *pdwSize * sizeof(WCHAR)); if (!lpExeNameW) { BaseSetLastNTError(STATUS_NO_MEMORY); return FALSE; } Result = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW); if (Result) Result = (0 != WideCharToMultiByte(CP_ACP, 0, lpExeNameW, -1, lpExeName, *pdwSize, NULL, NULL)); if (Result) *pdwSize = strlen(lpExeName); RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW); return Result; }
QString WinInfo::getForegroundWindowExePath() { QString exePath; HWND foreground = GetForegroundWindow(); HANDLE windowProcess = NULL; if (foreground) { DWORD processId; GetWindowThreadProcessId(foreground, &processId); windowProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, true, processId); } if (windowProcess != NULL) { TCHAR filename[MAX_PATH]; memset(filename, 0, sizeof(filename)); //qDebug() << QString::number(sizeof(filename)/sizeof(TCHAR)); if (isWindowsVistaOrHigher()) { DWORD pathLength = MAX_PATH * sizeof(TCHAR); QueryFullProcessImageNameW(windowProcess, 0, filename, &pathLength); //qDebug() << pathLength; } else { DWORD pathLength = GetModuleFileNameEx(windowProcess, NULL, filename, MAX_PATH * sizeof(TCHAR)); //qDebug() << pathLength; } exePath = QString::fromWCharArray(filename); //qDebug() << QString::fromWCharArray(filename); CloseHandle(windowProcess); } return exePath; }
QString SystemInfo::getProcessNameByPid(qint64 pid) { QString processName; #if defined(Q_OS_OSX) // Mac OS X // From: // http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qlockfile_unix.cpp errno = 0; char name[1024] = {0}; int retval = proc_name(pid, name, sizeof(name) / sizeof(char)); if (retval > 0) { processName = QFile::decodeName(name); } else if ((retval == 0) && (errno == static_cast<int>(std::errc::no_such_process))) { return QString(); // process not running } else { throw RuntimeError( __FILE__, __LINE__, QString(tr("proc_name() failed with error %1.")).arg(errno)); } #elif defined(Q_OS_FREEBSD) char exePath[64]; char buf[PATH_MAX + 1]; sprintf(exePath, "/proc/%lld/file", pid); size_t len = (size_t)readlink(exePath, buf, sizeof(buf)); if (len >= sizeof(buf)) { return QString(); // process not running } buf[len] = 0; processName = QFileInfo(QFile::decodeName(buf)).fileName(); #elif defined(Q_OS_LINUX) // From: // http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qlockfile_unix.cpp if (!FilePath("/proc/version").isExistingFile()) { throw RuntimeError(__FILE__, __LINE__, tr("Could not find the file \"/proc/version\".")); } char exePath[64]; char buf[PATH_MAX + 1]; sprintf(exePath, "/proc/%lld/exe", pid); size_t len = (size_t)readlink(exePath, buf, sizeof(buf)); if (len >= sizeof(buf)) { return QString(); // process not running } buf[len] = 0; processName = QFileInfo(QFile::decodeName(buf)).fileName(); // If the executable does no longer exist, the string " (deleted)" is added to // the end of the symlink, so we need to remove that to get the naked process // name. if (processName.endsWith(" (deleted)")) processName.chop(strlen(" (deleted)")); #elif defined(Q_OS_WIN32) || defined(Q_OS_WIN64) // Windows // Originally from: // http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qlockfile_win.cpp // But then saw this article: // https://blogs.msdn.microsoft.com/oldnewthing/20150716-00/?p=45131/ And // therefore switched from GetModuleFileNameExW() to // QueryFullProcessImageNameW() HANDLE hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid)); if ((!hProcess) && (GetLastError() == ERROR_INVALID_PARAMETER)) { return QString(); // process not running } else if (!hProcess) { throw RuntimeError( __FILE__, __LINE__, QString(tr("OpenProcess() failed with error %1.")).arg(GetLastError())); } wchar_t buf[MAX_PATH]; DWORD length = MAX_PATH; BOOL success = QueryFullProcessImageNameW(hProcess, 0, buf, &length); CloseHandle(hProcess); if ((!success) || (!length)) { throw RuntimeError( __FILE__, __LINE__, QString(tr("QueryFullProcessImageNameW() failed with error %1.")) .arg(GetLastError())); } processName = QString::fromWCharArray(buf, length); int i = processName.lastIndexOf(QLatin1Char('\\')); if (i >= 0) processName.remove(0, i + 1); i = processName.lastIndexOf(QLatin1Char('.')); if (i >= 0) processName.truncate(i); #else #error "Unknown operating system!" #endif // check if the process name is not empty if (processName.isEmpty()) { throw RuntimeError( __FILE__, __LINE__, tr("Could not determine the process name of another process.")); } return processName; }
// // Perform the scanning as specified in the various input parameters // void Scan(DWORD dwEventType, int dScanContext, PROCFILTER_EVENT *e, YARASCAN_CONTEXT *ctx, HANDLE hDriver, HANDLE hWriteCompletionEvent, DWORD dwProcessId, DWORD dwParentProcessId, WCHAR *lpszFileName, void *lpImageBase, void *lpvScanDataArray) { if (!lpszFileName) return; LONG64 llStart = GetPerformanceCount(); CONFIG_DATA *cd = GetConfigData(); bool bScanFile = false; bool bScanMemory = false; bool bBlock = false; bool bLog = false; bool bQuarantine = false; // Pull the scan parameters out of config if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_CREATE) { bScanFile = cd->bScanFileOnProcessCreate; bScanMemory = cd->bScanMemoryOnProcessCreate; } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_TERMINATE) { bScanFile = cd->bScanFileOnProcessTerminate; bScanMemory = cd->bScanMemoryOnProcessTerminate; } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_PERIODIC_SCAN) { bScanFile = cd->bScanFileOnPeriodic; bScanMemory = cd->bScanMemoryOnPeriodic; } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_IMAGE_LOAD) { bScanFile = cd->bScanFileOnImageLoad; bScanMemory = cd->bScanMemoryOnImageLoad; } else { Die("Invalid context passed to Scan(): %d", dScanContext); } // Initialize the API event with the passed-in parameters ApiEventReinit(e, PROCFILTER_EVENT_YARA_SCAN_INIT); e->dwProcessId = dwProcessId; e->dwParentProcessId = dwParentProcessId; e->lpszFileName = lpszFileName; e->dScanContext = dScanContext; e->bScanFile = bScanFile; e->bScanMemory = bScanMemory; e->lpvScanData = lpvScanDataArray; // Export the event to the API and handle the result flags DWORD dwPluginResultFlags = ApiEventExport(e); if (dwPluginResultFlags & PROCFILTER_RESULT_BLOCK_PROCESS) bBlock = true; if (dwPluginResultFlags & PROCFILTER_RESULT_DONT_SCAN_MEMORY) bScanMemory = false; if (dwPluginResultFlags & PROCFILTER_RESULT_FORCE_SCAN_MEMORY) bScanMemory = true; if (dwPluginResultFlags & PROCFILTER_RESULT_DONT_SCAN_FILE) bScanFile = false; if (dwPluginResultFlags & PROCFILTER_RESULT_FORCE_SCAN_FILE) bScanFile = true; if (dwPluginResultFlags & PROCFILTER_RESULT_QUARANTINE) bQuarantine = true; // Scan the file if requested SCAN_RESULT srFileResult; ZeroMemory(&srFileResult, sizeof(SCAN_RESULT)); if (bScanFile) { CALLBACK_USER_DATA cud = { e, dwProcessId, lpszFileName, lpvScanDataArray, dScanContext, PROCFILTER_MATCH_FILE }; YarascanScanFile(ctx, lpszFileName, cd->dwScanFileSizeLimit, OnMatchCallback, OnMetaCallback, &cud, &srFileResult); if (srFileResult.bScanSuccessful) { bBlock |= srFileResult.bBlock; bLog |= srFileResult.bLog; bQuarantine |= srFileResult.bQuarantine; } else { EventWriteSCAN_FILE_FAILED(dwProcessId, lpszFileName, srFileResult.szError); } } // Scan the memory if requested SCAN_RESULT srMemoryResult; ZeroMemory(&srMemoryResult, sizeof(SCAN_RESULT)); if (bScanMemory) { CALLBACK_USER_DATA cud = { e, dwProcessId, lpszFileName, lpvScanDataArray, dScanContext, PROCFILTER_MATCH_MEMORY }; YarascanScanMemory(ctx, dwProcessId, OnMatchCallback, OnMetaCallback, &cud, &srMemoryResult); if (srMemoryResult.bScanSuccessful) { bBlock |= srMemoryResult.bBlock; bLog |= srMemoryResult.bLog; bQuarantine |= srMemoryResult.bQuarantine; } else { EventWriteSCAN_PROCESS_FAILED(dwProcessId, lpszFileName, srMemoryResult.szError); } } // Export the scan results to plugins ApiEventReinit(e, PROCFILTER_EVENT_YARA_SCAN_COMPLETE); e->dwProcessId = dwProcessId; e->dwParentProcessId = dwParentProcessId; e->lpszFileName = lpszFileName; e->dScanContext = dScanContext; e->srFileResult = bScanFile ? &srFileResult : NULL; e->srMemoryResult = bScanMemory ? &srMemoryResult : NULL; e->bBlockProcess = bBlock; e->lpvScanData = lpvScanDataArray; dwPluginResultFlags = ApiEventExport(e); if (dwPluginResultFlags & PROCFILTER_RESULT_BLOCK_PROCESS) bBlock = true; if (dwPluginResultFlags & PROCFILTER_RESULT_QUARANTINE) bQuarantine = true; WCHAR *szFileQuarantineRuleNames = bScanFile && srFileResult.bScanSuccessful ? srFileResult.szQuarantineRuleNames : NULL; WCHAR *szMemoryQuarantineRuleNames = bScanMemory && srMemoryResult.bScanSuccessful ? srMemoryResult.szQuarantineRuleNames : NULL; // Quarantine here if (bQuarantine) { char hexdigest[SHA1_HEXDIGEST_LENGTH+1] = { '\0' }; if (QuarantineFile(lpszFileName, cd->szQuarantineDirectory, cd->dwQuarantineFileSizeLimit, szFileQuarantineRuleNames, szMemoryQuarantineRuleNames, hexdigest)) { EventWriteFILE_QUARANTINED(dwProcessId, lpszFileName, hexdigest, (bScanFile && srFileResult.bScanSuccessful) ? srFileResult.szQuarantineRuleNames : NULL, (bScanMemory && srMemoryResult.bScanSuccessful) ? srMemoryResult.szQuarantineRuleNames : NULL); } } // Write the result back to the kernel driver, which releases the process bool bProcessBlocked = false; if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_CREATE || dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_TERMINATE) { PROCFILTER_RESPONSE response; ZeroMemory(&response, sizeof(PROCFILTER_RESPONSE)); response.dwEventType = dwEventType; response.dwProcessId = dwProcessId; // Block the process according to configuration if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_CREATE) { if (cd->bDenyProcessCreationOnFailedScan) { if (bScanFile && !srFileResult.bScanSuccessful) bBlock = true; if (bScanMemory && !srMemoryResult.bScanSuccessful) bBlock = true; } if (bBlock) { response.bBlock = true; } } if (DriverSendResponse(hDriver, hWriteCompletionEvent, &response)) { if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_CREATE) bProcessBlocked = true; } } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_IMAGE_LOAD) { PROCFILTER_RESPONSE response; ZeroMemory(&response, sizeof(PROCFILTER_RESPONSE)); response.dwEventType = dwEventType; response.dwProcessId = dwProcessId; response.lpImageBase = lpImageBase; DriverSendResponse(hDriver, hWriteCompletionEvent, &response); } // Log to event log based on what was sent to the kernel (excluding the quarantining) WCHAR *szFileLogRuleNames = bScanFile && srFileResult.bScanSuccessful ? srFileResult.szLogRuleNames : NULL; WCHAR *szFileBlockRuleNames = bScanFile && srFileResult.bScanSuccessful ? srFileResult.szBlockRuleNames : NULL; WCHAR *szFileMatchRuleNames = bScanFile && srFileResult.bScanSuccessful ? srFileResult.szMatchedRuleNames : NULL; WCHAR *szMemoryLogRuleNames = bScanMemory && srMemoryResult.bScanSuccessful ? srMemoryResult.szLogRuleNames : NULL; WCHAR *szMemoryBlockRuleNames = bScanMemory && srMemoryResult.bScanSuccessful ? srMemoryResult.szBlockRuleNames : NULL; WCHAR *szMemoryMatchRuleNames = bScanMemory && srMemoryResult.bScanSuccessful ? srMemoryResult.szMatchedRuleNames : NULL; // Log the actions taken according to which events happened if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_CREATE) { if (bLog) EventWriteEXECUTION_LOGGED(dwProcessId, lpszFileName, szFileLogRuleNames, szMemoryLogRuleNames); if (bBlock) EventWriteEXECUTION_BLOCKED(dwProcessId, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames); } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_PROCESS_TERMINATE) { if (bLog) EventWriteEXITING_PROCESS_SCAN_MATCHED_LOGGED_RULE(dwProcessId, lpszFileName, szFileLogRuleNames, szMemoryLogRuleNames); if (bBlock) EventWriteEXITING_PROCESS_SCAN_MATCHED_BLOCKED_RULE(dwProcessId, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames); } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_PERIODIC_SCAN) { if (bLog) EventWriteRUNNING_PROCESS_MATCHED_LOGGED_RULE(dwProcessId, lpszFileName, szFileLogRuleNames, szMemoryLogRuleNames); if (bBlock) { EventWriteRUNNING_PROCESS_MATCHED_BLOCKED_RULE(dwProcessId, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames); if (TerminateProcessByPid(dwProcessId, true, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames)) { bProcessBlocked = true; } } } else if (dScanContext == PROCFILTER_SCAN_CONTEXT_IMAGE_LOAD) { if (bLog || bBlock) { WCHAR *lpszImageLoaderProcessName = NULL; DWORD dwImageLoaderProcessNameSize = sizeof(WCHAR) * (MAX_PATH+1); HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); if (hProcess) { lpszImageLoaderProcessName = (WCHAR*)_malloca(dwImageLoaderProcessNameSize); if (!QueryFullProcessImageNameW(hProcess, PROCESS_NAME_NATIVE, lpszImageLoaderProcessName, &dwImageLoaderProcessNameSize)) { _freea(lpszImageLoaderProcessName); lpszImageLoaderProcessName = NULL; } CloseHandle(hProcess); } if (bLog) EventWriteLOADED_IMAGE_LOGGED(dwProcessId, lpszImageLoaderProcessName, lpszFileName, szFileLogRuleNames, szMemoryLogRuleNames); if (bBlock) { EventWriteLOADED_IMAGE_BLOCKED(dwProcessId, lpszImageLoaderProcessName, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames); if (TerminateProcessByPid(dwProcessId, true, lpszFileName, szFileBlockRuleNames, szMemoryBlockRuleNames)) { bProcessBlocked = true; } } if (lpszImageLoaderProcessName) _freea(lpszImageLoaderProcessName); } } // Export post-scan notice to plugins ApiEventReinit(e, PROCFILTER_EVENT_YARA_SCAN_CLEANUP); e->dwProcessId = dwProcessId; e->dwParentProcessId = dwParentProcessId; e->lpszFileName = lpszFileName; e->dScanContext = dScanContext; e->srFileResult = bScanFile ? &srFileResult : NULL; e->srMemoryResult = bScanMemory ? &srMemoryResult : NULL; e->bBlockProcess = bBlock; e->bProcessBlocked = bProcessBlocked; e->lpvScanData = lpvScanDataArray; ApiEventExport(e); // Performance data update LONG64 llDuration = GetPerformanceCount() - llStart; MmaUpdate(&g_Stats[dScanContext].mma, llDuration); MmaUpdate(&g_Stats[PROCFILTER_NUM_CONTEXTS].mma, llDuration); }