VOID PhInitializeKph( VOID ) { static PH_STRINGREF kprocesshacker = PH_STRINGREF_INIT(L"kprocesshacker.sys"); static PH_STRINGREF processhackerSig = PH_STRINGREF_INIT(L"ProcessHacker.sig"); PPH_STRING kprocesshackerFileName; PPH_STRING processhackerSigFileName; KPH_PARAMETERS parameters; PUCHAR signature; ULONG signatureSize; if (WindowsVersion < WINDOWS_7) return; kprocesshackerFileName = PhConcatStringRef2(&PhApplicationDirectory->sr, &kprocesshacker); processhackerSigFileName = PhConcatStringRef2(&PhApplicationDirectory->sr, &processhackerSig); parameters.SecurityLevel = KphSecurityPrivilegeCheck; parameters.CreateDynamicConfiguration = TRUE; KphConnect2Ex(KPH_DEVICE_SHORT_NAME, kprocesshackerFileName->Buffer, ¶meters); if (signature = PhpReadSignature(processhackerSigFileName->Buffer, &signatureSize)) { KphVerifyClient(signature, signatureSize); PhFree(signature); } PhDereferenceObject(kprocesshackerFileName); PhDereferenceObject(processhackerSigFileName); }
_Check_return_ BOOLEAN RemoveAppCompatEntries( VOID ) { static PH_STRINGREF appCompatLayersName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"); static PH_STRINGREF appCompatPersistedName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Compatibility Assistant\\Persisted"); HANDLE keyHandle; if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_ALL_ACCESS | KEY_WOW64_64KEY, PH_KEY_CURRENT_USER, &appCompatLayersName, 0 ))) { RemoveAppCompatEntry(keyHandle); NtClose(keyHandle); } if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_ALL_ACCESS | KEY_WOW64_64KEY, PH_KEY_CURRENT_USER, &appCompatPersistedName, 0 ))) { RemoveAppCompatEntry(keyHandle); NtClose(keyHandle); } if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_ALL_ACCESS | KEY_WOW64_64KEY, PH_KEY_LOCAL_MACHINE, &appCompatLayersName, 0 ))) { RemoveAppCompatEntry(keyHandle); NtClose(keyHandle); } if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_ALL_ACCESS | KEY_WOW64_64KEY, PH_KEY_LOCAL_MACHINE, &appCompatPersistedName, 0 ))) { RemoveAppCompatEntry(keyHandle); NtClose(keyHandle); } return TRUE; }
BOOLEAN NTAPI DotNetVersionsEnumModulesCallback( __in PPH_MODULE_INFO Module, __in_opt PVOID Context ) { if ( PhEqualString2(Module->Name, L"clr.dll", TRUE) || PhEqualString2(Module->Name, L"mscorwks.dll", TRUE) || PhEqualString2(Module->Name, L"mscorsvr.dll", TRUE) ) { static PH_STRINGREF frameworkString = PH_STRINGREF_INIT(L"Microsoft.NET\\Framework\\"); static PH_STRINGREF framework64String = PH_STRINGREF_INIT(L"Microsoft.NET\\Framework64\\"); PPH_STRINGREF splitAt; PH_STRINGREF firstPart; PH_STRINGREF secondPart; #ifdef _M_X64 if (*(PULONG)Context & CLR_PROCESS_IS_WOW64) { #endif splitAt = &frameworkString; #ifdef _M_X64 } else { splitAt = &framework64String; } #endif if (PhSplitStringRefAtString(&Module->FileName->sr, splitAt, TRUE, &firstPart, &secondPart)) { if (secondPart.Length >= 4 * sizeof(WCHAR)) // vx.x { if (secondPart.Buffer[1] == '1') { if (secondPart.Buffer[3] == '0') *(PULONG)Context |= CLR_VERSION_1_0; else if (secondPart.Buffer[3] == '1') *(PULONG)Context |= CLR_VERSION_1_1; } else if (secondPart.Buffer[1] == '2') { *(PULONG)Context |= CLR_VERSION_2_0; } else if (secondPart.Buffer[1] >= '4' && secondPart.Buffer[1] <= '9') { *(PULONG)Context |= CLR_VERSION_4_ABOVE; } } } } return TRUE; }
NTSTATUS PhGetServiceDllParameter( _In_ PPH_STRINGREF ServiceName, _Out_ PPH_STRING *ServiceDll ) { static PH_STRINGREF servicesKeyName = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Services\\"); static PH_STRINGREF parameters = PH_STRINGREF_INIT(L"\\Parameters"); NTSTATUS status; HANDLE keyHandle; PPH_STRING keyName; keyName = PhConcatStringRef3(&servicesKeyName, ServiceName, ¶meters); if (NT_SUCCESS(status = 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)) { *ServiceDll = expandedString; PhDereferenceObject(serviceDllString); } else { *ServiceDll = serviceDllString; } } else { status = STATUS_NOT_FOUND; } NtClose(keyHandle); } PhDereferenceObject(keyName); return status; }
_Check_return_ BOOLEAN IsProcessHackerInstalled(VOID) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Process_Hacker2_is1"); BOOLEAN keySuccess = FALSE; HANDLE keyHandle; PPH_STRING installPath = NULL; if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ | KEY_WOW64_64KEY, // 64bit key PH_KEY_LOCAL_MACHINE, &keyName, 0 ))) { installPath = PhQueryRegistryString(keyHandle, L"InstallLocation"); NtClose(keyHandle); } if (!PhEndsWithString2(installPath, L"ProcessHacker.exe", TRUE)) { } // Check if KeyData value maps to valid file path. if (GetFileAttributes(installPath->Buffer) == INVALID_FILE_ATTRIBUTES) { } keySuccess = TRUE; return keySuccess; }
BOOLEAN UpdaterCheckKphInstallState( VOID ) { static PH_STRINGREF kph3ServiceKeyName = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Services\\KProcessHacker3"); BOOLEAN kphInstallRequired = FALSE; HANDLE runKeyHandle; if (NT_SUCCESS(PhOpenKey( &runKeyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &kph3ServiceKeyName, 0 ))) { // Make sure we re-install the driver when KPH was installed as a service. if (PhQueryRegistryUlong(runKeyHandle, L"Start") == SERVICE_SYSTEM_START) { kphInstallRequired = TRUE; } NtClose(runKeyHandle); } return kphInstallRequired; }
PPH_STRING UpdateWindowsString( VOID ) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows NT\\CurrentVersion"); HANDLE keyHandle; PPH_STRING buildLabHeader = NULL; if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName, 0 ))) { PPH_STRING buildLabString; if (buildLabString = PhQueryRegistryString(keyHandle, L"BuildLabEx")) { buildLabHeader = PhConcatStrings2(L"ProcessHacker-OsBuild: ", buildLabString->Buffer); PhDereferenceObject(buildLabString); } else if (buildLabString = PhQueryRegistryString(keyHandle, L"BuildLab")) { buildLabHeader = PhConcatStrings2(L"ProcessHacker-OsBuild: ", buildLabString->Buffer); PhDereferenceObject(buildLabString); } NtClose(keyHandle); } return buildLabHeader; }
PPH_STRING TrimString( _In_ PPH_STRING String ) { static PH_STRINGREF whitespace = PH_STRINGREF_INIT(L" \t\r\n"); PH_STRINGREF sr = String->sr; PhTrimStringRef(&sr, &whitespace, 0); return PhCreateString2(&sr); }
BOOLEAN UpdaterInstalledUsingSetup( VOID ) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ProcessHacker"); static PH_STRINGREF key2xName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Process_Hacker2_is1"); HANDLE keyHandle = NULL; // Check uninstall entries for the 'ProcessHacker' registry key. if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName, 0 ))) { NtClose(keyHandle); return TRUE; } // Check uninstall entries for the 2.x branch 'Process_Hacker2_is1' registry key. if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &key2xName, 0 ))) { NtClose(keyHandle); return TRUE; } return FALSE; }
VOID PhInitializeKph( VOID ) { static PH_STRINGREF kprocesshacker = PH_STRINGREF_INIT(L"kprocesshacker.sys"); PPH_STRING kprocesshackerFileName; KPH_PARAMETERS parameters; // Append kprocesshacker.sys to the application directory. kprocesshackerFileName = PhConcatStringRef2(&PhApplicationDirectory->sr, &kprocesshacker); parameters.SecurityLevel = KphSecurityPrivilegeCheck; parameters.CreateDynamicConfiguration = TRUE; KphConnect2Ex(L"KProcessHacker2", kprocesshackerFileName->Buffer, ¶meters); PhDereferenceObject(kprocesshackerFileName); }
VOID PhPluginsInitialization( VOID ) { ULONG i; for (i = 0; i < GeneralCallbackMaximum; i++) PhInitializeCallback(&GeneralCallbacks[i]); if (WindowsVersion <= WINDOWS_XP) { PH_STRINGREF extendedTools = PH_STRINGREF_INIT(L"ExtendedTools.dll"); // HACK and violation of abstraction. // Always disable ExtendedTools on XP to avoid the annoying error message. PhSetPluginDisabled(&extendedTools, TRUE); } }
_Maybenull_ PPH_STRING GetProcessHackerInstallPath( VOID ) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Process_Hacker2_is1"); HANDLE keyHandle; PPH_STRING installPath = NULL; if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ | KEY_WOW64_64KEY, PH_KEY_LOCAL_MACHINE, &keyName, 0 ))) { installPath = PhQueryRegistryString(keyHandle, L"InstallLocation"); NtClose(keyHandle); } return installPath; }
VOID NTAPI TreeNewMessageCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; switch (message->Message) { case TreeNewGetCellText: { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; switch (message->SubId) { case COLUMN_ID_VIUSTOTAL_PROCESS: { PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, processNode->ProcessItem, EmProcessItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; case COLUMN_ID_VIUSTOTAL_MODULE: { PPH_MODULE_NODE moduleNode = (PPH_MODULE_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, moduleNode->ModuleItem, EmModuleItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; case COLUMN_ID_VIUSTOTAL_SERVICE: { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)getCellText->Node; PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, serviceNode->ServiceItem, EmServiceItemType); getCellText->Text = PhGetStringRef(extension->VirusTotalResult); } break; } } break; case TreeNewCustomDraw: { PPH_TREENEW_CUSTOM_DRAW customDraw = message->Parameter1; PPROCESS_EXTENSION extension = NULL; PH_STRINGREF text; if (!VirusTotalScanningEnabled) { static PH_STRINGREF disabledText = PH_STRINGREF_INIT(L"Scanning disabled"); DrawText( customDraw->Dc, disabledText.Buffer, (ULONG)disabledText.Length / 2, &customDraw->CellRect, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE ); return; } switch (message->SubId) { case COLUMN_ID_VIUSTOTAL_PROCESS: { PPH_PROCESS_NODE processNode = (PPH_PROCESS_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, processNode->ProcessItem, EmProcessItemType); } break; case COLUMN_ID_VIUSTOTAL_MODULE: { PPH_MODULE_NODE moduleNode = (PPH_MODULE_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, moduleNode->ModuleItem, EmModuleItemType); } break; case COLUMN_ID_VIUSTOTAL_SERVICE: { PPH_SERVICE_NODE serviceNode = (PPH_SERVICE_NODE)customDraw->Node; extension = PhPluginGetObjectExtension(PluginInstance, serviceNode->ServiceItem, EmServiceItemType); } break; } if (!extension) break; //if (extension->Positives > 0) // SetTextColor(customDraw->Dc, RGB(0xff, 0x0, 0x0)); text = PhGetStringRef(extension->VirusTotalResult); DrawText( customDraw->Dc, text.Buffer, (ULONG)text.Length / sizeof(WCHAR), &customDraw->CellRect, DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE ); } break; } }
INT_PTR CALLBACK PhpOptionsGraphsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ); // All static BOOLEAN PageInit; static BOOLEAN PressedOk; static BOOLEAN RestartRequired; static POINT StartLocation; static WNDPROC OldWndProc; // General static PH_STRINGREF CurrentUserRunKeyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"); static BOOLEAN CurrentUserRunPresent; static BOOLEAN CurrentUserRunStartHidden; static HFONT CurrentFontInstance; static PPH_STRING NewFontSelection; // Advanced static PH_STRINGREF TaskMgrImageOptionsKeyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\taskmgr.exe"); static PPH_STRING OldTaskMgrDebugger; static BOOLEAN OldReplaceTaskMgr; static HWND WindowHandleForElevate; // Highlighting static HWND HighlightingListViewHandle; VOID PhShowOptionsDialog(
BOOLEAN DiskDriveQueryDeviceInformation( _In_ HANDLE DeviceHandle, _Out_opt_ PPH_STRING* DiskVendor, _Out_opt_ PPH_STRING* DiskModel, _Out_opt_ PPH_STRING* DiskRevision, _Out_opt_ PPH_STRING* DiskSerial ) { static PH_STRINGREF whitespace = PH_STRINGREF_INIT(L" "); ULONG bufferLength; IO_STATUS_BLOCK isb; STORAGE_PROPERTY_QUERY query; PSTORAGE_DESCRIPTOR_HEADER buffer = NULL; query.QueryType = PropertyStandardQuery; query.PropertyId = StorageDeviceProperty; bufferLength = sizeof(STORAGE_DESCRIPTOR_HEADER); buffer = PhAllocate(bufferLength); memset(buffer, 0, bufferLength); if (!NT_SUCCESS(NtDeviceIoControlFile( DeviceHandle, NULL, NULL, NULL, &isb, IOCTL_STORAGE_QUERY_PROPERTY, // https://msdn.microsoft.com/en-us/library/ff800830.aspx &query, sizeof(query), buffer, bufferLength ))) { PhFree(buffer); return FALSE; } bufferLength = buffer->Size; buffer = PhReAllocate(buffer, bufferLength); memset(buffer, 0, bufferLength); if (!NT_SUCCESS(NtDeviceIoControlFile( DeviceHandle, NULL, NULL, NULL, &isb, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), buffer, bufferLength ))) { PhFree(buffer); return FALSE; } PSTORAGE_DEVICE_DESCRIPTOR storageDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)buffer; if (DiskVendor && storageDescriptor->VendorIdOffset != 0) { PPH_STRING diskVendor; diskVendor = PhConvertMultiByteToUtf16((PBYTE)storageDescriptor + storageDescriptor->VendorIdOffset); PhTrimStringRef(&diskVendor->sr, &whitespace, 0); *DiskVendor = diskVendor; } if (DiskModel && storageDescriptor->ProductIdOffset != 0) { PPH_STRING diskModel; diskModel = PhConvertMultiByteToUtf16((PBYTE)storageDescriptor + storageDescriptor->ProductIdOffset); PhTrimStringRef(&diskModel->sr, &whitespace, 0); *DiskModel = diskModel; } if (DiskRevision && storageDescriptor->ProductRevisionOffset != 0) { PPH_STRING diskRevision; diskRevision = PhConvertMultiByteToUtf16((PBYTE)storageDescriptor + storageDescriptor->ProductRevisionOffset); PhTrimStringRef(&diskRevision->sr, &whitespace, 0); *DiskRevision = diskRevision; } if (DiskSerial && storageDescriptor->SerialNumberOffset != 0) { PPH_STRING diskSerial; diskSerial = PhConvertMultiByteToUtf16((PBYTE)storageDescriptor + storageDescriptor->SerialNumberOffset); PhTrimStringRef(&diskSerial->sr, &whitespace, 0); *DiskSerial = diskSerial; } if (buffer) { PhFree(buffer); } return TRUE; }
VOID PeInitializeSettings( VOID ) { static PH_STRINGREF settingsSuffix = PH_STRINGREF_INIT(L".peview.xml"); NTSTATUS status; PPH_STRING appFileName; PPH_STRING tempFileName; // There are three possible locations for the settings file: // 1. A file named peview.exe.peview.xml in the program directory. (This changes // based on the executable file name.) // 2. The default location. // 1. File in program directory appFileName = PhGetApplicationFileName(); tempFileName = PhConcatStringRef2(&appFileName->sr, &settingsSuffix); PhDereferenceObject(appFileName); if (RtlDoesFileExists_U(tempFileName->Buffer)) { PeSettingsFileName = tempFileName; } else { PhDereferenceObject(tempFileName); } // 2. Default location if (!PeSettingsFileName) { PeSettingsFileName = PhGetKnownLocation(CSIDL_APPDATA, L"\\Process Hacker\\peview.xml"); } if (PeSettingsFileName) { status = PhLoadSettings(PeSettingsFileName->Buffer); // If we didn't find the file, it will be created. Otherwise, // there was probably a parsing error and we don't want to // change anything. if (status == STATUS_FILE_CORRUPT_ERROR) { if (PhShowMessage2( NULL, TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, TD_WARNING_ICON, L"PE View's settings file is corrupt. Do you want to reset it?", L"If you select No, the settings system will not function properly." ) == IDYES) { HANDLE fileHandle; IO_STATUS_BLOCK isb; CHAR data[] = "<settings></settings>"; // This used to delete the file. But it's better to keep the file there // and overwrite it with some valid XML, especially with case (2) above. if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, PeSettingsFileName->Buffer, FILE_GENERIC_WRITE, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OVERWRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { NtWriteFile(fileHandle, NULL, NULL, NULL, &isb, data, sizeof(data) - 1, NULL, NULL); NtClose(fileHandle); } } else { // Pretend we don't have a settings store so bad things don't happen. PhDereferenceObject(PeSettingsFileName); PeSettingsFileName = NULL; } } } // Apply basic global settings. PhMaxSizeUnit = PhGetIntegerSetting(L"MaxSizeUnit"); }
#include <verify.h> #define CINTERFACE #define COBJMACROS #include <taskschd.h> VOID PhpFillUmdfDrivers( _In_ PPH_PROCESS_ITEM Process, _Inout_ PPH_STRING_BUILDER Drivers ); VOID PhpFillRunningTasks( _In_ PPH_PROCESS_ITEM Process, _Inout_ PPH_STRING_BUILDER Tasks ); static PH_STRINGREF StandardIndent = PH_STRINGREF_INIT(L" "); VOID PhpAppendStringWithLineBreaks( _Inout_ PPH_STRING_BUILDER StringBuilder, _In_ PPH_STRINGREF String, _In_ ULONG CharactersPerLine, _In_opt_ PPH_STRINGREF IndentAfterFirstLine ) { PH_STRINGREF line; SIZE_T bytesPerLine; BOOLEAN afterFirstLine; SIZE_T bytesToAppend; line = *String; bytesPerLine = CharactersPerLine * sizeof(WCHAR);
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>. */ #include <phapp.h> #include <cpysave.h> #include <emenu.h> #include <secedit.h> #include <procprv.h> #include <thrdprv.h> #include <thrdlist.h> #include <actions.h> #include <phplug.h> #include <extmgri.h> #include <procprpp.h> static PH_STRINGREF EmptyThreadsText = PH_STRINGREF_INIT(L"There are no threads to display."); static VOID NTAPI ThreadAddedHandler( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_THREADS_CONTEXT threadsContext = (PPH_THREADS_CONTEXT)Context; // Parameter contains a pointer to the added thread item. PhReferenceObject(Parameter); PhPushProviderEventQueue(&threadsContext->EventQueue, ProviderAddedEvent, Parameter, (ULONG)threadsContext->Provider->RunId); } static VOID NTAPI ThreadModifiedHandler( _In_opt_ PVOID Parameter,
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>. */ #include <phapp.h> #include <cpysave.h> #include <emenu.h> #include <procprv.h> #include <memprv.h> #include <memlist.h> #include <actions.h> #include <phplug.h> #include <extmgri.h> #include <windowsx.h> #include <procprpp.h> static PH_STRINGREF EmptyMemoryText = PH_STRINGREF_INIT(L"There are no memory regions to display."); VOID PhpRefreshProcessMemoryList( _In_ HWND hwndDlg, _In_ PPH_PROCESS_PROPPAGECONTEXT PropPageContext ) { PPH_MEMORY_CONTEXT memoryContext = PropPageContext->Context; if (memoryContext->MemoryItemListValid) { PhDeleteMemoryItemList(&memoryContext->MemoryItemList); memoryContext->MemoryItemListValid = FALSE; } memoryContext->LastRunStatus = PhQueryMemoryItemList(
#define SMALL_BUFFER_LENGTH (PH_OBJECT_SMALL_OBJECT_SIZE - FIELD_OFFSET(PH_STRING, Data) - sizeof(WCHAR)) #define BUFFER_SIZE 512 #define PHP_FORMAT_NEGATIVE 0x1 #define PHP_FORMAT_POSITIVE 0x2 #define PHP_FORMAT_PAD 0x4 // Internal CRT routine needed for floating-point conversion errno_t __cdecl _cfltcvt_l(double *arg, char *buffer, size_t sizeInBytes, int format, int precision, int caps, _locale_t plocinfo); // Keep in sync with PhSizeUnitNames static PH_STRINGREF PhpSizeUnitNamesCounted[7] = { PH_STRINGREF_INIT(L"B"), PH_STRINGREF_INIT(L"kB"), PH_STRINGREF_INIT(L"MB"), PH_STRINGREF_INIT(L"GB"), PH_STRINGREF_INIT(L"TB"), PH_STRINGREF_INIT(L"PB"), PH_STRINGREF_INIT(L"EB") }; static PH_INITONCE PhpFormatInitOnce = PH_INITONCE_INIT; static WCHAR PhpFormatDecimalSeparator = '.'; static WCHAR PhpFormatThousandSeparator = ','; static _locale_t PhpFormatUserLocale = NULL; #if (_MSC_VER >= 1900)
VOID PhpFillUmdfDrivers( _In_ PPH_PROCESS_ITEM Process, _Inout_ PPH_STRING_BUILDER Drivers ) { static PH_STRINGREF activeDevices = PH_STRINGREF_INIT(L"ACTIVE_DEVICES"); static PH_STRINGREF currentControlSetEnum = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Enum\\"); HANDLE processHandle; ULONG flags = 0; PVOID environment; ULONG environmentLength; ULONG enumerationKey; PH_ENVIRONMENT_VARIABLE variable; if (!NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, Process->ProcessId ))) return; #ifdef _WIN64 // Just in case. if (Process->IsWow64) flags |= PH_GET_PROCESS_ENVIRONMENT_WOW64; #endif if (NT_SUCCESS(PhGetProcessEnvironment( processHandle, flags, &environment, &environmentLength ))) { enumerationKey = 0; while (PhEnumProcessEnvironmentVariables(environment, environmentLength, &enumerationKey, &variable)) { PH_STRINGREF part; PH_STRINGREF remainingPart; if (!PhEqualStringRef(&variable.Name, &activeDevices, TRUE)) continue; remainingPart = variable.Value; while (remainingPart.Length != 0) { PhSplitStringRefAtChar(&remainingPart, ';', &part, &remainingPart); if (part.Length != 0) { HANDLE driverKeyHandle; PPH_STRING driverKeyPath; driverKeyPath = PhConcatStringRef2(¤tControlSetEnum, &part); if (NT_SUCCESS(PhOpenKey( &driverKeyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &driverKeyPath->sr, 0 ))) { PPH_STRING deviceDesc; PH_STRINGREF deviceName; PPH_STRING hardwareId; if (deviceDesc = PhQueryRegistryString(driverKeyHandle, L"DeviceDesc")) { PH_STRINGREF firstPart; PH_STRINGREF secondPart; if (PhSplitStringRefAtLastChar(&deviceDesc->sr, ';', &firstPart, &secondPart)) deviceName = secondPart; else deviceName = deviceDesc->sr; } else { PhInitializeStringRef(&deviceName, L"Unknown Device"); } hardwareId = PhQueryRegistryString(driverKeyHandle, L"HardwareID"); PhAppendStringBuilder(Drivers, &StandardIndent); PhAppendStringBuilder(Drivers, &deviceName); if (hardwareId) { PhTrimToNullTerminatorString(hardwareId); if (hardwareId->Length != 0) { PhAppendStringBuilder2(Drivers, L" ("); PhAppendStringBuilder(Drivers, &hardwareId->sr); PhAppendCharStringBuilder(Drivers, ')'); } } PhAppendCharStringBuilder(Drivers, '\n'); PhClearReference(&hardwareId); PhClearReference(&deviceDesc); NtClose(driverKeyHandle); } PhDereferenceObject(driverKeyPath); } } } PhFreePage(environment); } NtClose(processHandle); }
// NOTE: This function does not use the SCM due to major performance issues. // For now just query this information from the registry but it might be out-of-sync // with any recent services changes until the SCM flushes its cache. NTSTATUS QueryServiceFileName( _In_ PPH_STRINGREF ServiceName, _Out_ PPH_STRING *ServiceFileName, _Out_ PPH_STRING *ServiceBinaryPath ) { static PH_STRINGREF servicesKeyName = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Services\\"); static PH_STRINGREF typeKeyName = PH_STRINGREF_INIT(L"Type"); NTSTATUS status; HANDLE keyHandle; ULONG serviceType = 0; PPH_STRING keyName; PPH_STRING binaryPath; PPH_STRING fileName; keyName = PhConcatStringRef2(&servicesKeyName, ServiceName); binaryPath = NULL; fileName = NULL; if (NT_SUCCESS(status = PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName->sr, 0 ))) { PPH_STRING serviceImagePath; PKEY_VALUE_PARTIAL_INFORMATION buffer; if (NT_SUCCESS(status = PhQueryValueKey( keyHandle, &typeKeyName, KeyValuePartialInformation, &buffer ))) { if ( buffer->Type == REG_DWORD && buffer->DataLength == sizeof(ULONG) ) { serviceType = *(PULONG)buffer->Data; } PhFree(buffer); } if (serviceImagePath = PhQueryRegistryString(keyHandle, L"ImagePath")) { PPH_STRING expandedString; if (expandedString = PhExpandEnvironmentStrings(&serviceImagePath->sr)) { binaryPath = expandedString; PhDereferenceObject(serviceImagePath); } else { binaryPath = serviceImagePath; } } else { status = STATUS_NOT_FOUND; } NtClose(keyHandle); } if (NT_SUCCESS(status)) { PhGetServiceDllParameter(ServiceName, &fileName); if (!fileName) { if (serviceType & SERVICE_WIN32) { PH_STRINGREF dummyFileName; PH_STRINGREF dummyArguments; PhParseCommandLineFuzzy(&binaryPath->sr, &dummyFileName, &dummyArguments, &fileName); if (!fileName) PhSwapReference(&fileName, binaryPath); } else { fileName = PhGetFileName(binaryPath); } } *ServiceFileName = fileName; *ServiceBinaryPath = binaryPath; } else { if (binaryPath) PhDereferenceObject(binaryPath); } PhDereferenceObject(keyName); return status; }
*/ #include <phapp.h> #include <procprp.h> #include <procprpp.h> #include <kphuser.h> #include <settings.h> #include <phplug.h> #include <phsettings.h> #include <procprv.h> PPH_OBJECT_TYPE PhpProcessPropContextType = NULL; PPH_OBJECT_TYPE PhpProcessPropPageContextType = NULL; PH_STRINGREF PhpLoadingText = PH_STRINGREF_INIT(L"Loading..."); static RECT MinimumSize = { -1, -1, -1, -1 }; PPH_PROCESS_PROPCONTEXT PhCreateProcessPropContext( _In_ HWND ParentWindowHandle, _In_ PPH_PROCESS_ITEM ProcessItem ) { static PH_INITONCE initOnce = PH_INITONCE_INIT; PPH_PROCESS_PROPCONTEXT propContext; PROPSHEETHEADER propSheetHeader; if (PhBeginInitOnce(&initOnce)) { PhpProcessPropContextType = PhCreateObjectType(L"ProcessPropContext", 0, PhpProcessPropContextDeleteProcedure); PhpProcessPropPageContextType = PhCreateObjectType(L"ProcessPropPageContext", 0, PhpProcessPropPageContextDeleteProcedure);
VOID PhShellExecuteUserString( __in HWND hWnd, __in PWSTR Setting, __in PWSTR String, __in BOOLEAN UseShellExecute, __in_opt PWSTR ErrorMessage ) { static PH_STRINGREF replacementToken = PH_STRINGREF_INIT(L"%s"); PPH_STRING executeString; PH_STRINGREF stringBefore; PH_STRINGREF stringMiddle; PH_STRINGREF stringAfter; PPH_STRING newString; PPH_STRING ntMessage; executeString = PhGetStringSetting(Setting); // Make sure the user executable string is absolute. // We can't use RtlDetermineDosPathNameType_U here because the string // may be a URL. if (PhFindCharInString(executeString, 0, ':') == -1) { newString = PhConcatStringRef2(&PhApplicationDirectory->sr, &executeString->sr); PhDereferenceObject(executeString); executeString = newString; } // Replace "%s" with the string, or use the original string if "%s" is not present. if (PhSplitStringRefAtString(&executeString->sr, &replacementToken, FALSE, &stringBefore, &stringAfter)) { PhInitializeStringRef(&stringMiddle, String); newString = PhConcatStringRef3(&stringBefore, &stringMiddle, &stringAfter); } else { newString = executeString; PhReferenceObject(newString); } PhDereferenceObject(executeString); if (UseShellExecute) { PhShellExecute(hWnd, newString->Buffer, NULL); } else { NTSTATUS status; status = PhCreateProcessWin32(NULL, newString->Buffer, NULL, NULL, 0, NULL, NULL, NULL); if (!NT_SUCCESS(status)) { if (ErrorMessage) { ntMessage = PhGetNtMessage(status); PhShowError(hWnd, L"Unable to execute the command: %s\n%s", PhGetStringOrDefault(ntMessage, L"An unknown error occurred."), ErrorMessage); PhDereferenceObject(ntMessage); } else { PhShowStatus(hWnd, L"Unable to execute the command", status, 0); } } } PhDereferenceObject(newString); }
BOOLEAN PhaGetProcessKnownCommandLine( __in PPH_STRING CommandLine, __in PH_KNOWN_PROCESS_TYPE KnownProcessType, __out PPH_KNOWN_PROCESS_COMMAND_LINE KnownCommandLine ) { switch (KnownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: { // svchost.exe -k <GroupName> static PH_COMMAND_LINE_OPTION options[] = { { 1, L"k", MandatoryArgumentType } }; KnownCommandLine->ServiceHost.GroupName = NULL; PhParseCommandLine( &CommandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpSvchostCommandLineCallback, KnownCommandLine ); if (KnownCommandLine->ServiceHost.GroupName) { PhaDereferenceObject(KnownCommandLine->ServiceHost.GroupName); return TRUE; } else { return FALSE; } } break; case RunDllAsAppProcessType: { // rundll32.exe <DllName>,<ProcedureName> ... SIZE_T i; ULONG_PTR lastIndexOfComma; PPH_STRING dllName; PPH_STRING procedureName; i = 0; // Get the rundll32.exe part. dllName = PhParseCommandLinePart(&CommandLine->sr, &i); if (!dllName) return FALSE; PhDereferenceObject(dllName); // Get the DLL name part. while (i < CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ') i++; dllName = PhParseCommandLinePart(&CommandLine->sr, &i); if (!dllName) return FALSE; PhaDereferenceObject(dllName); // The procedure name begins after the last comma. lastIndexOfComma = PhFindLastCharInString(dllName, 0, ','); if (lastIndexOfComma == -1) return FALSE; procedureName = PhaSubstring( dllName, lastIndexOfComma + 1, dllName->Length / 2 - lastIndexOfComma - 1 ); dllName = PhaSubstring(dllName, 0, lastIndexOfComma); // If the DLL name isn't an absolute path, assume it's in system32. // TODO: Use a proper search function. if (RtlDetermineDosPathNameType_U(dllName->Buffer) == RtlPathTypeRelative) { dllName = PhaConcatStrings( 3, ((PPH_STRING)PHA_DEREFERENCE(PhGetSystemDirectory()))->Buffer, L"\\", dllName->Buffer ); } KnownCommandLine->RunDllAsApp.FileName = dllName; KnownCommandLine->RunDllAsApp.ProcedureName = procedureName; } break; case ComSurrogateProcessType: { // dllhost.exe /processid:<Guid> static PH_STRINGREF inprocServer32Name = PH_STRINGREF_INIT(L"InprocServer32"); SIZE_T i; ULONG_PTR indexOfProcessId; PPH_STRING argPart; PPH_STRING guidString; UNICODE_STRING guidStringUs; GUID guid; HANDLE clsidKeyHandle; HANDLE inprocServer32KeyHandle; PPH_STRING fileName; i = 0; // Get the dllhost.exe part. argPart = PhParseCommandLinePart(&CommandLine->sr, &i); if (!argPart) return FALSE; PhDereferenceObject(argPart); // Get the argument part. while (i < (ULONG)CommandLine->Length / 2 && CommandLine->Buffer[i] == ' ') i++; argPart = PhParseCommandLinePart(&CommandLine->sr, &i); if (!argPart) return FALSE; PhaDereferenceObject(argPart); // Find "/processid:"; the GUID is just after that. PhUpperString(argPart); indexOfProcessId = PhFindStringInString(argPart, 0, L"/PROCESSID:"); if (indexOfProcessId == -1) return FALSE; guidString = PhaSubstring( argPart, indexOfProcessId + 11, (ULONG)argPart->Length / 2 - indexOfProcessId - 11 ); PhStringRefToUnicodeString(&guidString->sr, &guidStringUs); if (!NT_SUCCESS(RtlGUIDFromString( &guidStringUs, &guid ))) return FALSE; KnownCommandLine->ComSurrogate.Guid = guid; KnownCommandLine->ComSurrogate.Name = NULL; KnownCommandLine->ComSurrogate.FileName = NULL; // Lookup the GUID in the registry to determine the name and file name. if (NT_SUCCESS(PhOpenKey( &clsidKeyHandle, KEY_READ, PH_KEY_CLASSES_ROOT, &PhaConcatStrings2(L"CLSID\\", guidString->Buffer)->sr, 0 ))) { KnownCommandLine->ComSurrogate.Name = PHA_DEREFERENCE(PhQueryRegistryString(clsidKeyHandle, NULL)); if (NT_SUCCESS(PhOpenKey( &inprocServer32KeyHandle, KEY_READ, clsidKeyHandle, &inprocServer32Name, 0 ))) { KnownCommandLine->ComSurrogate.FileName = PHA_DEREFERENCE(PhQueryRegistryString(inprocServer32KeyHandle, NULL)); if (fileName = PHA_DEREFERENCE(PhExpandEnvironmentStrings( &KnownCommandLine->ComSurrogate.FileName->sr ))) { KnownCommandLine->ComSurrogate.FileName = fileName; } NtClose(inprocServer32KeyHandle); } NtClose(clsidKeyHandle); } } break; default: return FALSE; } return TRUE; }
SID PhSeBatchSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_BATCH_RID } }; SID PhSeInteractiveSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_INTERACTIVE_RID } }; SID PhSeServiceSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_SERVICE_RID } }; SID PhSeAnonymousLogonSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_ANONYMOUS_LOGON_RID } }; SID PhSeProxySid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_PROXY_RID } }; SID PhSeAuthenticatedUserSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_AUTHENTICATED_USER_RID } }; SID PhSeRestrictedCodeSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_RESTRICTED_CODE_RID } }; SID PhSeTerminalServerUserSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_TERMINAL_SERVER_RID } }; SID PhSeRemoteInteractiveLogonSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_REMOTE_LOGON_RID } }; SID PhSeLocalSystemSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SYSTEM_RID } }; SID PhSeLocalServiceSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_LOCAL_SERVICE_RID } }; SID PhSeNetworkServiceSid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_NETWORK_SERVICE_RID } }; // Unicode PH_STRINGREF PhUnicodeByteOrderMark = PH_STRINGREF_INIT(L"\ufeff"); // Characters DECLSPEC_SELECTANY BOOLEAN PhCharIsPrintable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 - 15 */ // TAB, LF and CR are printable 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ' ' - '/' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* '0' - '9' */ 1, 1, 1, 1, 1, 1, 1, /* ':' - '@' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 'A' - 'Z' */ 1, 1, 1, 1, 1, 1, /* '[' - '`' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 'a' - 'z' */ 1, 1, 1, 1, 0, /* '{' - 127 */ // DEL is not printable
VOID PhpInitializeSettings( VOID ) { NTSTATUS status; if (!PhStartupParameters.NoSettings) { static PH_STRINGREF settingsSuffix = PH_STRINGREF_INIT(L".settings.xml"); PPH_STRING settingsFileName; // There are three possible locations for the settings file: // 1. The file name given in the command line. // 2. A file named ProcessHacker.exe.settings.xml in the program directory. (This changes // based on the executable file name.) // 3. The default location. // 1. File specified in command line if (PhStartupParameters.SettingsFileName) { // Get an absolute path now. PhSettingsFileName = PhGetFullPath(PhStartupParameters.SettingsFileName->Buffer, NULL); } // 2. File in program directory if (!PhSettingsFileName) { settingsFileName = PhConcatStringRef2(&PhApplicationFileName->sr, &settingsSuffix); if (RtlDoesFileExists_U(settingsFileName->Buffer)) { PhSettingsFileName = settingsFileName; } else { PhDereferenceObject(settingsFileName); } } // 3. Default location if (!PhSettingsFileName) { PhSettingsFileName = PhGetKnownLocation(CSIDL_APPDATA, L"\\Process Hacker 2\\settings.xml"); } if (PhSettingsFileName) { status = PhLoadSettings(PhSettingsFileName->Buffer); // If we didn't find the file, it will be created. Otherwise, // there was probably a parsing error and we don't want to // change anything. if (status == STATUS_FILE_CORRUPT_ERROR) { if (PhShowMessage( NULL, MB_ICONWARNING | MB_YESNO, L"Process Hacker's settings file is corrupt. Do you want to reset it?\n" L"If you select No, the settings system will not function properly." ) == IDYES) { HANDLE fileHandle; IO_STATUS_BLOCK isb; CHAR data[] = "<settings></settings>"; // This used to delete the file. But it's better to keep the file there // and overwrite it with some valid XML, especially with case (2) above. if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, PhSettingsFileName->Buffer, FILE_GENERIC_WRITE, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OVERWRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { NtWriteFile(fileHandle, NULL, NULL, NULL, &isb, data, sizeof(data) - 1, NULL, NULL); NtClose(fileHandle); } } else { // Pretend we don't have a settings store so bad things // don't happen. PhDereferenceObject(PhSettingsFileName); PhSettingsFileName = NULL; } } } } // Apply basic global settings. PhMaxSizeUnit = PhGetIntegerSetting(L"MaxSizeUnit"); if (PhGetIntegerSetting(L"SampleCountAutomatic")) { ULONG sampleCount; sampleCount = (GetSystemMetrics(SM_CXVIRTUALSCREEN) + 1) / 2; if (sampleCount > 2048) sampleCount = 2048; PhSetIntegerSetting(L"SampleCount", sampleCount); } }
static VOID RemoveAppCompatEntry( _In_ HANDLE ParentKey ) { static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"ProcessHacker.exe"); ULONG bufferLength; KEY_FULL_INFORMATION fullInfo; memset(&fullInfo, 0, sizeof(KEY_FULL_INFORMATION)); if (!NT_SUCCESS(NtQueryKey( ParentKey, KeyFullInformation, &fullInfo, sizeof(KEY_FULL_INFORMATION), &bufferLength ))) { return; } for (ULONG i = 0; i < fullInfo.Values; i++) { PPH_STRING value; PKEY_VALUE_FULL_INFORMATION buffer; bufferLength = sizeof(KEY_VALUE_FULL_INFORMATION); buffer = PhAllocate(bufferLength); memset(buffer, 0, bufferLength); if (NT_SUCCESS(NtEnumerateValueKey( ParentKey, i, KeyValueFullInformation, buffer, bufferLength, &bufferLength ))) { PhFree(buffer); break; } //bufferLength = bufferLength; buffer = PhReAllocate(buffer, bufferLength); memset(buffer, 0, bufferLength); if (!NT_SUCCESS(NtEnumerateValueKey( ParentKey, i, KeyValueFullInformation, buffer, bufferLength, &bufferLength ))) { PhFree(buffer); break; } if (value = PhCreateStringEx(buffer->Name, buffer->NameLength)) { UNICODE_STRING us; PhStringRefToUnicodeString(&value->sr, &us); if (PhEndsWithStringRef(&value->sr, &keyName, TRUE)) { NtDeleteValueKey(ParentKey, &us); } PhDereferenceObject(value); } PhFree(buffer); } }
NTSTATUS PhpGetBestObjectName( __in HANDLE ProcessHandle, __in HANDLE Handle, __in PPH_STRING ObjectName, __in PPH_STRING TypeName, __out PPH_STRING *BestObjectName ) { NTSTATUS status; PPH_STRING bestObjectName = NULL; PPH_GET_CLIENT_ID_NAME handleGetClientIdName; if (PhEqualString2(TypeName, L"EtwRegistration", TRUE)) { if (KphIsConnected()) { ETWREG_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectEtwRegBasicInformation, &basicInfo, sizeof(ETWREG_BASIC_INFORMATION), NULL ); if (NT_SUCCESS(status)) { static PH_STRINGREF publishersKeyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Publishers\\"); PPH_STRING guidString; PPH_STRING keyName; HANDLE keyHandle; PPH_STRING publisherName = NULL; guidString = PhFormatGuid(&basicInfo.Guid); // We should perform a lookup on the GUID to get the publisher name. keyName = PhConcatStringRef2(&publishersKeyName, &guidString->sr); if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName->sr, 0 ))) { publisherName = PhQueryRegistryString(keyHandle, NULL); if (publisherName && publisherName->Length == 0) { PhDereferenceObject(publisherName); publisherName = NULL; } NtClose(keyHandle); } PhDereferenceObject(keyName); if (publisherName) { bestObjectName = publisherName; PhDereferenceObject(guidString); } else { bestObjectName = guidString; } } } } else if (PhEqualString2(TypeName, L"File", TRUE)) { // Convert the file name to a DOS file name. bestObjectName = PhResolveDevicePrefix(ObjectName); if (!bestObjectName) { bestObjectName = ObjectName; PhReferenceObject(ObjectName); } } else if (PhEqualString2(TypeName, L"Key", TRUE)) { bestObjectName = PhFormatNativeKeyName(ObjectName); } else if (PhEqualString2(TypeName, L"Process", TRUE)) { CLIENT_ID clientId; clientId.UniqueThread = NULL; if (KphIsConnected()) { PROCESS_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectProcessBasicInformation, &basicInfo, sizeof(PROCESS_BASIC_INFORMATION), NULL ); if (!NT_SUCCESS(status)) goto CleanupExit; clientId.UniqueProcess = basicInfo.UniqueProcessId; } else { HANDLE dupHandle; PROCESS_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ProcessQueryAccess, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetProcessBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (!NT_SUCCESS(status)) goto CleanupExit; clientId.UniqueProcess = basicInfo.UniqueProcessId; } handleGetClientIdName = PhHandleGetClientIdName; if (handleGetClientIdName) bestObjectName = handleGetClientIdName(&clientId); } else if (PhEqualString2(TypeName, L"Thread", TRUE)) { CLIENT_ID clientId; if (KphIsConnected()) { THREAD_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL ); if (!NT_SUCCESS(status)) goto CleanupExit; clientId = basicInfo.ClientId; } else { HANDLE dupHandle; THREAD_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ThreadQueryAccess, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetThreadBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (!NT_SUCCESS(status)) goto CleanupExit; clientId = basicInfo.ClientId; } handleGetClientIdName = PhHandleGetClientIdName; if (handleGetClientIdName) bestObjectName = handleGetClientIdName(&clientId); } else if (PhEqualString2(TypeName, L"TmEn", TRUE)) { HANDLE dupHandle; ENLISTMENT_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ENLISTMENT_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetEnlistmentBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.EnlistmentId); } } else if (PhEqualString2(TypeName, L"TmRm", TRUE)) { HANDLE dupHandle; GUID guid; PPH_STRING description; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, RESOURCEMANAGER_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetResourceManagerBasicInformation( dupHandle, &guid, &description ); NtClose(dupHandle); if (NT_SUCCESS(status)) { if (!PhIsNullOrEmptyString(description)) { bestObjectName = description; } else { bestObjectName = PhFormatGuid(&guid); if (description) PhDereferenceObject(description); } } } else if (PhEqualString2(TypeName, L"TmTm", TRUE)) { HANDLE dupHandle; PPH_STRING logFileName = NULL; TRANSACTIONMANAGER_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TRANSACTIONMANAGER_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTransactionManagerLogFileName( dupHandle, &logFileName ); if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(logFileName)) { bestObjectName = PhGetFileName(logFileName); PhDereferenceObject(logFileName); } else { if (logFileName) PhDereferenceObject(logFileName); status = PhGetTransactionManagerBasicInformation( dupHandle, &basicInfo ); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.TmIdentity); } } NtClose(dupHandle); } else if (PhEqualString2(TypeName, L"TmTx", TRUE)) { HANDLE dupHandle; PPH_STRING description = NULL; TRANSACTION_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TRANSACTION_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTransactionPropertiesInformation( dupHandle, NULL, NULL, &description ); if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(description)) { bestObjectName = description; } else { if (description) PhDereferenceObject(description); status = PhGetTransactionBasicInformation( dupHandle, &basicInfo ); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.TransactionId); } } NtClose(dupHandle); } else if (PhEqualString2(TypeName, L"Token", TRUE)) { HANDLE dupHandle; PTOKEN_USER tokenUser = NULL; TOKEN_STATISTICS statistics = { 0 }; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TOKEN_QUERY, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTokenUser(dupHandle, &tokenUser); PhGetTokenStatistics(dupHandle, &statistics); if (NT_SUCCESS(status)) { PPH_STRING fullName; fullName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); if (fullName) { PH_FORMAT format[3]; PhInitFormatSR(&format[0], fullName->sr); PhInitFormatS(&format[1], L": 0x"); PhInitFormatX(&format[2], statistics.AuthenticationId.LowPart); bestObjectName = PhFormat(format, 3, fullName->Length + 8 + 16); PhDereferenceObject(fullName); } PhFree(tokenUser); } NtClose(dupHandle); } CleanupExit: if (!bestObjectName) { bestObjectName = ObjectName; PhReferenceObject(ObjectName); } *BestObjectName = bestObjectName; return STATUS_SUCCESS; }
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); }