BOOLEAN CreateDirectoryPath(_In_ PWSTR DirPath) { BOOLEAN success = FALSE; PPH_STRING dirPathString = NULL; PWSTR dirPathDup = NULL; if (RtlDoesFileExists_U(DirPath)) return TRUE; if ((dirPathDup = PhDuplicateStringZ(DirPath)) == NULL) goto CleanupExit; for (PWSTR path = _wcstok(dirPathDup, L"\\"); path; path = _wcstok(NULL, L"\\")) { if (!dirPathString) dirPathString = PhCreateString(path); else { PPH_STRING tempPathString; tempPathString = PhConcatStrings( 3, dirPathString->Buffer, L"\\", path ); if (!RtlDoesFileExists_U(PhGetString(tempPathString))) { if (!CreateDirectory(PhGetString(tempPathString), NULL)) { PhDereferenceObject(tempPathString); goto CleanupExit; } } PhSwapReference(&dirPathString, tempPathString); PhDereferenceObject(tempPathString); } } success = TRUE; CleanupExit: if (dirPathString) { PhDereferenceObject(dirPathString); } if (dirPathDup) { PhFree(dirPathDup); } return success; }
NTSTATUS PhInvokeRunAsService( _In_ PPH_RUNAS_SERVICE_PARAMETERS Parameters ) { NTSTATUS status; PPH_STRING domainName; PPH_STRING userName; PH_CREATE_PROCESS_AS_USER_INFO createInfo; ULONG flags; if (Parameters->UserName) { PhpSplitUserName(Parameters->UserName, &domainName, &userName); } else { domainName = NULL; userName = NULL; } memset(&createInfo, 0, sizeof(PH_CREATE_PROCESS_AS_USER_INFO)); createInfo.ApplicationName = Parameters->FileName; createInfo.CommandLine = Parameters->CommandLine; createInfo.CurrentDirectory = Parameters->CurrentDirectory; createInfo.DomainName = PhGetString(domainName); createInfo.UserName = PhGetString(userName); createInfo.Password = Parameters->Password; createInfo.LogonType = Parameters->LogonType; createInfo.SessionId = Parameters->SessionId; createInfo.DesktopName = Parameters->DesktopName; flags = PH_CREATE_PROCESS_SET_SESSION_ID; if (Parameters->ProcessId) { createInfo.ProcessIdWithToken = UlongToHandle(Parameters->ProcessId); flags |= PH_CREATE_PROCESS_USE_PROCESS_TOKEN; } if (Parameters->UseLinkedToken) flags |= PH_CREATE_PROCESS_USE_LINKED_TOKEN; status = PhCreateProcessAsUser( &createInfo, flags, NULL, NULL, NULL ); if (domainName) PhDereferenceObject(domainName); if (userName) PhDereferenceObject(userName); return status; }
HRESULT CALLBACK TaskDialogResultFoundProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR dwRefData ) { PUPLOAD_CONTEXT context = (PUPLOAD_CONTEXT)dwRefData; switch (uMsg) { case TDN_NAVIGATED: { if (context->TaskbarListClass) { ITaskbarList3_SetProgressState(context->TaskbarListClass, PhMainWndHandle, TBPF_NOPROGRESS); } } break; case TDN_BUTTON_CLICKED: { INT buttonID = (INT)wParam; if (buttonID == IDOK) { ShowVirusTotalProgressDialog(context); return S_FALSE; } else if (buttonID == IDRETRY) { if (!PhIsNullOrEmptyString(context->ReAnalyseUrl)) PhShellExecute(hwndDlg, PhGetString(context->ReAnalyseUrl), NULL); } else if (buttonID == IDYES) { if (!PhIsNullOrEmptyString(context->LaunchCommand)) { PhShellExecute(hwndDlg, PhGetString(context->LaunchCommand), NULL); } } } break; case TDN_VERIFICATION_CLICKED: { BOOL verification = (BOOL)wParam; } break; } return S_OK; }
VOID SetupShowUpdatingErrorDialog( _In_ PPH_SETUP_CONTEXT Context ) { TASKDIALOGCONFIG config; memset(&config, 0, sizeof(TASKDIALOGCONFIG)); config.cbSize = sizeof(TASKDIALOGCONFIG); config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_MARQUEE_PROGRESS_BAR | TDF_CAN_BE_MINIMIZED | TDF_ENABLE_HYPERLINKS; config.cxWidth = 200; config.dwCommonButtons = TDCBF_CLOSE_BUTTON; config.hMainIcon = Context->IconLargeHandle; config.pfCallback = SetupErrorTaskDialogCallbackProc; config.lpCallbackData = (LONG_PTR)Context; config.pszWindowTitle = PhApplicationName; config.pszMainInstruction = L"Error updating to the latest version."; if (Context->ErrorCode) { PPH_STRING errorString; if (errorString = PhGetStatusMessage(0, Context->ErrorCode)) config.pszContent = PhGetString(errorString); } SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config); }
BOOLEAN UpdaterCheckApplicationDirectory( VOID ) { HANDLE fileHandle; PPH_STRING directory; PPH_STRING file; if (UpdaterCheckKphInstallState()) return FALSE; directory = PhGetApplicationDirectory(); file = PhConcatStrings(2, PhGetStringOrEmpty(directory), L"\\processhacker.update"); if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, PhGetString(file), FILE_GENERIC_WRITE | DELETE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_DELETE_ON_CLOSE ))) { PhDereferenceObject(file); PhDereferenceObject(directory); NtClose(fileHandle); return TRUE; } PhDereferenceObject(file); PhDereferenceObject(directory); return FALSE; }
PPH_STRING VirusTotalStringToTime( _In_ PPH_STRING Time ) { PPH_STRING result = NULL; SYSTEMTIME time = { 0 }; SYSTEMTIME localTime = { 0 }; swscanf( PhGetString(Time), L"%hu-%hu-%hu %hu:%hu:%hu", &time.wYear, &time.wMonth, &time.wDay, &time.wHour, &time.wMinute, &time.wSecond ); if (SystemTimeToTzSpecificLocalTime(NULL, &time, &localTime)) { result = PhFormatDateTime(&localTime); } return result; }
static VOID PhpAddJobProcesses( __in HWND hwndDlg, __in HANDLE JobHandle ) { PJOBOBJECT_BASIC_PROCESS_ID_LIST processIdList; HWND processesLv; processesLv = GetDlgItem(hwndDlg, IDC_PROCESSES); if (NT_SUCCESS(PhGetJobProcessIdList(JobHandle, &processIdList))) { ULONG i; CLIENT_ID clientId; PPH_STRING name; clientId.UniqueThread = NULL; for (i = 0; i < processIdList->NumberOfProcessIdsInList; i++) { clientId.UniqueProcess = (HANDLE)processIdList->ProcessIdList[i]; name = PHA_DEREFERENCE(PhGetClientIdName(&clientId)); PhAddListViewItem(processesLv, MAXINT, PhGetString(name), NULL); } PhFree(processIdList); } }
NTSTATUS SetupDownloadWebSetupThread( _In_ PPH_SETUP_CONTEXT Context ) { ULONGLONG currentVersion = 0; ULONGLONG latestVersion = 0; PPH_STRING setupFileName; PH_IMAGE_VERSION_INFO versionInfo; if (!SetupQueryUpdateData(Context)) goto CleanupExit; setupFileName = PhGetApplicationFileName(); if (!PhInitializeImageVersionInfo(&versionInfo, PhGetString(setupFileName))) goto CleanupExit; currentVersion = ParseVersionString(versionInfo.FileVersion); #ifdef FORCE_UPDATE_CHECK latestVersion = MAKE_VERSION_ULONGLONG( 9999, 9999, 9999, 0 ); #else latestVersion = ParseVersionString(Context->WebSetupFileVersion); #endif // Compare the current version against the latest available version if (currentVersion < latestVersion) { if (!UpdateDownloadUpdateData(Context)) goto CleanupExit; } PostMessage(Context->DialogHandle, PSM_SETCURSELID, 0, IDD_DIALOG5); return STATUS_SUCCESS; CleanupExit: PostMessage(Context->DialogHandle, PSM_SETCURSELID, 0, IDD_ERROR); return STATUS_FAIL_CHECK; }
NTSTATUS PhpModuleQueryWorker( _In_ PVOID Parameter ) { PPH_MODULE_QUERY_DATA data = (PPH_MODULE_QUERY_DATA)Parameter; data->VerifyResult = PhVerifyFileCached( data->ModuleItem->FileName, PhGetString(data->ModuleProvider->PackageFullName), &data->VerifySignerName, FALSE ); RtlInterlockedPushEntrySList(&data->ModuleProvider->QueryListHead, &data->ListEntry); PhDereferenceObject(data->ModuleProvider); return STATUS_SUCCESS; }
PVIRUSTOTAL_FILE_HASH_ENTRY VirusTotalAddCacheResult( _In_ PPH_STRING FileName, _In_ PPROCESS_EXTENSION Extension ) { PVIRUSTOTAL_FILE_HASH_ENTRY result; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_HASH_ENTRY)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_HASH_ENTRY)); PhReferenceObject(FileName); result->FileName = FileName; result->FileNameAnsi = PhConvertUtf16ToMultiByte(PhGetString(FileName)); result->Extension = Extension; PhAcquireQueuedLockExclusive(&ProcessListLock); PhAddItemList(VirusTotalList, result); PhReleaseQueuedLockExclusive(&ProcessListLock); return result; }
ULONG64 ParseVersionString( _Inout_ PPH_STRING VersionString ) { PH_STRINGREF remaining, majorPart, minorPart, revisionPart; ULONG64 majorInteger = 0, minorInteger = 0, revisionInteger = 0; PhInitializeStringRef(&remaining, PhGetString(VersionString)); PhSplitStringRefAtChar(&remaining, '.', &majorPart, &remaining); PhSplitStringRefAtChar(&remaining, '.', &minorPart, &remaining); PhSplitStringRefAtChar(&remaining, '.', &revisionPart, &remaining); PhStringToInteger64(&majorPart, 10, &majorInteger); PhStringToInteger64(&minorPart, 10, &minorInteger); PhStringToInteger64(&revisionPart, 10, &revisionInteger); return MAKE_VERSION_ULONGLONG( (ULONG)majorInteger, (ULONG)minorInteger, (ULONG)revisionInteger, 0 ); }
INT_PTR CALLBACK PhpHandleGeneralDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PHANDLE_PROPERTIES_CONTEXT context = (PHANDLE_PROPERTIES_CONTEXT)propSheetPage->lParam; PPH_ACCESS_ENTRY accessEntries; ULONG numberOfAccessEntries; HANDLE processHandle; OBJECT_BASIC_INFORMATION basicInfo; BOOLEAN haveBasicInfo = FALSE; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); SetDlgItemText(hwndDlg, IDC_NAME, PhGetString(context->HandleItem->BestObjectName)); SetDlgItemText(hwndDlg, IDC_TYPE, context->HandleItem->TypeName->Buffer); SetDlgItemText(hwndDlg, IDC_ADDRESS, context->HandleItem->ObjectString); if (PhGetAccessEntries( context->HandleItem->TypeName->Buffer, &accessEntries, &numberOfAccessEntries )) { PPH_STRING accessString; PPH_STRING grantedAccessString; accessString = PhGetAccessString( context->HandleItem->GrantedAccess, accessEntries, numberOfAccessEntries ); if (accessString->Length != 0) { grantedAccessString = PhFormatString( L"%s (%s)", context->HandleItem->GrantedAccessString, accessString->Buffer ); SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, grantedAccessString->Buffer); PhDereferenceObject(grantedAccessString); } else { SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString); } PhDereferenceObject(accessString); PhFree(accessEntries); } else { SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString); } if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, context->ProcessId ))) { if (NT_SUCCESS(PhGetHandleInformation( processHandle, context->HandleItem->Handle, -1, &basicInfo, NULL, NULL, NULL ))) { SetDlgItemInt(hwndDlg, IDC_REFERENCES, basicInfo.PointerCount, FALSE); SetDlgItemInt(hwndDlg, IDC_HANDLES, basicInfo.HandleCount, FALSE); SetDlgItemInt(hwndDlg, IDC_PAGED, basicInfo.PagedPoolCharge, FALSE); SetDlgItemInt(hwndDlg, IDC_NONPAGED, basicInfo.NonPagedPoolCharge, FALSE); haveBasicInfo = TRUE; } NtClose(processHandle); } if (!haveBasicInfo) { SetDlgItemText(hwndDlg, IDC_REFERENCES, L"Unknown"); SetDlgItemText(hwndDlg, IDC_HANDLES, L"Unknown"); SetDlgItemText(hwndDlg, IDC_PAGED, L"Unknown"); SetDlgItemText(hwndDlg, IDC_NONPAGED, L"Unknown"); } } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_BASICINFORMATION)); } return TRUE; } } break; } return FALSE; }
PPH_BYTES VirusTotalSendHttpRequest( _In_ PPH_BYTES JsonArray ) { PPH_BYTES subRequestBuffer = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate(&httpContext, PhGetString(userAgentString))) goto CleanupExit; if (!PhHttpSocketConnect(httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT)) goto CleanupExit; { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%S", L"/partners", L"/sysinternals", L"/file-reports", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", urlPathString->Buffer, PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, JsonArray->Buffer, (ULONG)JsonArray->Length)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(subRequestBuffer = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); PhClearReference(&urlPathString); PhClearReference(&versionString); PhClearReference(&userAgentString); if (JsonArray) PhDereferenceObject(JsonArray); return subRequestBuffer; }
PVIRUSTOTAL_FILE_REPORT VirusTotalRequestFileReport( _In_ PPH_STRING FileHash ) { PVIRUSTOTAL_FILE_REPORT result = NULL; PPH_BYTES jsonString = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; PVOID jsonRootObject = NULL; PVOID jsonScanObject; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate( &httpContext, PhGetString(userAgentString) )) { goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT )) { goto CleanupExit; } { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/file", L"/report", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer, L"&resource=", FileHash->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", PhGetString(urlPathString), PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(jsonString = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; if (!(jsonRootObject = PhCreateJsonParser(jsonString->Buffer))) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_REPORT)); result->ResponseCode = PhGetJsonValueAsLong64(jsonRootObject, "response_code"); result->StatusMessage = PhGetJsonValueAsString(jsonRootObject, "verbose_msg"); result->PermaLink = PhGetJsonValueAsString(jsonRootObject, "permalink"); result->ScanDate = PhGetJsonValueAsString(jsonRootObject, "scan_date"); result->ScanId = PhGetJsonValueAsString(jsonRootObject, "scan_id"); result->Total = PhFormatUInt64(PhGetJsonValueAsLong64(jsonRootObject, "total"), FALSE); result->Positives = PhFormatUInt64(PhGetJsonValueAsLong64(jsonRootObject, "positives"), FALSE); //result->Md5 = PhGetJsonValueAsString(jsonRootObject, "md5"); //result->Sha1 = PhGetJsonValueAsString(jsonRootObject, "sha1"); //result->Sha256 = PhGetJsonValueAsString(jsonRootObject, "sha256"); if (jsonScanObject = PhGetJsonObject(jsonRootObject, "scans")) { PPH_LIST jsonArrayList; if (jsonArrayList = PhGetJsonObjectAsArrayList(jsonScanObject)) { result->ScanResults = PhCreateList(jsonArrayList->Count); for (ULONG i = 0; i < jsonArrayList->Count; i++) { PVIRUSTOTAL_FILE_REPORT_RESULT entry; PJSON_ARRAY_LIST_OBJECT object = jsonArrayList->Items[i]; entry = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); memset(entry, 0, sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); entry->Vendor = PhConvertUtf8ToUtf16(object->Key); entry->Detected = PhGetJsonObjectBool(object->Entry, "detected"); entry->EngineVersion = PhGetJsonValueAsString(object->Entry, "version"); entry->DetectionName = PhGetJsonValueAsString(object->Entry, "result"); entry->DatabaseDate = PhGetJsonValueAsString(object->Entry, "update"); PhAddItemList(result->ScanResults, entry); PhFree(object); } PhDereferenceObject(jsonArrayList); } } CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (jsonRootObject) PhFreeJsonParser(jsonRootObject); PhClearReference(&jsonString); PhClearReference(&versionString); PhClearReference(&userAgentString); return result; }
static VOID PhpRefreshProcessList( _In_ HWND hwndDlg, _In_ PCHOOSE_PROCESS_DIALOG_CONTEXT Context ) { NTSTATUS status; HWND lvHandle; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; lvHandle = Context->ListViewHandle; ListView_DeleteAllItems(lvHandle); ImageList_RemoveAll(Context->ImageList); if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) { PhShowStatus(hwndDlg, L"Unable to enumerate processes", status, 0); return; } ExtendedListView_SetRedraw(lvHandle, FALSE); process = PH_FIRST_PROCESS(processes); do { INT lvItemIndex; PPH_STRING name; HANDLE processHandle; PPH_STRING fileName = NULL; HICON icon = NULL; WCHAR processIdString[PH_INT32_STR_LEN_1]; PPH_STRING userName = NULL; INT imageIndex; if (process->UniqueProcessId != SYSTEM_IDLE_PROCESS_ID) name = PhCreateStringFromUnicodeString(&process->ImageName); else name = PhCreateString(SYSTEM_IDLE_PROCESS_NAME); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, name->Buffer, process->UniqueProcessId); PhDereferenceObject(name); if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess, process->UniqueProcessId))) { HANDLE tokenHandle; PTOKEN_USER user; if (!WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID) PhGetProcessImageFileName(processHandle, &fileName); if (NT_SUCCESS(PhOpenProcessToken(&tokenHandle, TOKEN_QUERY, processHandle))) { if (NT_SUCCESS(PhGetTokenUser(tokenHandle, &user))) { userName = PhGetSidFullName(user->User.Sid, TRUE, NULL); PhFree(user); } NtClose(tokenHandle); } NtClose(processHandle); } if (process->UniqueProcessId == SYSTEM_IDLE_PROCESS_ID && !userName && PhLocalSystemName) PhSetReference(&userName, PhLocalSystemName); if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID) PhGetProcessImageFileNameByProcessId(process->UniqueProcessId, &fileName); if (process->UniqueProcessId == SYSTEM_PROCESS_ID) fileName = PhGetKernelFileName(); if (fileName) PhMoveReference(&fileName, PhGetFileName(fileName)); icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", FALSE); // Icon if (icon) { imageIndex = ImageList_AddIcon(Context->ImageList, icon); PhSetListViewItemImageIndex(Context->ListViewHandle, lvItemIndex, imageIndex); DestroyIcon(icon); } // PID PhPrintUInt32(processIdString, HandleToUlong(process->UniqueProcessId)); PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 1, processIdString); // User Name PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 2, PhGetString(userName)); if (userName) PhDereferenceObject(userName); if (fileName) PhDereferenceObject(fileName); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); ExtendedListView_SortItems(lvHandle); ExtendedListView_SetRedraw(lvHandle, TRUE); }
INT_PTR CALLBACK PhpServiceGeneralDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)propSheetPage->lParam; PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; ULONG startType; ULONG errorControl; // HACK PhCenterWindow(GetParent(hwndDlg), GetParent(GetParent(hwndDlg))); SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_TYPE), PhServiceTypeStrings, sizeof(PhServiceTypeStrings) / sizeof(WCHAR *)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_STARTTYPE), PhServiceStartTypeStrings, sizeof(PhServiceStartTypeStrings) / sizeof(WCHAR *)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_ERRORCONTROL), PhServiceErrorControlStrings, sizeof(PhServiceErrorControlStrings) / sizeof(WCHAR *)); SetDlgItemText(hwndDlg, IDC_DESCRIPTION, serviceItem->DisplayName->Buffer); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_TYPE), PhGetServiceTypeString(serviceItem->Type), FALSE); startType = serviceItem->StartType; errorControl = serviceItem->ErrorControl; serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_QUERY_CONFIG); if (serviceHandle) { LPQUERY_SERVICE_CONFIG config; PPH_STRING description; BOOLEAN delayedStart; if (config = PhGetServiceConfig(serviceHandle)) { SetDlgItemText(hwndDlg, IDC_GROUP, config->lpLoadOrderGroup); SetDlgItemText(hwndDlg, IDC_BINARYPATH, config->lpBinaryPathName); SetDlgItemText(hwndDlg, IDC_USERACCOUNT, config->lpServiceStartName); if (startType != config->dwStartType || errorControl != config->dwErrorControl) { startType = config->dwStartType; errorControl = config->dwErrorControl; PhMarkNeedsConfigUpdateServiceItem(serviceItem); } PhFree(config); } if (description = PhGetServiceDescription(serviceHandle)) { SetDlgItemText(hwndDlg, IDC_DESCRIPTION, description->Buffer); PhDereferenceObject(description); } if ( WindowsVersion >= WINDOWS_VISTA && PhGetServiceDelayedAutoStart(serviceHandle, &delayedStart) ) { context->OldDelayedStart = delayedStart; if (delayedStart) Button_SetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART), BST_CHECKED); } CloseServiceHandle(serviceHandle); } PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_STARTTYPE), PhGetServiceStartTypeString(startType), FALSE); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_ERRORCONTROL), PhGetServiceErrorControlString(errorControl), FALSE); SetDlgItemText(hwndDlg, IDC_PASSWORD, L"password"); Button_SetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK), BST_UNCHECKED); SetDlgItemText(hwndDlg, IDC_SERVICEDLL, L"N/A"); { HANDLE keyHandle; PPH_STRING keyName; keyName = PhConcatStrings( 3, L"System\\CurrentControlSet\\Services\\", serviceItem->Name->Buffer, L"\\Parameters" ); if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName->sr, 0 ))) { PPH_STRING serviceDllString; if (serviceDllString = PhQueryRegistryString(keyHandle, L"ServiceDll")) { PPH_STRING expandedString; if (expandedString = PhExpandEnvironmentStrings(&serviceDllString->sr)) { SetDlgItemText(hwndDlg, IDC_SERVICEDLL, expandedString->Buffer); PhDereferenceObject(expandedString); } PhDereferenceObject(serviceDllString); } NtClose(keyHandle); } PhDereferenceObject(keyName); } PhpRefreshControls(hwndDlg); context->Ready = TRUE; } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); switch (LOWORD(wParam)) { case IDCANCEL: { // Workaround for property sheet + multiline edit: http://support.microsoft.com/kb/130765 SendMessage(GetParent(hwndDlg), uMsg, wParam, lParam); } break; case IDC_PASSWORD: { if (HIWORD(wParam) == EN_CHANGE) { Button_SetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK), BST_CHECKED); } } break; case IDC_DELAYEDSTART: { context->Dirty = TRUE; } break; case IDC_BROWSE: { static PH_FILETYPE_FILTER filters[] = { { L"Executable files (*.exe;*.sys)", L"*.exe;*.sys" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_STRING fileName; fileDialog = PhCreateOpenFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); fileName = PhGetFileName(PHA_GET_DLGITEM_TEXT(hwndDlg, IDC_BINARYPATH)); PhSetFileDialogFileName(fileDialog, fileName->Buffer); PhDereferenceObject(fileName); if (PhShowFileDialog(hwndDlg, fileDialog)) { fileName = PhGetFileDialogFileName(fileDialog); SetDlgItemText(hwndDlg, IDC_BINARYPATH, fileName->Buffer); PhDereferenceObject(fileName); } PhFreeFileDialog(fileDialog); } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { PhpRefreshControls(hwndDlg); if (context->Ready) context->Dirty = TRUE; } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_STARTTYPE)); } return TRUE; case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { NTSTATUS status; PSERVICE_PROPERTIES_CONTEXT context = (PSERVICE_PROPERTIES_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; PPH_STRING newServiceTypeString; PPH_STRING newServiceStartTypeString; PPH_STRING newServiceErrorControlString; ULONG newServiceType; ULONG newServiceStartType; ULONG newServiceErrorControl; PPH_STRING newServiceGroup; PPH_STRING newServiceBinaryPath; PPH_STRING newServiceUserAccount; PPH_STRING newServicePassword; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); if (!context->Dirty) { return TRUE; } newServiceTypeString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_TYPE))); newServiceStartTypeString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_STARTTYPE))); newServiceErrorControlString = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_ERRORCONTROL))); newServiceType = PhGetServiceTypeInteger(newServiceTypeString->Buffer); newServiceStartType = PhGetServiceStartTypeInteger(newServiceStartTypeString->Buffer); newServiceErrorControl = PhGetServiceErrorControlInteger(newServiceErrorControlString->Buffer); newServiceGroup = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_GROUP))); newServiceBinaryPath = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_BINARYPATH))); newServiceUserAccount = PHA_DEREFERENCE(PhGetWindowText(GetDlgItem(hwndDlg, IDC_USERACCOUNT))); if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_PASSWORDCHECK)) == BST_CHECKED) { newServicePassword = PhGetWindowText(GetDlgItem(hwndDlg, IDC_PASSWORD)); } else { newServicePassword = NULL; } if (newServiceType == SERVICE_KERNEL_DRIVER && newServiceUserAccount->Length == 0) { newServiceUserAccount = NULL; } serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_CHANGE_CONFIG); if (serviceHandle) { if (ChangeServiceConfig( serviceHandle, newServiceType, newServiceStartType, newServiceErrorControl, newServiceBinaryPath->Buffer, newServiceGroup->Buffer, NULL, NULL, PhGetString(newServiceUserAccount), PhGetString(newServicePassword), NULL )) { if (WindowsVersion >= WINDOWS_VISTA) { BOOLEAN newDelayedStart; newDelayedStart = Button_GetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART)) == BST_CHECKED; if (newDelayedStart != context->OldDelayedStart) { PhSetServiceDelayedAutoStart(serviceHandle, newDelayedStart); } } PhMarkNeedsConfigUpdateServiceItem(serviceItem); CloseServiceHandle(serviceHandle); } else { CloseServiceHandle(serviceHandle); goto ErrorCase; } } else { if (GetLastError() == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { if (NT_SUCCESS(status = PhSvcCallChangeServiceConfig( serviceItem->Name->Buffer, newServiceType, newServiceStartType, newServiceErrorControl, newServiceBinaryPath->Buffer, newServiceGroup->Buffer, NULL, NULL, PhGetString(newServiceUserAccount), PhGetString(newServicePassword), NULL ))) { if (WindowsVersion >= WINDOWS_VISTA) { BOOLEAN newDelayedStart; newDelayedStart = Button_GetCheck(GetDlgItem(hwndDlg, IDC_DELAYEDSTART)) == BST_CHECKED; if (newDelayedStart != context->OldDelayedStart) { SERVICE_DELAYED_AUTO_START_INFO info; info.fDelayedAutostart = newDelayedStart; PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &info ); } } PhMarkNeedsConfigUpdateServiceItem(serviceItem); } PhUiDisconnectFromPhSvc(); if (!NT_SUCCESS(status)) { SetLastError(PhNtStatusToDosError(status)); goto ErrorCase; } } else { // User cancelled elevation. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } else { goto ErrorCase; } } goto Cleanup; ErrorCase: if (PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service configuration: %s", ((PPH_STRING)PHA_DEREFERENCE(PhGetWin32Message(GetLastError())))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } Cleanup: if (newServicePassword) { RtlSecureZeroMemory(newServicePassword->Buffer, newServicePassword->Length); PhDereferenceObject(newServicePassword); } } return TRUE; } } break; } return FALSE; }
NTSTATUS UpdateDownloadThread( _In_ PVOID Parameter ) { BOOLEAN downloadSuccess = FALSE; BOOLEAN hashSuccess = FALSE; BOOLEAN signatureSuccess = FALSE; HANDLE tempFileHandle = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING downloadHostPath = NULL; PPH_STRING downloadUrlPath = NULL; PUPDATER_HASH_CONTEXT hashContext = NULL; USHORT httpPort = 0; LARGE_INTEGER timeNow; LARGE_INTEGER timeStart; ULONG64 timeTicks = 0; ULONG64 timeBitsPerSecond = 0; PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)Parameter; SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Initializing download request..."); if (!PhHttpSocketParseUrl( context->SetupFileDownloadUrl, &downloadHostPath, &downloadUrlPath, &httpPort )) { context->ErrorCode = GetLastError(); goto CleanupExit; } // Create the local path string. context->SetupFilePath = UpdaterParseDownloadFileName(downloadUrlPath); if (PhIsNullOrEmptyString(context->SetupFilePath)) goto CleanupExit; // Create temporary output file. if (!NT_SUCCESS(PhCreateFileWin32( &tempFileHandle, PhGetString(context->SetupFilePath), FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { goto CleanupExit; } SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Connecting..."); if (!PhHttpSocketCreate(&httpContext, NULL)) { context->ErrorCode = GetLastError(); goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, PhGetString(downloadHostPath), httpPort )) { context->ErrorCode = GetLastError(); goto CleanupExit; } if (!PhHttpSocketBeginRequest( httpContext, NULL, PhGetString(downloadUrlPath), PH_HTTP_FLAG_REFRESH | (httpPort == PH_HTTP_DEFAULT_HTTPS_PORT ? PH_HTTP_FLAG_SECURE : 0) )) { context->ErrorCode = GetLastError(); goto CleanupExit; } SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Sending download request..."); if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) { context->ErrorCode = GetLastError(); goto CleanupExit; } SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Waiting for response..."); if (!PhHttpSocketEndRequest(httpContext)) { context->ErrorCode = GetLastError(); goto CleanupExit; } else { ULONG bytesDownloaded = 0; ULONG downloadedBytes = 0; ULONG contentLength = 0; PPH_STRING status; IO_STATUS_BLOCK isb; BYTE buffer[PAGE_SIZE]; status = PhFormatString(L"Downloading update %s...", PhGetStringOrEmpty(context->Version)); SendMessage(context->DialogHandle, TDM_SET_MARQUEE_PROGRESS_BAR, FALSE, 0); SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)status->Buffer); PhDereferenceObject(status); if (!PhHttpSocketQueryHeaderUlong( httpContext, PH_HTTP_QUERY_CONTENT_LENGTH, &contentLength )) { context->ErrorCode = GetLastError(); goto CleanupExit; } // Initialize hash algorithm. if (!(hashContext = UpdaterInitializeHash())) goto CleanupExit; // Zero the buffer. memset(buffer, 0, PAGE_SIZE); // Start the clock. PhQuerySystemTime(&timeStart); // Download the data. while (PhHttpSocketReadData(httpContext, buffer, PAGE_SIZE, &bytesDownloaded)) { // If we get zero bytes, the file was uploaded or there was an error if (bytesDownloaded == 0) break; // If the dialog was closed, just cleanup and exit if (!UpdateDialogThreadHandle) goto CleanupExit; // Update the hash of bytes we downloaded. UpdaterUpdateHash(hashContext, buffer, bytesDownloaded); // Write the downloaded bytes to disk. if (!NT_SUCCESS(NtWriteFile( tempFileHandle, NULL, NULL, NULL, &isb, buffer, bytesDownloaded, NULL, NULL ))) { goto CleanupExit; } downloadedBytes += (DWORD)isb.Information; // Check the number of bytes written are the same we downloaded. if (bytesDownloaded != isb.Information) goto CleanupExit; // Query the current time PhQuerySystemTime(&timeNow); // Calculate the number of ticks timeTicks = (timeNow.QuadPart - timeStart.QuadPart) / PH_TICKS_PER_SEC; timeBitsPerSecond = downloadedBytes / __max(timeTicks, 1); // TODO: Update on timer callback. { FLOAT percent = ((FLOAT)downloadedBytes / contentLength * 100); PPH_STRING totalLength = PhFormatSize(contentLength, -1); PPH_STRING totalDownloaded = PhFormatSize(downloadedBytes, -1); PPH_STRING totalSpeed = PhFormatSize(timeBitsPerSecond, -1); PPH_STRING statusMessage = PhFormatString( L"Downloaded: %s of %s (%.0f%%)\r\nSpeed: %s/s", PhGetStringOrEmpty(totalDownloaded), PhGetStringOrEmpty(totalLength), percent, PhGetStringOrEmpty(totalSpeed) ); SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_CONTENT, (LPARAM)statusMessage->Buffer); SendMessage(context->DialogHandle, TDM_SET_PROGRESS_BAR_POS, (WPARAM)percent, 0); PhDereferenceObject(statusMessage); PhDereferenceObject(totalSpeed); PhDereferenceObject(totalLength); PhDereferenceObject(totalDownloaded); } } if (UpdaterVerifyHash(hashContext, context->SetupFileHash)) { hashSuccess = TRUE; } if (UpdaterVerifySignature(hashContext, context->SetupFileSignature)) { signatureSuccess = TRUE; } if (hashSuccess && signatureSuccess) { downloadSuccess = TRUE; } } CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (hashContext) UpdaterDestroyHash(hashContext); if (tempFileHandle) NtClose(tempFileHandle); if (downloadHostPath) PhDereferenceObject(downloadHostPath); if (downloadUrlPath) PhDereferenceObject(downloadUrlPath); if (UpdateDialogThreadHandle) { if (downloadSuccess && hashSuccess && signatureSuccess) { ShowUpdateInstallDialog(context); } else if (downloadSuccess) { if (signatureSuccess) ShowUpdateFailedDialog(context, TRUE, FALSE); else if (hashSuccess) ShowUpdateFailedDialog(context, FALSE, TRUE); else ShowUpdateFailedDialog(context, FALSE, FALSE); } else { ShowUpdateFailedDialog(context, FALSE, FALSE); } } PhDereferenceObject(context); return STATUS_SUCCESS; }
HRESULT CALLBACK FinalTaskDialogCallbackProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR dwRefData ) { PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData; switch (uMsg) { case TDN_NAVIGATED: { if (!UpdaterCheckApplicationDirectory()) { SendMessage(hwndDlg, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, IDYES, TRUE); } } break; case TDN_BUTTON_CLICKED: { INT buttonId = (INT)wParam; if (buttonId == IDRETRY) { ShowCheckForUpdatesDialog(context); return S_FALSE; } else if (buttonId == IDYES) { SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) }; PPH_STRING parameters; if (PhIsNullOrEmptyString(context->SetupFilePath)) break; parameters = PH_AUTO(PhGetApplicationDirectory()); parameters = PH_AUTO(PhBufferToHexString((PUCHAR)parameters->Buffer, (ULONG)parameters->Length)); parameters = PH_AUTO(PhConcatStrings(3, L"-update \"", PhGetStringOrEmpty(parameters), L"\"")); info.lpFile = PhGetStringOrEmpty(context->SetupFilePath); info.lpParameters = PhGetString(parameters); info.lpVerb = UpdaterCheckApplicationDirectory() ? NULL : L"runas"; info.nShow = SW_SHOW; info.hwnd = hwndDlg; info.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOZONECHECKS; ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle); if (ShellExecuteEx(&info)) { ProcessHacker_Destroy(PhMainWndHandle); } else { ULONG errorCode = GetLastError(); // Install failed, cancel the shutdown. ProcessHacker_CancelEarlyShutdown(PhMainWndHandle); // Show error dialog. if (errorCode != ERROR_CANCELLED) // Ignore UAC decline. { PhShowStatus(hwndDlg, L"Unable to execute the setup.", 0, errorCode); if (context->StartupCheck) ShowAvailableDialog(context); else ShowCheckForUpdatesDialog(context); } return S_FALSE; } } } break; case TDN_HYPERLINK_CLICKED: { TaskDialogLinkClicked(context); return S_FALSE; } break; } return S_OK; }
PVIRUSTOTAL_API_RESPONSE VirusTotalRequestIpAddressReport( _In_ PPH_STRING IpAddress ) { PVIRUSTOTAL_API_RESPONSE result = NULL; PPH_BYTES jsonString = NULL; PPH_HTTP_CONTEXT httpContext = NULL; PPH_STRING versionString = NULL; PPH_STRING userAgentString = NULL; PPH_STRING urlPathString = NULL; PVOID jsonRootObject = NULL; versionString = PhGetPhVersion(); userAgentString = PhConcatStrings2(L"ProcessHacker_", versionString->Buffer); if (!PhHttpSocketCreate( &httpContext, PhGetString(userAgentString) )) { goto CleanupExit; } if (!PhHttpSocketConnect( httpContext, L"www.virustotal.com", PH_HTTP_DEFAULT_HTTPS_PORT )) { goto CleanupExit; } { PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlPathString = PhFormatString( L"%s%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/ip-address", L"/report", L"?\x0061\x0070\x0069\x006B\x0065\x0079=", resourceString->Buffer, L"&ip=", IpAddress->Buffer ); PhClearReference(&resourceString); } if (!PhHttpSocketBeginRequest( httpContext, L"POST", PhGetString(urlPathString), PH_HTTP_FLAG_REFRESH | PH_HTTP_FLAG_SECURE )) { goto CleanupExit; } if (!PhHttpSocketAddRequestHeaders(httpContext, L"Content-Type: application/json", 0)) goto CleanupExit; if (!PhHttpSocketSendRequest(httpContext, NULL, 0)) goto CleanupExit; if (!PhHttpSocketEndRequest(httpContext)) goto CleanupExit; if (!(jsonString = PhHttpSocketDownloadString(httpContext, FALSE))) goto CleanupExit; if (!(jsonRootObject = PhCreateJsonParser(jsonString->Buffer))) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_API_RESPONSE)); memset(result, 0, sizeof(VIRUSTOTAL_API_RESPONSE)); //result->ResponseCode = PhGetJsonValueAsLong64(jsonRootObject, "response_code"); //result->StatusMessage = PhGetJsonValueAsString(jsonRootObject, "verbose_msg"); //result->PermaLink = PhGetJsonValueAsString(jsonRootObject, "permalink"); //result->ScanId = PhGetJsonValueAsString(jsonRootObject, "scan_id"); CleanupExit: if (httpContext) PhHttpSocketDestroy(httpContext); if (jsonRootObject) PhFreeJsonParser(jsonRootObject); PhClearReference(&jsonString); PhClearReference(&versionString); PhClearReference(&userAgentString); return result; }
INT_PTR CALLBACK PhpColumnSetEditorDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PCOLUMNSET_DIALOG_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(COLUMNSET_DIALOG_CONTEXT)); memset(context, 0, sizeof(COLUMNSET_DIALOG_CONTEXT)); context->SettingName = PhCreateString((PWSTR)lParam); SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } else { context = (PCOLUMNSET_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { context->DialogHandle = hwndDlg; context->ListViewHandle = GetDlgItem(hwndDlg, IDC_COLUMNSETLIST); context->RenameButtonHandle = GetDlgItem(hwndDlg, IDC_RENAME); context->MoveUpButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEUP); context->MoveDownButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEDOWN); context->RemoveButtonHandle = GetDlgItem(hwndDlg, IDC_REMOVE); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE); PhSetControlTheme(context->ListViewHandle, L"explorer"); PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 250, L"Name"); PhSetExtendedListView(context->ListViewHandle); context->ColumnSetList = PhInitializeColumnSetList(PhGetString(context->SettingName)); for (ULONG i = 0; i < context->ColumnSetList->Count; i++) { PPH_COLUMN_SET_ENTRY entry = context->ColumnSetList->Items[i]; PhAddListViewItem(context->ListViewHandle, MAXINT, entry->Name->Buffer, entry); } Button_Enable(context->RenameButtonHandle, FALSE); Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); Button_Enable(context->RemoveButtonHandle, FALSE); } break; case WM_DESTROY: { PhDeleteColumnSetList(context->ColumnSetList); RemoveProp(hwndDlg, PhMakeContextAtom()); PhFree(context); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { if (context->LabelEditActive) break; PhSaveSettingsColumnList(PhGetString(context->SettingName), context->ColumnSetList); EndDialog(hwndDlg, IDOK); } break; case IDC_RENAME: { INT lvItemIndex; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1) { SetFocus(context->ListViewHandle); ListView_EditLabel(context->ListViewHandle, lvItemIndex); } } break; case IDC_MOVEUP: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; PhpMoveSelectedListViewItemUp(context->ListViewHandle); lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhInsertItemList(context->ColumnSetList, lvItemIndex, entry); } } } break; case IDC_MOVEDOWN: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; PhpMoveSelectedListViewItemDown(context->ListViewHandle); lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhInsertItemList(context->ColumnSetList, lvItemIndex, entry); } } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhRemoveListViewItem(context->ListViewHandle, lvItemIndex); PhClearReference(&entry->Name); PhClearReference(&entry->Setting); PhClearReference(&entry->Sorting); PhFree(entry); } SetFocus(context->ListViewHandle); ListView_SetItemState(context->ListViewHandle, 0, LVNI_SELECTED, LVNI_SELECTED); //ListView_EnsureVisible(context->ListViewHandle, 0, FALSE); } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case NM_DBLCLK: { INT lvItemIndex; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1) { SetFocus(context->ListViewHandle); ListView_EditLabel(context->ListViewHandle, lvItemIndex); } } break; case LVN_ITEMCHANGED: { LPNMLISTVIEW listview = (LPNMLISTVIEW)lParam; INT index; INT lvItemIndex; INT count; index = listview->iItem; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); count = ListView_GetItemCount(context->ListViewHandle); if (count == 0 || index == -1 || lvItemIndex == -1) { Button_Enable(context->RenameButtonHandle, FALSE); Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); Button_Enable(context->RemoveButtonHandle, FALSE); break; } if (index != lvItemIndex) break; if (index == 0 && count == 1) { // First and last item Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); } else if (index == (count - 1)) { // Last item Button_Enable(context->MoveUpButtonHandle, TRUE); Button_Enable(context->MoveDownButtonHandle, FALSE); } else if (index == 0) { // First item Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, TRUE); } else { Button_Enable(context->MoveUpButtonHandle, TRUE); Button_Enable(context->MoveDownButtonHandle, TRUE); } Button_Enable(context->RenameButtonHandle, TRUE); Button_Enable(context->RemoveButtonHandle, TRUE); } break; case LVN_BEGINLABELEDIT: context->LabelEditActive = TRUE; break; case LVN_ENDLABELEDIT: { LV_DISPINFO* lvinfo = (LV_DISPINFO*)lParam; if (lvinfo->item.iItem != -1 && lvinfo->item.pszText) { BOOLEAN found = FALSE; PPH_COLUMN_SET_ENTRY entry; ULONG index; for (ULONG i = 0; i < context->ColumnSetList->Count; i++) { entry = context->ColumnSetList->Items[i]; if (PhEqualStringRef2(&entry->Name->sr, lvinfo->item.pszText, FALSE)) { found = TRUE; break; } } if (!found && PhGetListViewItemParam(context->ListViewHandle, lvinfo->item.iItem, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhMoveReference(&entry->Name, PhCreateString(lvinfo->item.pszText)); ListView_SetItemText(context->ListViewHandle, lvinfo->item.iItem, 0, lvinfo->item.pszText); } } } context->LabelEditActive = FALSE; } break; } } break; } return FALSE; }
PSTR VirusTotalSendHttpRequest( _In_ PPH_BYTES JsonArray ) { HANDLE fileHandle = INVALID_HANDLE_VALUE; HINTERNET httpSessionHandle = NULL; HINTERNET connectHandle = NULL; HINTERNET requestHandle = NULL; PSTR subRequestBuffer = NULL; PPH_STRING phVersion = NULL; PPH_STRING userAgent = NULL; PPH_STRING urlString = NULL; phVersion = PhGetPhVersion(); userAgent = PhConcatStrings2(L"ProcessHacker_", phVersion->Buffer); if (!(httpSessionHandle = WinHttpOpen( userAgent->Buffer, WindowsVersion >= WINDOWS_8_1 ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ))) { goto CleanupExit; } if (WindowsVersion >= WINDOWS_8_1) { WinHttpSetOption( httpSessionHandle, WINHTTP_OPTION_DECOMPRESSION, &(ULONG){ WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE }, sizeof(ULONG) ); } if (!(connectHandle = WinHttpConnect( httpSessionHandle, L"www.virustotal.com", INTERNET_DEFAULT_HTTPS_PORT, 0 ))) { goto CleanupExit; } PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlString = PhFormatString( L"%s%s%s%s%S", L"/partners", L"/sysinternals", L"/file-reports", L"?apikey=", resourceString->Buffer ); PhClearReference(&resourceString); if (!(requestHandle = WinHttpOpenRequest( connectHandle, L"POST", PhGetString(urlString), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE ))) { PhClearReference(&urlString); goto CleanupExit; } PhClearReference(&urlString); if (!WinHttpAddRequestHeaders(requestHandle, L"Content-Type: application/json", -1L, 0)) { goto CleanupExit; } if (!WinHttpSendRequest( requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, JsonArray->Buffer, (ULONG)JsonArray->Length, (ULONG)JsonArray->Length, 0 )) { goto CleanupExit; } if (WinHttpReceiveResponse(requestHandle, NULL)) { BYTE buffer[PAGE_SIZE]; ULONG allocatedLength; ULONG dataLength; ULONG returnLength; allocatedLength = sizeof(buffer); subRequestBuffer = PhAllocate(allocatedLength); dataLength = 0; while (WinHttpReadData(requestHandle, buffer, PAGE_SIZE, &returnLength)) { if (returnLength == 0) break; if (allocatedLength < dataLength + returnLength) { allocatedLength *= 2; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } memcpy(subRequestBuffer + dataLength, buffer, returnLength); dataLength += returnLength; } if (allocatedLength < dataLength + 1) { allocatedLength++; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } // Ensure that the buffer is null-terminated. subRequestBuffer[dataLength] = 0; } CleanupExit: if (requestHandle) WinHttpCloseHandle(requestHandle); if (connectHandle) WinHttpCloseHandle(connectHandle); if (httpSessionHandle) WinHttpCloseHandle(httpSessionHandle); if (JsonArray) PhDereferenceObject(JsonArray); return subRequestBuffer; }
PVIRUSTOTAL_FILE_REPORT_RESULT VirusTotalSendHttpFileReportRequest( _In_ PPH_STRING FileHash ) { NTSTATUS status = STATUS_SUCCESS; HANDLE fileHandle = INVALID_HANDLE_VALUE; HINTERNET httpSessionHandle = NULL; HINTERNET connectHandle = NULL; HINTERNET requestHandle = NULL; PSTR subRequestBuffer = NULL; PPH_STRING phVersion = NULL; PPH_STRING userAgent = NULL; PPH_STRING urlString = NULL; phVersion = PhGetPhVersion(); userAgent = PhConcatStrings2(L"ProcessHacker_", phVersion->Buffer); if (!(httpSessionHandle = WinHttpOpen( userAgent->Buffer, WindowsVersion >= WINDOWS_8_1 ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ))) { goto CleanupExit; } if (WindowsVersion >= WINDOWS_8_1) { WinHttpSetOption( httpSessionHandle, WINHTTP_OPTION_DECOMPRESSION, &(ULONG){ WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE }, sizeof(ULONG) ); } if (!(connectHandle = WinHttpConnect( httpSessionHandle, L"www.virustotal.com", INTERNET_DEFAULT_HTTPS_PORT, 0 ))) { goto CleanupExit; } PPH_BYTES resourceString = VirusTotalGetCachedDbHash(); urlString = PhFormatString( L"%s%s%s%s%S%s%s", L"/vtapi", L"/v2", L"/file", L"/report", L"?apikey=", resourceString->Buffer, L"&resource=", PhGetString(FileHash) ); PhClearReference(&resourceString); if (!(requestHandle = WinHttpOpenRequest( connectHandle, L"POST", PhGetString(urlString), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE ))) { goto CleanupExit; } if (!WinHttpAddRequestHeaders(requestHandle, L"Content-Type: application/json", -1L, 0)) goto CleanupExit; if (!WinHttpSendRequest( requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0 )) { goto CleanupExit; } if (WinHttpReceiveResponse(requestHandle, NULL)) { BYTE buffer[PAGE_SIZE]; ULONG allocatedLength; ULONG dataLength; ULONG returnLength; allocatedLength = sizeof(buffer); subRequestBuffer = PhAllocate(allocatedLength); dataLength = 0; while (WinHttpReadData(requestHandle, buffer, PAGE_SIZE, &returnLength)) { if (returnLength == 0) break; if (allocatedLength < dataLength + returnLength) { allocatedLength *= 2; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } memcpy(subRequestBuffer + dataLength, buffer, returnLength); dataLength += returnLength; } if (allocatedLength < dataLength + 1) { allocatedLength++; subRequestBuffer = PhReAllocate(subRequestBuffer, allocatedLength); } subRequestBuffer[dataLength] = 0; } CleanupExit: PhClearReference(&urlString); if (requestHandle) WinHttpCloseHandle(requestHandle); if (connectHandle) WinHttpCloseHandle(connectHandle); if (httpSessionHandle) WinHttpCloseHandle(httpSessionHandle); PVOID jsonRootObject; //PVOID jsonScanObject; PVIRUSTOTAL_FILE_REPORT_RESULT result; if (!(jsonRootObject = CreateJsonParser(subRequestBuffer))) goto CleanupExit; if (!GetJsonValueAsUlong(jsonRootObject, "response_code")) goto CleanupExit; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_REPORT_RESULT)); result->Total = PhFormatUInt64(GetJsonValueAsUlong(jsonRootObject, "total"), FALSE); result->Positives = PhFormatUInt64(GetJsonValueAsUlong(jsonRootObject, "positives"), FALSE); result->Resource = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "resource")); result->ScanId = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "scan_id")); result->Md5 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "md5")); result->Sha1 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "sha1")); result->Sha256 = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "sha256")); result->ScanDate = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "scan_date")); result->Permalink = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "permalink")); result->StatusMessage = PhZeroExtendToUtf16(GetJsonValueAsString(jsonRootObject, "verbose_msg")); //if (jsonScanObject = JsonGetObject(jsonRootObject, "scans")) //{ // PPH_LIST jsonArrayList; // // if (jsonArrayList = JsonGetObjectArrayList(jsonScanObject)) // { // result->ScanResults = PhCreateList(jsonArrayList->Count); // // for (ULONG i = 0; i < jsonArrayList->Count; i++) // { // PJSON_ARRAY_LIST_OBJECT object = jsonArrayList->Items[i]; // //BOOLEAN detected = GetJsonValueAsBool(object->Entry, "detected") == TRUE; // //PSTR version = GetJsonValueAsString(object->Entry, "version"); // //PSTR result = GetJsonValueAsString(object->Entry, "result"); // //PSTR update = GetJsonValueAsString(object->Entry, "update"); // // PhFree(object); // } // // PhDereferenceObject(jsonArrayList); // } //} return result; }
VOID PhpRefreshGdiHandles( _In_ HWND hwndDlg, _In_ PGDI_HANDLES_CONTEXT Context ) { HWND lvHandle; ULONG i; PGDI_SHARED_MEMORY gdiShared; USHORT processId; PGDI_HANDLE_ENTRY handle; PPH_GDI_HANDLE_ITEM gdiHandleItem; lvHandle = GetDlgItem(hwndDlg, IDC_LIST); ExtendedListView_SetRedraw(lvHandle, FALSE); ListView_DeleteAllItems(lvHandle); for (i = 0; i < Context->List->Count; i++) { gdiHandleItem = Context->List->Items[i]; if (gdiHandleItem->Information) PhDereferenceObject(gdiHandleItem->Information); PhFree(Context->List->Items[i]); } PhClearList(Context->List); gdiShared = (PGDI_SHARED_MEMORY)NtCurrentPeb()->GdiSharedHandleTable; processId = (USHORT)Context->ProcessItem->ProcessId; for (i = 0; i < GDI_MAX_HANDLE_COUNT; i++) { PWSTR typeName; INT lvItemIndex; WCHAR pointer[PH_PTR_STR_LEN_1]; handle = &gdiShared->Handles[i]; if (handle->Owner.ProcessId != processId) continue; typeName = PhpGetGdiHandleTypeName(handle->Unique); if (!typeName) continue; gdiHandleItem = PhAllocate(sizeof(PH_GDI_HANDLE_ITEM)); gdiHandleItem->Entry = handle; gdiHandleItem->Handle = GDI_MAKE_HANDLE(i, handle->Unique); gdiHandleItem->Object = handle->Object; gdiHandleItem->TypeName = typeName; gdiHandleItem->Information = PhpGetGdiHandleInformation(gdiHandleItem->Handle); PhAddItemList(Context->List, gdiHandleItem); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, gdiHandleItem->TypeName, gdiHandleItem); PhPrintPointer(pointer, UlongToPtr(gdiHandleItem->Handle)); PhSetListViewSubItem(lvHandle, lvItemIndex, 1, pointer); PhPrintPointer(pointer, gdiHandleItem->Object); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, pointer); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, PhGetString(gdiHandleItem->Information)); } ExtendedListView_SortItems(lvHandle); ExtendedListView_SetRedraw(lvHandle, TRUE); }
INT_PTR CALLBACK RestartComputerDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_RECOVERY_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PSERVICE_RECOVERY_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_RECOVERY_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { SetDlgItemInt(hwndDlg, IDC_RESTARTCOMPAFTER, context->RebootAfter / (1000 * 60), FALSE); // ms to min Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLERESTARTMESSAGE), context->RebootMessage ? BST_CHECKED : BST_UNCHECKED); SetDlgItemText(hwndDlg, IDC_RESTARTMESSAGE, PhGetString(context->RebootMessage)); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_RESTARTCOMPAFTER), TRUE); Edit_SetSel(GetDlgItem(hwndDlg, IDC_RESTARTCOMPAFTER), 0, -1); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { context->RebootAfter = GetDlgItemInt(hwndDlg, IDC_RESTARTCOMPAFTER, NULL, FALSE) * 1000 * 60; if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLERESTARTMESSAGE)) == BST_CHECKED) PhMoveReference(&context->RebootMessage, PhGetWindowText(GetDlgItem(hwndDlg, IDC_RESTARTMESSAGE))); else PhClearReference(&context->RebootMessage); context->Dirty = TRUE; EndDialog(hwndDlg, IDOK); } break; case IDC_USEDEFAULTMESSAGE: { PPH_STRING message; PWSTR computerName; ULONG bufferSize; BOOLEAN allocated = TRUE; // Get the computer name. bufferSize = 64; computerName = PhAllocate((bufferSize + 1) * sizeof(WCHAR)); if (!GetComputerName(computerName, &bufferSize)) { PhFree(computerName); computerName = PhAllocate((bufferSize + 1) * sizeof(WCHAR)); if (!GetComputerName(computerName, &bufferSize)) { PhFree(computerName); computerName = L"(unknown)"; allocated = FALSE; } } // This message is exactly the same as the one in the Services console, // except the double spaces are replaced by single spaces. message = PhFormatString( L"Your computer is connected to the computer named %s. " L"The %s service on %s has ended unexpectedly. " L"%s will restart automatically, and then you can reestablish the connection.", computerName, context->ServiceItem->Name->Buffer, computerName, computerName ); SetDlgItemText(hwndDlg, IDC_RESTARTMESSAGE, message->Buffer); PhDereferenceObject(message); if (allocated) PhFree(computerName); Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLERESTARTMESSAGE), BST_CHECKED); } break; case IDC_RESTARTMESSAGE: { if (HIWORD(wParam) == EN_CHANGE) { // A zero length restart message disables it, so we might as well uncheck the box. Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLERESTARTMESSAGE), GetWindowTextLength(GetDlgItem(hwndDlg, IDC_RESTARTMESSAGE)) != 0 ? BST_CHECKED : BST_UNCHECKED); } } break; } } break; } return FALSE; }
int __cdecl main(int argc, char *argv[]) { static PH_COMMAND_LINE_OPTION options[] = { { FI_ARG_HELP, L"h", NoArgumentType }, { FI_ARG_ACTION, L"a", MandatoryArgumentType }, { FI_ARG_NATIVE, L"N", NoArgumentType }, { FI_ARG_PATTERN, L"p", MandatoryArgumentType }, { FI_ARG_CASESENSITIVE, L"C", NoArgumentType }, { FI_ARG_OUTPUT, L"o", MandatoryArgumentType }, { FI_ARG_FORCE, L"f", NoArgumentType }, { FI_ARG_LENGTH, L"L", MandatoryArgumentType } }; PH_STRINGREF commandLine; NTSTATUS status = STATUS_SUCCESS; if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0))) return 1; PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine); if (!PhParseCommandLine( &commandLine, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_FIRST_PART, FiCommandLineCallback, NULL ) || FiArgHelp) { FiPrintHelp(); return 0; } if (!FiArgFileName && ( FiArgAction && PhEqualString2(FiArgAction, L"dir", TRUE) )) { FiArgFileName = PhCreateStringFromUnicodeString(&NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath); } if (!FiArgAction) { FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"map", TRUE)) { WCHAR deviceNameBuffer[7] = L"\\??\\ :"; ULONG i; WCHAR targetNameBuffer[0x100]; UNICODE_STRING targetName; targetName.Buffer = targetNameBuffer; targetName.MaximumLength = sizeof(targetNameBuffer); for (i = 0; i < 26; i++) { HANDLE linkHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING deviceName; deviceNameBuffer[4] = (WCHAR)('A' + i); deviceName.Buffer = deviceNameBuffer; deviceName.Length = 6 * sizeof(WCHAR); InitializeObjectAttributes( &oa, &deviceName, OBJ_CASE_INSENSITIVE, NULL, NULL ); if (NT_SUCCESS(NtOpenSymbolicLinkObject( &linkHandle, SYMBOLIC_LINK_QUERY, &oa ))) { if (NT_SUCCESS(NtQuerySymbolicLinkObject( linkHandle, &targetName, NULL ))) { wprintf(L"%c: %.*s\n", 'A' + i, targetName.Length / 2, targetName.Buffer); } NtClose(linkHandle); } } } else if (!FiArgFileName) { wprintf(L"Error: file name missing.\n"); FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"hash", TRUE)) { HANDLE fileHandle; LARGE_INTEGER fileSize; IO_STATUS_BLOCK isb; ULONG mode; if (!FiArgOutput) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"md5", TRUE)) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"sha1", TRUE)) mode = HASH_SHA1; else if (PhEqualString2(FiArgOutput, L"crc32", TRUE)) mode = HASH_CRC32; else { wprintf(L"Invalid hash algorithm. Possibilities: md5, sha1, crc32\n"); return 1; } if (FiCreateFile( &fileHandle, FILE_GENERIC_READ, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY )) { if (NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize))) { MD5_CTX md5Context; A_SHA_CTX shaContext; ULONG crc; UCHAR buffer[PAGE_SIZE * 4]; ULONG64 bytesRemaining; bytesRemaining = fileSize.QuadPart; switch (mode) { case HASH_MD5: MD5Init(&md5Context); break; case HASH_SHA1: A_SHAInit(&shaContext); break; case HASH_CRC32: crc = 0; break; } while (bytesRemaining) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, sizeof(buffer), NULL, NULL ); if (!NT_SUCCESS(status)) break; switch (mode) { case HASH_MD5: MD5Update(&md5Context, buffer, (ULONG)isb.Information); break; case HASH_SHA1: A_SHAUpdate(&shaContext, buffer, (ULONG)isb.Information); break; case HASH_CRC32: crc = PhCrc32(crc, buffer, isb.Information); break; } bytesRemaining -= (ULONG)isb.Information; } if (status == STATUS_END_OF_FILE) status = STATUS_SUCCESS; switch (mode) { case HASH_MD5: { MD5Final(&md5Context); wprintf(L"%s", PhBufferToHexString(md5Context.digest, 16)->Buffer); } break; case HASH_SHA1: { UCHAR hash[20]; A_SHAFinal(&shaContext, hash); wprintf(L"%s", PhBufferToHexString(hash, 20)->Buffer); } break; case HASH_CRC32: { wprintf(L"%08x", crc); } break; } if (!NT_SUCCESS(status)) wprintf(L"Warning: I/O error encountered: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } if (!NT_SUCCESS(status)) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else if (PhEqualString2(FiArgAction, L"execute", TRUE)) { if (FiArgNative) { if (!NT_SUCCESS(status = PhCreateProcess( FiFormatFileName(FiArgFileName)->Buffer, FiArgOutput ? &FiArgOutput->sr : NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else { if (!NT_SUCCESS(status = PhCreateProcessWin32( FiArgFileName->Buffer, PhGetString(FiArgOutput), NULL, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer, PH_CREATE_PROCESS_NEW_CONSOLE, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } } else if (PhEqualString2(FiArgAction, L"del", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT )) { FILE_DISPOSITION_INFORMATION dispositionInfo; IO_STATUS_BLOCK isb; dispositionInfo.DeleteFile = TRUE; if (!NT_SUCCESS(status = NtSetInformationFile(fileHandle, &isb, &dispositionInfo, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation))) { wprintf(L"Error deleting file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"touch", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"mkdir", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"rename", TRUE)) { HANDLE fileHandle; PPH_STRING newFileName; if (!FiArgOutput) { wprintf(L"Error: new file name missing.\n"); FiPrintHelp(); return 1; } newFileName = FiFormatFileName(FiArgOutput); if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { PFILE_RENAME_INFORMATION renameInfo; ULONG renameInfoSize; IO_STATUS_BLOCK isb; renameInfoSize = FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) + (ULONG)newFileName->Length; renameInfo = PhAllocate(renameInfoSize); renameInfo->ReplaceIfExists = FiArgForce; renameInfo->RootDirectory = NULL; renameInfo->FileNameLength = (ULONG)newFileName->Length; memcpy(renameInfo->FileName, newFileName->Buffer, newFileName->Length); status = NtSetInformationFile(fileHandle, &isb, renameInfo, renameInfoSize, FileRenameInformation); PhFree(renameInfo); if (!NT_SUCCESS(status)) { wprintf(L"Error renaming file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"copy", TRUE)) { HANDLE fileHandle; HANDLE outFileHandle; LARGE_INTEGER fileSize; FILE_BASIC_INFORMATION basicInfo; if (!FiArgOutput) { wprintf(L"Error: output file name missing.\n"); FiPrintHelp(); return 1; } if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | FILE_READ_DATA | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT ) && FiCreateFile( &outFileHandle, FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | SYNCHRONIZE, FiArgOutput, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, !FiArgForce ? FILE_CREATE : FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT )) { #define COPY_BUFFER_SIZE 0x10000 IO_STATUS_BLOCK isb; PVOID buffer; ULONG64 bytesToCopy = FiArgLength; if (NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize))) { PhSetFileSize(outFileHandle, &fileSize); } buffer = PhAllocatePage(COPY_BUFFER_SIZE, NULL); if (!buffer) { wprintf(L"Error allocating buffer.\n"); return 1; } while (bytesToCopy) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, bytesToCopy >= COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (ULONG)bytesToCopy, NULL, NULL ); if (status == STATUS_END_OF_FILE) { break; } else if (!NT_SUCCESS(status)) { wprintf(L"Error reading from file: %s\n", PhGetNtMessage(status)->Buffer); break; } status = NtWriteFile( outFileHandle, NULL, NULL, NULL, &isb, buffer, (ULONG)isb.Information, // number of bytes read NULL, NULL ); if (!NT_SUCCESS(status)) { wprintf(L"Error writing to output file: %s\n", PhGetNtMessage(status)->Buffer); break; } bytesToCopy -= (ULONG)isb.Information; } PhFreePage(buffer); // Copy basic attributes over. if (NT_SUCCESS(NtQueryInformationFile( fileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ))) { NtSetInformationFile( outFileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ); } NtClose(fileHandle); NtClose(outFileHandle); } } else if (PhEqualString2(FiArgAction, L"dir", TRUE)) { HANDLE fileHandle; UNICODE_STRING pattern; PPH_STRING totalSize, totalAllocSize; if (FiCreateFile( &fileHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { FipDirFileCount = 0; FipDirDirCount = 0; FipDirTotalSize = 0; FipDirTotalAllocSize = 0; if (FiArgPattern) PhStringRefToUnicodeString(&FiArgPattern->sr, &pattern); PhEnumDirectoryFile( fileHandle, FiArgPattern ? &pattern : NULL, FipEnumDirectoryFileForDir, NULL ); NtClose(fileHandle); totalSize = PhFormatUInt64(FipDirTotalSize, TRUE); totalAllocSize = PhFormatUInt64(FipDirTotalAllocSize, TRUE); wprintf( L"%12I64u file(s) %11s bytes\n" L"%12I64u dir(s) %11s bytes allocated\n", FipDirFileCount, totalSize->Buffer, FipDirDirCount, totalAllocSize->Buffer ); PhDereferenceObject(totalSize); PhDereferenceObject(totalAllocSize); } } else if (PhEqualString2(FiArgAction, L"streams", TRUE)) { HANDLE fileHandle; PVOID streams; PFILE_STREAM_INFORMATION stream; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { if (NT_SUCCESS(PhEnumFileStreams(fileHandle, &streams))) { stream = PH_FIRST_STREAM(streams); while (stream) { PPH_STRING size, allocationSize; size = PhFormatUInt64(stream->StreamSize.QuadPart, TRUE); allocationSize = PhFormatUInt64(stream->StreamAllocationSize.QuadPart, TRUE); wprintf( L"%11s %11s %.*s\n", size->Buffer, allocationSize->Buffer, stream->StreamNameLength / 2, stream->StreamName ); PhDereferenceObject(size); PhDereferenceObject(allocationSize); stream = PH_NEXT_STREAM(stream); } } NtClose(fileHandle); } } else { wprintf(L"Error: invalid action \"%s\".\n", FiArgAction->Buffer); FiPrintHelp(); return 1; } }
VOID PhModuleProviderUpdate( __in PVOID Object ) { PPH_MODULE_PROVIDER moduleProvider = (PPH_MODULE_PROVIDER)Object; PPH_LIST modules; ULONG i; // If we didn't get a handle when we created the provider, // abort (unless this is the System process - in that case // we don't need a handle). if (!moduleProvider->ProcessHandle && moduleProvider->ProcessId != SYSTEM_PROCESS_ID) return; modules = PhCreateList(20); PhEnumGenericModules( moduleProvider->ProcessId, moduleProvider->ProcessHandle, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, modules ); // Look for removed modules. { PPH_LIST modulesToRemove = NULL; ULONG enumerationKey = 0; PPH_MODULE_ITEM *moduleItem; while (PhEnumHashtable(moduleProvider->ModuleHashtable, (PPVOID)&moduleItem, &enumerationKey)) { BOOLEAN found = FALSE; // Check if the module still exists. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; if ((*moduleItem)->BaseAddress == module->BaseAddress) { found = TRUE; break; } } if (!found) { // Raise the module removed event. PhInvokeCallback(&moduleProvider->ModuleRemovedEvent, *moduleItem); if (!modulesToRemove) modulesToRemove = PhCreateList(2); PhAddItemList(modulesToRemove, *moduleItem); } } if (modulesToRemove) { PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); for (i = 0; i < modulesToRemove->Count; i++) { PhpRemoveModuleItem( moduleProvider, (PPH_MODULE_ITEM)modulesToRemove->Items[i] ); } PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhDereferenceObject(modulesToRemove); } } // Go through the queued thread query data. { PSLIST_ENTRY entry; PPH_MODULE_QUERY_DATA data; entry = RtlInterlockedFlushSList(&moduleProvider->QueryListHead); while (entry) { data = CONTAINING_RECORD(entry, PH_MODULE_QUERY_DATA, ListEntry); entry = entry->Next; data->ModuleItem->VerifyResult = data->VerifyResult; data->ModuleItem->VerifySignerName = data->VerifySignerName; data->ModuleItem->JustProcessed = TRUE; PhDereferenceObject(data->ModuleItem); PhFree(data); } } // Look for new modules. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PPH_MODULE_ITEM moduleItem; moduleItem = PhReferenceModuleItem(moduleProvider, module->BaseAddress); if (!moduleItem) { moduleItem = PhCreateModuleItem(); moduleItem->BaseAddress = module->BaseAddress; PhPrintPointer(moduleItem->BaseAddressString, moduleItem->BaseAddress); moduleItem->Size = module->Size; moduleItem->Flags = module->Flags; moduleItem->Type = module->Type; moduleItem->Reserved = 0; moduleItem->LoadCount = module->LoadCount; moduleItem->Name = module->Name; PhReferenceObject(moduleItem->Name); moduleItem->FileName = module->FileName; PhReferenceObject(moduleItem->FileName); PhInitializeImageVersionInfo( &moduleItem->VersionInfo, PhGetString(moduleItem->FileName) ); moduleItem->IsFirst = i == 0; if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { PH_REMOTE_MAPPED_IMAGE remoteMappedImage; // Note: // On Windows 7 the LDRP_IMAGE_NOT_AT_BASE flag doesn't appear to be used // anymore. Instead we'll check ImageBase in the image headers. We read this in // from the process' memory because: // // 1. It (should be) faster than opening the file and mapping it in, and // 2. It contains the correct original image base relocated by ASLR, if present. if (NT_SUCCESS(PhLoadRemoteMappedImage(moduleProvider->ProcessHandle, moduleItem->BaseAddress, &remoteMappedImage))) { moduleItem->ImageTimeDateStamp = remoteMappedImage.NtHeaders->FileHeader.TimeDateStamp; moduleItem->ImageCharacteristics = remoteMappedImage.NtHeaders->FileHeader.Characteristics; if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } else if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } PhUnloadRemoteMappedImage(&remoteMappedImage); } } if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_KERNEL_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { // See if the file has already been verified; if not, queue for verification. moduleItem->VerifyResult = PhVerifyFileCached(moduleItem->FileName, &moduleItem->VerifySignerName, TRUE); if (moduleItem->VerifyResult == VrUnknown) PhpQueueModuleQuery(moduleProvider, moduleItem); } // Add the module item to the hashtable. PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhAddEntryHashtable(moduleProvider->ModuleHashtable, &moduleItem); PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); // Raise the module added event. PhInvokeCallback(&moduleProvider->ModuleAddedEvent, moduleItem); } else { BOOLEAN modified = FALSE; if (moduleItem->JustProcessed) modified = TRUE; moduleItem->JustProcessed = FALSE; if (modified) PhInvokeCallback(&moduleProvider->ModuleModifiedEvent, moduleItem); PhDereferenceObject(moduleItem); } } // Free the modules list. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PhDereferenceObject(module->Name); PhDereferenceObject(module->FileName); PhFree(module); } PhDereferenceObject(modules); PhInvokeCallback(&moduleProvider->UpdatedEvent, NULL); }
VOID FindNetworkAdapters( _In_ PDV_NETADAPTER_CONTEXT Context ) { if (Context->UseAlternateMethod) { ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_ALL_INTERFACES; ULONG bufferLength = 0; PVOID buffer; if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &bufferLength) != ERROR_BUFFER_OVERFLOW) return; buffer = PhAllocate(bufferLength); memset(buffer, 0, bufferLength); if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, buffer, &bufferLength) == ERROR_SUCCESS) { PhAcquireQueuedLockShared(&NetworkAdaptersListLock); for (PIP_ADAPTER_ADDRESSES i = buffer; i; i = i->Next) { PPH_STRING description; if (description = PhCreateString(i->Description)) { AddNetworkAdapterToListView( Context, TRUE, i->IfIndex, i->Luid, PhConvertMultiByteToUtf16(i->AdapterName), description ); PhDereferenceObject(description); } } PhReleaseQueuedLockShared(&NetworkAdaptersListLock); } PhFree(buffer); } else { static PH_STRINGREF devicePathSr = PH_STRINGREF_INIT(L"\\\\.\\"); PPH_LIST deviceList; PWSTR deviceInterfaceList; ULONG deviceInterfaceListLength = 0; PWSTR deviceInterface; if (CM_Get_Device_Interface_List_Size( &deviceInterfaceListLength, (PGUID)&GUID_DEVINTERFACE_NET, NULL, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES ) != CR_SUCCESS) { return; } deviceInterfaceList = PhAllocate(deviceInterfaceListLength * sizeof(WCHAR)); memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR)); if (CM_Get_Device_Interface_List( (PGUID)&GUID_DEVINTERFACE_NET, NULL, deviceInterfaceList, deviceInterfaceListLength, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES ) != CR_SUCCESS) { PhFree(deviceInterfaceList); return; } deviceList = PH_AUTO(PhCreateList(1)); for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += PhCountStringZ(deviceInterface) + 1) { HKEY keyHandle; DEVINST deviceInstanceHandle; PPH_STRING deviceDescription = NULL; if (!QueryNetworkDeviceInterfaceDescription(deviceInterface, &deviceInstanceHandle, &deviceDescription)) continue; if (CM_Open_DevInst_Key( deviceInstanceHandle, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &keyHandle, CM_REGISTRY_SOFTWARE ) == CR_SUCCESS) { PNET_ENUM_ENTRY adapterEntry; HANDLE deviceHandle; adapterEntry = PhAllocate(sizeof(NET_ENUM_ENTRY)); memset(adapterEntry, 0, sizeof(NET_ENUM_ENTRY)); adapterEntry->DeviceGuid = PhQueryRegistryString(keyHandle, L"NetCfgInstanceId"); adapterEntry->DeviceInterface = PhConcatStringRef2(&devicePathSr, &adapterEntry->DeviceGuid->sr); adapterEntry->DeviceLuid.Info.IfType = PhQueryRegistryUlong64(keyHandle, L"*IfType"); adapterEntry->DeviceLuid.Info.NetLuidIndex = PhQueryRegistryUlong64(keyHandle, L"NetLuidIndex"); if (NT_SUCCESS(PhCreateFileWin32( &deviceHandle, PhGetString(adapterEntry->DeviceInterface), FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { PPH_STRING adapterName; // Try query the full adapter name adapterName = NetworkAdapterQueryName(deviceHandle, adapterEntry->DeviceGuid); if (adapterName) adapterEntry->DeviceName = adapterName; adapterEntry->DevicePresent = TRUE; NtClose(deviceHandle); } if (!adapterEntry->DeviceName) adapterEntry->DeviceName = PhCreateString2(&deviceDescription->sr); PhAddItemList(deviceList, adapterEntry); NtClose(keyHandle); } PhClearReference(&deviceDescription); } // Cleanup. PhFree(deviceInterfaceList); // Sort the entries qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), AdapterEntryCompareFunction); PhAcquireQueuedLockShared(&NetworkAdaptersListLock); for (ULONG i = 0; i < deviceList->Count; i++) { PNET_ENUM_ENTRY entry = deviceList->Items[i]; AddNetworkAdapterToListView( Context, entry->DevicePresent, 0, entry->DeviceLuid, entry->DeviceGuid, entry->DeviceName ); if (entry->DeviceName) PhDereferenceObject(entry->DeviceName); if (entry->DeviceInterface) PhDereferenceObject(entry->DeviceInterface); // Note: DeviceGuid is disposed by WM_DESTROY. PhFree(entry); } PhReleaseQueuedLockShared(&NetworkAdaptersListLock); } // HACK: Show all unknown devices. PhAcquireQueuedLockShared(&NetworkAdaptersListLock); for (ULONG i = 0; i < NetworkAdaptersList->Count; i++) { ULONG index = ULONG_MAX; BOOLEAN found = FALSE; PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]); if (!entry) continue; while ((index = PhFindListViewItemByFlags( Context->ListViewHandle, index, LVNI_ALL )) != ULONG_MAX) { PDV_NETADAPTER_ID param; if (PhGetListViewItemParam(Context->ListViewHandle, index, ¶m)) { if (EquivalentNetAdapterId(param, &entry->AdapterId)) { found = TRUE; } } } if (!found) { PPH_STRING description; MIB_IF_ROW2 interfaceRow; memset(&interfaceRow, 0, sizeof(MIB_IF_ROW2)); interfaceRow.InterfaceLuid = entry->AdapterId.InterfaceLuid; interfaceRow.InterfaceIndex = entry->AdapterId.InterfaceIndex; // HACK: Try query the description from the interface entry (if it exists). if (GetIfEntry2(&interfaceRow) == NO_ERROR) description = PhCreateString(interfaceRow.Description); else description = PhCreateString(L"Unknown network adapter"); if (description) { AddNetworkAdapterToListView( Context, FALSE, entry->AdapterId.InterfaceIndex, entry->AdapterId.InterfaceLuid, entry->AdapterId.InterfaceGuid, description ); PhDereferenceObject(description); } } PhDereferenceObjectDeferDelete(entry); } PhReleaseQueuedLockShared(&NetworkAdaptersListLock); }
INT_PTR CALLBACK PhpProcessRecordDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { PPROCESS_RECORD_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PPROCESS_RECORD_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } else { context = (PPROCESS_RECORD_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); if (uMsg == WM_DESTROY) { RemoveProp(hwndDlg, PhMakeContextAtom()); } } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_IMAGE_VERSION_INFO versionInfo; BOOLEAN versionInfoInitialized; PPH_STRING processNameString; PPH_PROCESS_ITEM processItem; if (!PH_IS_FAKE_PROCESS_ID(context->Record->ProcessId)) { processNameString = PhaFormatString(L"%s (%u)", context->Record->ProcessName->Buffer, (ULONG)context->Record->ProcessId); } else { processNameString = context->Record->ProcessName; } PhCenterWindow(hwndDlg, GetParent(hwndDlg)); SetWindowText(hwndDlg, processNameString->Buffer); SetDlgItemText(hwndDlg, IDC_PROCESSNAME, processNameString->Buffer); if (processItem = PhReferenceProcessItemForRecord(context->Record)) { PPH_PROCESS_ITEM parentProcess; if (parentProcess = PhReferenceProcessItemForParent( processItem->ParentProcessId, processItem->ProcessId, &processItem->CreateTime )) { CLIENT_ID clientId; clientId.UniqueProcess = parentProcess->ProcessId; clientId.UniqueThread = NULL; SetDlgItemText(hwndDlg, IDC_PARENT, ((PPH_STRING)PHA_DEREFERENCE(PhGetClientIdNameEx(&clientId, parentProcess->ProcessName)))->Buffer); PhDereferenceObject(parentProcess); } else { SetDlgItemText(hwndDlg, IDC_PARENT, PhaFormatString(L"Non-existent process (%u)", (ULONG)context->Record->ParentProcessId)->Buffer); } PhDereferenceObject(processItem); } else { SetDlgItemText(hwndDlg, IDC_PARENT, PhaFormatString(L"Unknown process (%u)", (ULONG)context->Record->ParentProcessId)->Buffer); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), FALSE); } memset(&versionInfo, 0, sizeof(PH_IMAGE_VERSION_INFO)); versionInfoInitialized = FALSE; if (context->Record->FileName) { if (PhInitializeImageVersionInfo(&versionInfo, context->Record->FileName->Buffer)) versionInfoInitialized = TRUE; } context->FileIcon = PhGetFileShellIcon(PhGetString(context->Record->FileName), L".exe", TRUE); SendMessage(GetDlgItem(hwndDlg, IDC_OPENFILENAME), BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)PH_LOAD_SHARED_IMAGE(MAKEINTRESOURCE(IDB_FOLDER), IMAGE_BITMAP)); SendMessage(GetDlgItem(hwndDlg, IDC_FILEICON), STM_SETICON, (WPARAM)context->FileIcon, 0); SetDlgItemText(hwndDlg, IDC_NAME, PhpGetStringOrNa(versionInfo.FileDescription)); SetDlgItemText(hwndDlg, IDC_COMPANYNAME, PhpGetStringOrNa(versionInfo.CompanyName)); SetDlgItemText(hwndDlg, IDC_VERSION, PhpGetStringOrNa(versionInfo.FileVersion)); SetDlgItemText(hwndDlg, IDC_FILENAME, PhpGetStringOrNa(context->Record->FileName)); if (versionInfoInitialized) PhDeleteImageVersionInfo(&versionInfo); if (!context->Record->FileName) EnableWindow(GetDlgItem(hwndDlg, IDC_OPENFILENAME), FALSE); SetDlgItemText(hwndDlg, IDC_CMDLINE, PhpGetStringOrNa(context->Record->CommandLine)); if (context->Record->CreateTime.QuadPart != 0) SetDlgItemText(hwndDlg, IDC_STARTED, PhapGetRelativeTimeString(&context->Record->CreateTime)->Buffer); else SetDlgItemText(hwndDlg, IDC_STARTED, L"N/A"); if (context->Record->ExitTime.QuadPart != 0) SetDlgItemText(hwndDlg, IDC_TERMINATED, PhapGetRelativeTimeString(&context->Record->ExitTime)->Buffer); else SetDlgItemText(hwndDlg, IDC_TERMINATED, L"N/A"); SetDlgItemInt(hwndDlg, IDC_SESSIONID, context->Record->SessionId, FALSE); } break; case WM_DESTROY: { if (context->FileIcon) DestroyIcon(context->FileIcon); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { EndDialog(hwndDlg, IDOK); } break; case IDC_OPENFILENAME: { if (context->Record->FileName) PhShellExploreFile(hwndDlg, context->Record->FileName->Buffer); } break; case IDC_PROPERTIES: { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItemForRecord(context->Record)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process has already terminated; only the process record is available."); } } break; } } break; } return FALSE; }
static VOID DbgProcessLogMessageEntry( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ BOOLEAN GlobalEvents ) { NTSTATUS status; PDBWIN_PAGE_BUFFER debugMessageBuffer; PDEBUG_LOG_ENTRY entry = NULL; HANDLE processHandle = NULL; PPH_STRING fileName = NULL; HICON icon = NULL; debugMessageBuffer = GlobalEvents ? Context->GlobalDebugBuffer : Context->LocalDebugBuffer; entry = PhAllocate(sizeof(DEBUG_LOG_ENTRY)); memset(entry, 0, sizeof(DEBUG_LOG_ENTRY)); PhQuerySystemTime(&entry->Time); entry->ProcessId = UlongToHandle(debugMessageBuffer->ProcessId); entry->Message = PhConvertMultiByteToUtf16(debugMessageBuffer->Buffer); if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID) { status = PhGetProcessImageFileNameByProcessId(entry->ProcessId, &fileName); } else { if (NT_SUCCESS(status = PhOpenProcess(&processHandle, ProcessQueryAccess, entry->ProcessId))) { status = PhGetProcessImageFileName(processHandle, &fileName); NtClose(processHandle); } } if (!NT_SUCCESS(status)) fileName = PhGetKernelFileName(); PhSwapReference2(&fileName, PhGetFileName(fileName)); icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", TRUE); if (icon) { entry->ImageIndex = ImageList_AddIcon(Context->ListViewImageList, icon); DestroyIcon(icon); } entry->FilePath = fileName; entry->ProcessName = PhGetBaseName(fileName); // Drop event if it matches a filter for (ULONG i = 0; i < Context->ExcludeList->Count; i++) { PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i]; if (filterEntry->Type == FilterByName) { if (PhEqualString(filterEntry->ProcessName, entry->ProcessName, TRUE)) { DbgFreeLogEntry(entry); return; } } else if (filterEntry->Type == FilterByPid) { if (filterEntry->ProcessId == entry->ProcessId) { DbgFreeLogEntry(entry); return; } } } DbgAddLogEntry(Context, entry); }