From 71bb78db99fac9998979677cec2966d08e73ab3b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 20 Feb 2019 10:56:07 -0800 Subject: too complicated to load NtWow64ReadVirtualMemory64 dynamically; restore the original code --- make.bat | 2 ++ psutil/_psutil_windows.c | 6 ++-- psutil/arch/windows/global.c | 7 ++-- psutil/arch/windows/global.h | 4 +++ psutil/arch/windows/ntextapi.h | 10 ------ psutil/arch/windows/process_handles.c | 3 +- psutil/arch/windows/process_info.c | 61 ++++++++++++++++++++++++++--------- 7 files changed, 58 insertions(+), 35 deletions(-) diff --git a/make.bat b/make.bat index d47eaecc..c83ec4cb 100644 --- a/make.bat +++ b/make.bat @@ -27,6 +27,8 @@ if "%PYTHON%" == "" ( ) ) +set PYTHON=C:\Python36-32\python.exe + if "%TSCRIPT%" == "" ( set TSCRIPT=psutil\tests\__main__.py ) diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 36a800f6..3908884e 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -32,14 +32,14 @@ // Link with Iphlpapi.lib #pragma comment(lib, "IPHLPAPI.lib") -#include "_psutil_common.h" +#include "arch/windows/ntextapi.h" +#include "arch/windows/global.h" #include "arch/windows/security.h" #include "arch/windows/process_info.h" #include "arch/windows/process_handles.h" -#include "arch/windows/ntextapi.h" -#include "arch/windows/global.h" #include "arch/windows/inet_ntop.h" #include "arch/windows/services.h" +#include "_psutil_common.h" /* diff --git a/psutil/arch/windows/global.c b/psutil/arch/windows/global.c index d7ca4fce..c669620b 100644 --- a/psutil/arch/windows/global.c +++ b/psutil/arch/windows/global.c @@ -11,7 +11,7 @@ // A wrapper around GetModuleHandle and GetProcAddress. -static PVOID +PVOID psutil_GetProcAddress(LPCSTR libname, LPCSTR procname) { HMODULE mod; FARPROC addr; @@ -29,7 +29,7 @@ psutil_GetProcAddress(LPCSTR libname, LPCSTR procname) { // A wrapper around LoadLibrary and GetProcAddress. -static PVOID +PVOID psutil_GetProcAddressFromLib(LPCSTR libname, LPCSTR procname) { HMODULE mod; FARPROC addr; @@ -127,9 +127,6 @@ psutil_loadlibs() { psutil_NtWow64QueryInformationProcess64 = psutil_GetProcAddressFromLib( "ntdll.dll", "NtWow64QueryInformationProcess64"); - psutil_NtWow64ReadVirtualMemory64 = psutil_GetProcAddressFromLib( - "ntdll.dll", "NtWow64ReadVirtualMemory64"); - PyErr_Clear(); return 0; } diff --git a/psutil/arch/windows/global.h b/psutil/arch/windows/global.h index 0a6cd25d..8d828776 100644 --- a/psutil/arch/windows/global.h +++ b/psutil/arch/windows/global.h @@ -4,4 +4,8 @@ * found in the LICENSE file. */ +#include + int psutil_loadlibs(); +PVOID psutil_GetProcAddress(LPCSTR libname, LPCSTR procname); +PVOID psutil_GetProcAddressFromLib(LPCSTR libname, LPCSTR procname); diff --git a/psutil/arch/windows/ntextapi.h b/psutil/arch/windows/ntextapi.h index e2b8329e..838b48e8 100644 --- a/psutil/arch/windows/ntextapi.h +++ b/psutil/arch/windows/ntextapi.h @@ -457,13 +457,6 @@ typedef NTSTATUS (NTAPI *_NtQueryObject)( PULONG ReturnLength ); -typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)( - HANDLE ProcessHandle, - PVOID64 BaseAddress, - PVOID Buffer, - ULONG64 Size, - PULONG64 NumberOfBytesRead); - /* * ================================================================ * Custom psutil definitions for modules loaded at runtime. @@ -507,9 +500,6 @@ _NtQueryObject \ _NtQueryInformationProcess \ psutil_NtWow64QueryInformationProcess64; -_NtWow64ReadVirtualMemory64 \ - psutil_NtWow64ReadVirtualMemory64; - _GetLogicalProcessorInformationEx \ psutil_GetLogicalProcessorInformationEx; diff --git a/psutil/arch/windows/process_handles.c b/psutil/arch/windows/process_handles.c index b193feee..f295f18d 100644 --- a/psutil/arch/windows/process_handles.c +++ b/psutil/arch/windows/process_handles.c @@ -8,9 +8,10 @@ #include #include #include +#include "ntextapi.h" +#include "global.h" #include "process_handles.h" #include "process_info.h" -#include "global.h" #include "../../_psutil_common.h" CRITICAL_SECTION g_cs; diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c index bd8952a9..83c7b8bd 100644 --- a/psutil/arch/windows/process_info.c +++ b/psutil/arch/windows/process_info.c @@ -12,10 +12,10 @@ #include #include -#include "security.h" -#include "process_info.h" #include "ntextapi.h" #include "global.h" +#include "security.h" +#include "process_info.h" #include "../../_psutil_common.h" @@ -77,6 +77,16 @@ typedef struct { /* More fields ... */ } PEB32; #else +/* When we are a 32 bit (WoW64) process accessing a 64 bit process we need to + use the 64 bit structure layout and a special function to read its memory. + */ +typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)( + HANDLE ProcessHandle, + PVOID64 BaseAddress, + PVOID Buffer, + ULONG64 Size, + PULONG64 NumberOfBytesRead); + typedef struct { PVOID Reserved1[2]; PVOID64 PebBaseAddress; @@ -112,6 +122,7 @@ typedef struct { } PEB64; #endif + #define PSUTIL_FIRST_PROCESS(Processes) ( \ (PSYSTEM_PROCESS_INFORMATION)(Processes)) #define PSUTIL_NEXT_PROCESS(Process) ( \ @@ -445,6 +456,11 @@ psutil_get_process_data(long pid, http://stackoverflow.com/a/14012919 http://www.drdobbs.com/embracing-64-bit-windows/184401966 */ + _NtQueryInformationProcess NtQueryInformationProcess = NULL; +#ifndef _WIN64 + static _NtQueryInformationProcess NtWow64QueryInformationProcess64 = NULL; + static _NtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = NULL; +#endif HANDLE hProcess = NULL; LPCVOID src; SIZE_T size; @@ -525,13 +541,27 @@ psutil_get_process_data(long pid, PEB64 peb64; RTL_USER_PROCESS_PARAMETERS64 procParameters64; - if ((psutil_NtWow64QueryInformationProcess64 == NULL) || - (psutil_NtWow64ReadVirtualMemory64 == NULL)) { - AccessDenied("can't query 64-bit process in 32-bit-WoW mode"); - goto error; + if (NtWow64QueryInformationProcess64 == NULL) { + NtWow64QueryInformationProcess64 = \ + psutil_GetProcAddressFromLib( + "ntdll.dll", "NtWow64QueryInformationProcess64"); + if (NtWow64QueryInformationProcess64 == NULL) { + AccessDenied("can't query 64-bit process in 32-bit-WoW mode"); + goto error; + } + } + if (NtWow64ReadVirtualMemory64 == NULL) { + NtWow64ReadVirtualMemory64 = \ + psutil_GetProcAddressFromLib( + "ntdll.dll", "NtWow64ReadVirtualMemory64"); + if (NtWow64ReadVirtualMemory64 == NULL) { + AccessDenied("can't query 64-bit process in 32-bit-WoW mode"); + goto error; + } } - if (! NT_SUCCESS(psutil_NtWow64QueryInformationProcess64( + if (! NT_SUCCESS( + NtWow64QueryInformationProcess64( hProcess, ProcessBasicInformation, &pbi64, @@ -543,19 +573,19 @@ psutil_get_process_data(long pid, } // read peb - if (! NT_SUCCESS(psutil_NtWow64ReadVirtualMemory64( - hProcess, - pbi64.PebBaseAddress, - &peb64, - sizeof(peb64), - NULL))) + if (! NT_SUCCESS(NtWow64ReadVirtualMemory64( + hProcess, + pbi64.PebBaseAddress, + &peb64, + sizeof(peb64), + NULL))) { PyErr_SetFromWindowsErr(0); goto error; } // read process parameters - if (! NT_SUCCESS(psutil_NtWow64ReadVirtualMemory64( + if (! NT_SUCCESS(NtWow64ReadVirtualMemory64( hProcess, peb64.ProcessParameters, &procParameters64, @@ -581,7 +611,6 @@ psutil_get_process_data(long pid, } } else #endif - /* Target process is of the same bitness as us. */ { PROCESS_BASIC_INFORMATION pbi; @@ -655,7 +684,7 @@ psutil_get_process_data(long pid, #ifndef _WIN64 if (weAreWow64 && !theyAreWow64) { - if (! NT_SUCCESS(psutil_NtWow64ReadVirtualMemory64( + if (! NT_SUCCESS(NtWow64ReadVirtualMemory64( hProcess, src64, buffer, -- cgit v1.2.1