From b712cdc695cc7915006ca4bace7fac5e6ea80ea1 Mon Sep 17 00:00:00 2001 From: wj32 Date: Tue, 29 Dec 2009 21:57:14 +0000 Subject: [PATCH] added remaining KPH support to PhOpenThread, PhOpenProcessToken git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2534 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- 2.x/trunk/ProcessHacker/basesup.c | 50 +++++++++++ 2.x/trunk/ProcessHacker/include/ph.h | 11 ++- 2.x/trunk/ProcessHacker/include/phbase.h | 36 ++++++++ 2.x/trunk/ProcessHacker/kph.c | 2 +- 2.x/trunk/ProcessHacker/main.c | 22 ++++- 2.x/trunk/ProcessHacker/process.c | 55 +++++++++--- 2.x/trunk/ProcessHacker/support.c | 106 +++++++++++++++++++++++ 7 files changed, 266 insertions(+), 16 deletions(-) diff --git a/2.x/trunk/ProcessHacker/basesup.c b/2.x/trunk/ProcessHacker/basesup.c index 4c0225088..9291b8dee 100644 --- a/2.x/trunk/ProcessHacker/basesup.c +++ b/2.x/trunk/ProcessHacker/basesup.c @@ -265,6 +265,56 @@ PPH_STRING PhCreateStringEx( return string; } +PPH_STRING PhConcatStrings( + __in ULONG Count, + ... + ) +{ + va_list argptr; + ULONG i; + SIZE_T totalLength = 0; + SIZE_T stringLength; + PWSTR arg; + PPH_STRING string; + + // Compute the total length, in bytes, of the strings. + + va_start(argptr, Count); + + for (i = 0; i < Count; i++) + { + arg = va_arg(argptr, PWSTR); + totalLength += wcslen(arg) * sizeof(WCHAR); + } + + va_end(argptr); + + // Create the string. + + string = PhCreateStringEx(NULL, totalLength); + totalLength = 0; + + // Append the strings one by one. + + va_start(argptr, Count); + + for (i = 0; i < Count; i++) + { + arg = va_arg(argptr, PWSTR); + stringLength = wcslen(arg) * sizeof(WCHAR); + memcpy( + &string->Buffer[totalLength / sizeof(WCHAR)], + arg, + stringLength + ); + totalLength += stringLength; + } + + va_end(argptr); + + return string; +} + PPH_LIST PhCreateList( __in ULONG InitialCapacity ) diff --git a/2.x/trunk/ProcessHacker/include/ph.h b/2.x/trunk/ProcessHacker/include/ph.h index 365826c59..a2b77f0e0 100644 --- a/2.x/trunk/ProcessHacker/include/ph.h +++ b/2.x/trunk/ProcessHacker/include/ph.h @@ -349,6 +349,15 @@ PPH_STRING PhGetFileVersionInfoString2( __in PWSTR StringName ); -PPH_STRING PhGetSystemDirectory(); +PPH_STRING PhGetFullPath( + __in PWSTR FileName, + __out_opt PULONG IndexOfFileName + ); + +PPH_STRING PhGetSystemDirectory(); + +PPH_STRING PhGetApplicationFileName(); + +PPH_STRING PhGetApplicationDirectory(); #endif diff --git a/2.x/trunk/ProcessHacker/include/phbase.h b/2.x/trunk/ProcessHacker/include/phbase.h index 6bd5855a3..e6a22f6ee 100644 --- a/2.x/trunk/ProcessHacker/include/phbase.h +++ b/2.x/trunk/ProcessHacker/include/phbase.h @@ -9,6 +9,11 @@ #ifndef MAIN_PRIVATE +struct _PH_STRING; +typedef struct _PH_STRING *PPH_STRING; + +extern PPH_STRING PhApplicationDirectory; +extern PPH_STRING PhApplicationFileName; extern HFONT PhApplicationFont; extern HANDLE PhHeapHandle; extern HINSTANCE PhInstanceHandle; @@ -153,6 +158,11 @@ PPH_STRING PhCreateStringEx( __in SIZE_T Length ); +PPH_STRING PhConcatStrings( + __in ULONG Count, + ... + ); + PWSTR FORCEINLINE PhGetString( __in_opt PPH_STRING String ) @@ -163,6 +173,32 @@ PWSTR FORCEINLINE PhGetString( return NULL; } +PPH_STRING FORCEINLINE PhConcatStrings2( + __in PWSTR String1, + __in PWSTR String2 + ) +{ + PPH_STRING string; + SIZE_T length1; + SIZE_T length2; + + length1 = wcslen(String1) * sizeof(WCHAR); + length2 = wcslen(String2) * sizeof(WCHAR); + string = PhCreateStringEx(NULL, length1 + length2); + memcpy( + string->Buffer, + String1, + length1 + ); + memcpy( + &string->Buffer[length1 / sizeof(WCHAR)], + String2, + length2 + ); + + return string; +} + BOOLEAN FORCEINLINE PhStringEquals( __in PPH_STRING String1, __in PWSTR String2, diff --git a/2.x/trunk/ProcessHacker/kph.c b/2.x/trunk/ProcessHacker/kph.c index f149f2138..85d35ecbd 100644 --- a/2.x/trunk/ProcessHacker/kph.c +++ b/2.x/trunk/ProcessHacker/kph.c @@ -186,7 +186,7 @@ NTSTATUS KphpDeviceIoControl( ); if (NT_SUCCESS(status) && ReturnLength) - *ReturnLength = ioStatusBlock.Information; + *ReturnLength = (ULONG)ioStatusBlock.Information; return status; } diff --git a/2.x/trunk/ProcessHacker/main.c b/2.x/trunk/ProcessHacker/main.c index b0f974c6f..56150c2db 100644 --- a/2.x/trunk/ProcessHacker/main.c +++ b/2.x/trunk/ProcessHacker/main.c @@ -1,6 +1,9 @@ #define MAIN_PRIVATE #include +#include +PPH_STRING PhApplicationDirectory; +PPH_STRING PhApplicationFileName; HFONT PhApplicationFont; HANDLE PhHeapHandle; HINSTANCE PhInstanceHandle; @@ -38,6 +41,11 @@ INT WINAPI WinMain( if (!PhInitializeSystem()) return 1; + { + PhApplicationFileName = PhGetApplicationFileName(); + PhApplicationDirectory = PhGetApplicationDirectory(); + } + PhInitializeKph(); if (!PhMainWndInitialization(nCmdShow)) @@ -125,8 +133,20 @@ VOID PhInitializeFont( VOID PhInitializeKph() { + static WCHAR kprocesshacker[] = L"kprocesshacker.sys"; + PPH_STRING kprocesshackerFileName; + PhKphHandle = NULL; - KphConnect2(&PhKphHandle, L"KProcessHacker", L"kprocesshacker.sys"); + + // KProcessHacker doesn't support 64-bit systems. +#ifdef _M_IX86 + + // Append kprocesshacker.sys to the application directory. + kprocesshackerFileName = PhConcatStrings2(PhApplicationDirectory->Buffer, kprocesshacker); + + KphConnect2(&PhKphHandle, L"KProcessHacker", kprocesshackerFileName->Buffer); + PhDereferenceObject(kprocesshackerFileName); +#endif } BOOLEAN PhInitializeSystem() diff --git a/2.x/trunk/ProcessHacker/process.c b/2.x/trunk/ProcessHacker/process.c index 633d31aa8..588a82dc5 100644 --- a/2.x/trunk/ProcessHacker/process.c +++ b/2.x/trunk/ProcessHacker/process.c @@ -1,4 +1,5 @@ #include +#include static PWSTR PhDosDeviceNames[26]; @@ -43,15 +44,27 @@ NTSTATUS PhOpenThread( OBJECT_ATTRIBUTES objectAttributes = { 0 }; CLIENT_ID clientId; - clientId.UniqueProcess = NULL; - clientId.UniqueThread = ThreadId; + if (PhKphHandle) + { + return KphOpenThread( + PhKphHandle, + ThreadHandle, + ThreadId, + DesiredAccess + ); + } + else + { + clientId.UniqueProcess = NULL; + clientId.UniqueThread = ThreadId; - return NtOpenThread( - ThreadHandle, - DesiredAccess, - &objectAttributes, - &clientId - ); + return NtOpenThread( + ThreadHandle, + DesiredAccess, + &objectAttributes, + &clientId + ); + } } NTSTATUS PhOpenProcessToken( @@ -60,11 +73,23 @@ NTSTATUS PhOpenProcessToken( __in HANDLE ProcessHandle ) { - return NtOpenProcessToken( - ProcessHandle, - DesiredAccess, - TokenHandle - ); + if (PhKphHandle) + { + return KphOpenProcessToken( + PhKphHandle, + TokenHandle, + ProcessHandle, + DesiredAccess + ); + } + else + { + return NtOpenProcessToken( + ProcessHandle, + DesiredAccess, + TokenHandle + ); + } } NTSTATUS PhReadVirtualMemory( @@ -75,6 +100,10 @@ NTSTATUS PhReadVirtualMemory( __out_opt PSIZE_T NumberOfBytesRead ) { + // KphReadVirtualMemory is much slower than + // NtReadVirtualMemory, so we'll stick to + // the using the original system call. + return NtReadVirtualMemory( ProcessHandle, BaseAddress, diff --git a/2.x/trunk/ProcessHacker/support.c b/2.x/trunk/ProcessHacker/support.c index 5c82babf6..785840da8 100644 --- a/2.x/trunk/ProcessHacker/support.c +++ b/2.x/trunk/ProcessHacker/support.c @@ -119,6 +119,49 @@ PPH_STRING PhGetFileVersionInfoString2( return PhGetFileVersionInfoString(VersionInfo, subBlock); } +PPH_STRING PhGetFullPath( + __in PWSTR FileName, + __out_opt PULONG IndexOfFileName + ) +{ + PPH_STRING fullPath; + PVOID buffer; + ULONG bufferSize; + ULONG returnLength; + PWSTR filePart; + + bufferSize = 0x80; + buffer = PhAllocate(bufferSize * 2); + + returnLength = GetFullPathName(FileName, bufferSize, buffer, &filePart); + + if (returnLength > bufferSize) + { + PhFree(buffer); + bufferSize = returnLength; + buffer = PhAllocate(bufferSize * 2); + + returnLength = GetFullPathName(FileName, bufferSize, buffer, &filePart); + } + + if (returnLength == 0) + { + PhFree(buffer); + return NULL; + } + + fullPath = PhCreateString(buffer); + + if (IndexOfFileName) + { + *IndexOfFileName = (ULONG)(filePart - (PWSTR)buffer); + } + + PhFree(buffer); + + return fullPath; +} + PPH_STRING PhGetSystemDirectory() { PPH_STRING systemDirectory; @@ -151,3 +194,66 @@ PPH_STRING PhGetSystemDirectory() return systemDirectory; } + +PPH_STRING PhpGetApplicationFileName( + __out_opt PULONG IndexOfFileName + ) +{ + PPH_STRING fileName; + PVOID buffer; + ULONG bufferSize; + ULONG returnLength; + + bufferSize = 0x40; + buffer = PhAllocate(bufferSize * 2); + + while (TRUE) + { + returnLength = GetModuleFileName(GetModuleHandle(NULL), buffer, bufferSize); + + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + PhFree(buffer); + bufferSize *= 2; + buffer = PhAllocate(bufferSize); + } + else + { + break; + } + } + + if (returnLength == 0) + { + PhFree(buffer); + return NULL; + } + + fileName = PhGetFullPath((PWSTR)buffer, IndexOfFileName); + PhFree(buffer); + + return fileName; +} + +PPH_STRING PhGetApplicationFileName() +{ + return PhpGetApplicationFileName(NULL); +} + +PPH_STRING PhGetApplicationDirectory() +{ + PPH_STRING fileName; + ULONG indexOfFileName; + PPH_STRING path = NULL; + + fileName = PhpGetApplicationFileName(&indexOfFileName); + + if (fileName) + { + // Remove the file name from the path. + path = PhSubstring(fileName, 0, indexOfFileName); + PhDereferenceObject(fileName); + } + + return path; +}