summaryrefslogtreecommitdiff
path: root/psutil
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-12-14 22:03:32 +0100
committerGitHub <noreply@github.com>2020-12-14 22:03:32 +0100
commita6e5e3cf959d803e0dbabd9eade8959bab086ee3 (patch)
treed169d7197866967173e92567bae1a018b275afd7 /psutil
parent6e288e0105b001ad37e67279d73578b3e1790877 (diff)
downloadpsutil-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.c46
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