diff options
| author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-12-14 22:03:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-14 22:03:32 +0100 |
| commit | a6e5e3cf959d803e0dbabd9eade8959bab086ee3 (patch) | |
| tree | d169d7197866967173e92567bae1a018b275afd7 /psutil | |
| parent | 6e288e0105b001ad37e67279d73578b3e1790877 (diff) | |
| download | psutil-a6e5e3cf959d803e0dbabd9eade8959bab086ee3.tar.gz | |
[Windows] giveup with AD for all NtWow64 API calls (query 64-bit process from 32-bit) (#1888)
On Windows, cmdline(), cwd() and environ() use some complex logic to query a 64 bit process from a 32 bit one by using NtWow64* APIs which may randomly file with:
[Error 0] The operation completed successfully
[Error 998] Invalid access to memory location
possibly others
Since this happens randomly and it's unclear how to do this properly, this PR turns any error from NtWow64* APIs into AccessDenied.
Signed-off-by: Giampaolo Rodola <g.rodola@gmail.com>
Diffstat (limited to 'psutil')
| -rw-r--r-- | psutil/arch/windows/process_info.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c index 0ce6297a..d44c4eb7 100644 --- a/psutil/arch/windows/process_info.c +++ b/psutil/arch/windows/process_info.c @@ -77,6 +77,21 @@ psutil_convert_ntstatus_err(NTSTATUS status, char* syscall) { } +static void +psutil_giveup_with_ad(NTSTATUS status, char* syscall) { + ULONG err; + char fullmsg[8192]; + + if (NT_NTWIN32(status)) + err = WIN32_FROM_NTSTATUS(status); + else + err = RtlNtStatusToDosErrorNoTeb(status); + sprintf(fullmsg, "%s -> %lu (%s)", syscall, err, strerror(err)); + psutil_debug(fullmsg); + AccessDenied(fullmsg); +} + + /* * Get data from the process with the given pid. The data is returned * in the pdata output member as a nul terminated string which must be @@ -190,7 +205,18 @@ psutil_get_process_data(DWORD pid, } } else #else // #ifdef _WIN64 - /* 32 bit case. Check if the target is also 32 bit. */ + // 32 bit process. In here we may run into a lot of errors, e.g.: + // * [Error 0] The operation completed successfully + // (originated from NtWow64ReadVirtualMemory64) + // * [Error 998] Invalid access to memory location: + // (originated from NtWow64ReadVirtualMemory64) + // Refs: + // * https://github.com/giampaolo/psutil/issues/1839 + // * https://github.com/giampaolo/psutil/pull/1866 + // Since the following code is quite hackish and fails unpredictably, + // in case of any error from NtWow64* APIs we raise AccessDenied. + + // 32 bit case. Check if the target is also 32 bit. if (!IsWow64Process(GetCurrentProcess(), &weAreWow64) || !IsWow64Process(hProcess, &theyAreWow64)) { PyErr_SetFromOSErrnoWithSyscall("IsWow64Process"); @@ -231,9 +257,14 @@ psutil_get_process_data(DWORD pid, sizeof(pbi64), NULL); if (!NT_SUCCESS(status)) { + /* psutil_convert_ntstatus_err( status, "NtWow64QueryInformationProcess64(ProcessBasicInformation)"); + */ + psutil_giveup_with_ad( + status, + "NtWow64QueryInformationProcess64(ProcessBasicInformation)"); goto error; } @@ -245,8 +276,13 @@ psutil_get_process_data(DWORD pid, sizeof(peb64), NULL); if (!NT_SUCCESS(status)) { + /* psutil_convert_ntstatus_err( status, "NtWow64ReadVirtualMemory64(pbi64.PebBaseAddress)"); + */ + psutil_giveup_with_ad( + status, + "NtWow64ReadVirtualMemory64(pbi64.PebBaseAddress)"); goto error; } @@ -258,8 +294,13 @@ psutil_get_process_data(DWORD pid, sizeof(procParameters64), NULL); if (!NT_SUCCESS(status)) { + /* psutil_convert_ntstatus_err( status, "NtWow64ReadVirtualMemory64(peb64.ProcessParameters)"); + */ + psutil_giveup_with_ad( + status, + "NtWow64ReadVirtualMemory64(peb64.ProcessParameters)"); goto error; } @@ -366,7 +407,8 @@ psutil_get_process_data(DWORD pid, size, NULL); if (!NT_SUCCESS(status)) { - psutil_convert_ntstatus_err(status, "NtWow64ReadVirtualMemory64"); + // psutil_convert_ntstatus_err(status, "NtWow64ReadVirtualMemory64"); + psutil_giveup_with_ad(status, "NtWow64ReadVirtualMemory64"); goto error; } } else |
