NTSTATUS PhpGetDllBaseRemote( _In_ HANDLE ProcessHandle, _In_ PPH_STRINGREF BaseDllName, _Out_ PVOID *DllBase ) { NTSTATUS status; GET_DLL_BASE_REMOTE_CONTEXT context; #ifdef _WIN64 BOOLEAN isWow64 = FALSE; #endif context.BaseDllName = *BaseDllName; context.DllBase = NULL; #ifdef _WIN64 PhGetProcessIsWow64(ProcessHandle, &isWow64); if (isWow64) status = PhEnumProcessModules32(ProcessHandle, PhpGetDllBaseRemoteCallback, &context); if (!context.DllBase) #endif status = PhEnumProcessModules(ProcessHandle, PhpGetDllBaseRemoteCallback, &context); if (NT_SUCCESS(status)) *DllBase = context.DllBase; return status; }
ICLRDataTarget *DnCLRDataTarget_Create( __in HANDLE ProcessId ) { DnCLRDataTarget *dataTarget; HANDLE processHandle; BOOLEAN isWow64; if (!NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess | PROCESS_VM_READ, ProcessId))) return NULL; #ifdef _M_X64 if (!NT_SUCCESS(PhGetProcessIsWow64(processHandle, &isWow64))) { NtClose(processHandle); return NULL; } #else isWow64 = FALSE; #endif dataTarget = PhAllocate(sizeof(DnCLRDataTarget)); dataTarget->VTable = &DnCLRDataTarget_VTable; dataTarget->RefCount = 1; dataTarget->ProcessId = ProcessId; dataTarget->ProcessHandle = processHandle; dataTarget->IsWow64 = isWow64; return (ICLRDataTarget *)dataTarget; }
ULONG GetProcessDotNetVersions( __in HANDLE ProcessId ) { HANDLE processHandle; ULONG versions; #ifdef _M_X64 BOOLEAN isWow64; #endif versions = 0; if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess | PROCESS_VM_READ, ProcessId))) { #ifdef _M_X64 isWow64 = FALSE; PhGetProcessIsWow64(processHandle, &isWow64); if (isWow64) versions |= CLR_PROCESS_IS_WOW64; #endif PhEnumGenericModules(ProcessId, processHandle, 0, DotNetVersionsEnumModulesCallback, &versions); NtClose(processHandle); } return versions; }
BOOLEAN PhpCreateProcessMiniDumpWithProgress( _In_ HWND hWnd, _In_ HANDLE ProcessId, _In_ PWSTR FileName, _In_ MINIDUMP_TYPE DumpType ) { NTSTATUS status; PROCESS_MINIDUMP_CONTEXT context; memset(&context, 0, sizeof(PROCESS_MINIDUMP_CONTEXT)); context.ProcessId = ProcessId; context.FileName = FileName; context.DumpType = DumpType; if (!NT_SUCCESS(status = PhOpenProcess( &context.ProcessHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, ProcessId ))) { PhShowStatus(hWnd, L"Unable to open the process", status, 0); return FALSE; } #ifdef _WIN64 PhGetProcessIsWow64(context.ProcessHandle, &context.IsWow64); #endif status = PhCreateFileWin32( &context.FileHandle, FileName, FILE_GENERIC_WRITE | DELETE, 0, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) { PhShowStatus(hWnd, L"Unable to access the dump file", status, 0); NtClose(context.ProcessHandle); return FALSE; } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_PROGRESS), hWnd, PhpProcessMiniDumpDlgProc, (LPARAM)&context ); NtClose(context.FileHandle); NtClose(context.ProcessHandle); return context.Succeeded; }
BOOLEAN PhIsExecutingInWow64( VOID ) { static BOOLEAN valid = FALSE; static BOOLEAN isWow64; if (!valid) { PhGetProcessIsWow64(NtCurrentProcess(), &isWow64); MemoryBarrier(); valid = TRUE; } return isWow64; }
VOID PhUiAnalyzeWaitThread( _In_ HWND hWnd, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId, _In_ PPH_SYMBOL_PROVIDER SymbolProvider ) { NTSTATUS status; HANDLE threadHandle; #ifdef _WIN64 HANDLE processHandle; BOOLEAN isWow64; #endif CLIENT_ID clientId; ANALYZE_WAIT_CONTEXT context; #ifdef _WIN64 // Determine if the process is WOW64. If not, we use the passive method. if (!NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_LIMITED_INFORMATION, ProcessId))) { PhShowStatus(hWnd, L"Unable to open the process", status, 0); return; } if (!NT_SUCCESS(status = PhGetProcessIsWow64(processHandle, &isWow64)) || !isWow64) { PhpAnalyzeWaitPassive(hWnd, ProcessId, ThreadId); return; } NtClose(processHandle); #endif if (!NT_SUCCESS(status = PhOpenThread( &threadHandle, THREAD_QUERY_LIMITED_INFORMATION | THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME, ThreadId ))) { PhShowStatus(hWnd, L"Unable to open the thread.", status, 0); return; } memset(&context, 0, sizeof(ANALYZE_WAIT_CONTEXT)); context.ProcessId = ProcessId; context.ThreadId = ThreadId; context.ProcessHandle = SymbolProvider->ProcessHandle; context.SymbolProvider = SymbolProvider; PhInitializeStringBuilder(&context.StringBuilder, 100); clientId.UniqueProcess = ProcessId; clientId.UniqueThread = ThreadId; PhWalkThreadStack( threadHandle, SymbolProvider->ProcessHandle, &clientId, SymbolProvider, PH_WALK_I386_STACK, PhpWalkThreadStackAnalyzeCallback, &context ); NtClose(threadHandle); PhpAnalyzeWaitFallbacks(&context); if (context.Found) { PhShowInformationDialog(hWnd, context.StringBuilder.String->Buffer, 0); } else { PhShowInformation2(hWnd, L"The thread does not appear to be waiting.", L""); } PhDeleteStringBuilder(&context.StringBuilder); }