diff --git a/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys b/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys index cad5af8b6..c6a6339b4 100644 Binary files a/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys and b/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys differ diff --git a/2.x/trunk/KProcessHacker/include/kph.h b/2.x/trunk/KProcessHacker/include/kph.h index 84bd08bc4..f8d3855d6 100644 --- a/2.x/trunk/KProcessHacker/include/kph.h +++ b/2.x/trunk/KProcessHacker/include/kph.h @@ -107,6 +107,20 @@ typedef struct _DRIVER_BASIC_INFORMATION ULONG DriverSize; } DRIVER_BASIC_INFORMATION, *PDRIVER_BASIC_INFORMATION; +/* ETW registration object information */ + +typedef enum _ETWREG_INFORMATION_CLASS +{ + EtwRegBasicInformation, + MaxEtwRegInfoClass +} ETWREG_INFORMATION_CLASS; + +typedef struct _ETWREG_BASIC_INFORMATION +{ + GUID Guid; + ULONG_PTR SessionId; +} ETWREG_BASIC_INFORMATION, *PETWREG_BASIC_INFORMATION; + typedef struct _KPH_ATTACH_STATE { BOOLEAN Attached; @@ -336,6 +350,15 @@ NTSTATUS KphQueryInformationDriver( __in KPROCESSOR_MODE AccessMode ); +NTSTATUS KphQueryInformationEtwReg( + __in HANDLE EtwRegHandle, + __in ETWREG_INFORMATION_CLASS EtwRegInformationClass, + __out_bcount_opt(EtwRegInformationLength) PVOID EtwRegInformation, + __in ULONG EtwRegInformationLength, + __out_opt PULONG ReturnLength, + __in KPROCESSOR_MODE AccessMode + ); + NTSTATUS KphQueryNameFileObject( __in PFILE_OBJECT FileObject, __inout_bcount(BufferLength) PUNICODE_STRING Buffer, diff --git a/2.x/trunk/KProcessHacker/include/kprocesshacker.h b/2.x/trunk/KProcessHacker/include/kprocesshacker.h index 703b074e9..9423c976a 100644 --- a/2.x/trunk/KProcessHacker/include/kprocesshacker.h +++ b/2.x/trunk/KProcessHacker/include/kprocesshacker.h @@ -91,6 +91,7 @@ #define KPH_OPENDRIVER KPH_CTL_CODE(202) #define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(203) #define KPH_OPENTYPE KPH_CTL_CODE(204) +#define KPH_QUERYINFORMATIONETWREG KPH_CTL_CODE(205) /* Standard Driver Routines */ diff --git a/2.x/trunk/KProcessHacker/include/version.h b/2.x/trunk/KProcessHacker/include/version.h index 702b32457..7726dd96f 100644 --- a/2.x/trunk/KProcessHacker/include/version.h +++ b/2.x/trunk/KProcessHacker/include/version.h @@ -76,18 +76,22 @@ EXT ACCESS_MASK ThreadAllAccess; /* Offsets */ /* Structures - * Et: ETHREAD + * Ege: ETW_GUID_ENTRY * Ep: EPROCESS + * Ere: ETW_REG_ENTRY + * Et: ETHREAD * Oh: OBJECT_HEADER * Ot: OBJECT_TYPE * Oti: OBJECT_TYPE_INITIALIZER, offset measured from an OBJECT_TYPE */ -EXT ULONG OffEtClientId; +EXT ULONG OffEgeGuid; EXT ULONG OffEpJob; EXT ULONG OffEpObjectTable; EXT ULONG OffEpProtectedProcessOff; EXT ULONG OffEpProtectedProcessBit; EXT ULONG OffEpRundownProtect; +EXT ULONG OffEreGuidEntry; +EXT ULONG OffEtClientId; EXT ULONG OffOhBody; EXT ULONG OffOtName; EXT ULONG OffOtIndex; diff --git a/2.x/trunk/KProcessHacker/kprocesshacker.c b/2.x/trunk/KProcessHacker/kprocesshacker.c index 6a985c357..6d5bd5441 100644 --- a/2.x/trunk/KProcessHacker/kprocesshacker.c +++ b/2.x/trunk/KProcessHacker/kprocesshacker.c @@ -260,6 +260,8 @@ PCHAR KphpGetControlCodeName(ULONG ControlCode) return "KphQueryInformationDriver"; case KPH_OPENTYPE: return "KphOpenType"; + case KPH_QUERYINFORMATIONETWREG: + return "KphQueryInformationEtwReg"; default: return "Unknown"; @@ -1508,6 +1510,82 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) } break; + case KPH_QUERYINFORMATIONETWREG: + { + struct + { + HANDLE ProcessHandle; + HANDLE EtwRegHandle; + ETWREG_INFORMATION_CLASS EtwRegInformationClass; + PVOID EtwRegInformation; + ULONG EtwRegInformationLength; + PULONG ReturnLength; + } *args = dataBuffer; + ETWREG_BASIC_INFORMATION basicInfo; + KPH_ATTACH_STATE attachState; + + CHECK_IN_LENGTH; + + if (args->EtwRegInformationClass != EtwRegBasicInformation) + { + status = STATUS_INVALID_INFO_CLASS; + goto IoControlEnd; + } + + status = KphAttachProcessHandle(args->ProcessHandle, &attachState); + + if (!NT_SUCCESS(status)) + goto IoControlEnd; + + if (attachState.Process == PsInitialSystemProcess) + MakeKernelHandle(args->EtwRegHandle); + + status = KphQueryInformationEtwReg( + args->EtwRegHandle, + EtwRegBasicInformation, + &basicInfo, + sizeof(ETWREG_BASIC_INFORMATION), + NULL, + KernelMode + ); + KphDetachProcess(&attachState); + + if (!NT_SUCCESS(status)) + goto IoControlEnd; + + if ( + args->EtwRegInformation && + args->EtwRegInformationLength >= sizeof(ETWREG_BASIC_INFORMATION) + ) + { + __try + { + ProbeForWrite(args->EtwRegInformation, args->EtwRegInformationLength, 1); + memcpy(args->EtwRegInformation, &basicInfo, sizeof(ETWREG_BASIC_INFORMATION)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + goto IoControlEnd; + } + } + + if (args->ReturnLength) + { + __try + { + ProbeForWrite(args->ReturnLength, sizeof(ULONG), 1); + *args->ReturnLength = sizeof(ETWREG_BASIC_INFORMATION); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + goto IoControlEnd; + } + } + } + break; + default: { dprintf("Unrecognized IOCTL code 0x%08x\n", controlCode); diff --git a/2.x/trunk/KProcessHacker/ob.c b/2.x/trunk/KProcessHacker/ob.c index ab72700f3..0cc7cc47c 100644 --- a/2.x/trunk/KProcessHacker/ob.c +++ b/2.x/trunk/KProcessHacker/ob.c @@ -890,3 +890,128 @@ PHANDLE_TABLE ObReferenceProcessHandleTable( return handleTable; } + +/* KphQueryInformationEtwReg + * + * Queries information about an ETW registration entry. + */ +NTSTATUS KphQueryInformationEtwReg( + __in HANDLE EtwRegHandle, + __in ETWREG_INFORMATION_CLASS EtwRegInformationClass, + __out_bcount_opt(EtwRegInformationLength) PVOID EtwRegInformation, + __in ULONG EtwRegInformationLength, + __out_opt PULONG ReturnLength, + __in KPROCESSOR_MODE AccessMode + ) +{ + NTSTATUS status = STATUS_SUCCESS; + PVOID etwRegEntry; + POBJECT_TYPE objectType; + UNICODE_STRING objectTypeName; + UNICODE_STRING etwRegistrationName; + + if (WindowsVersion < WINDOWS_VISTA) + return STATUS_NOT_SUPPORTED; + + if ( + EtwRegInformationClass < EtwRegBasicInformation || + EtwRegInformationClass >= MaxEtwRegInfoClass + ) + return STATUS_INVALID_INFO_CLASS; + + /* Probe user input. */ + if (AccessMode != KernelMode) + { + __try + { + if (EtwRegInformation) + ProbeForWrite(EtwRegInformation, EtwRegInformationLength, 1); + if (ReturnLength) + ProbeForWrite(ReturnLength, sizeof(ULONG), 1); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return GetExceptionCode(); + } + } + + status = ObReferenceObjectByHandle( + EtwRegHandle, + 0, + NULL, + KernelMode, + &etwRegEntry, + NULL + ); + + if (!NT_SUCCESS(status)) + return status; + + /* HACK: we can't get a pointer to the ETW registration type, so we have + * to check this way. + */ + objectType = KphGetObjectTypeNt(etwRegEntry); + objectTypeName = *(PUNICODE_STRING)KVOFF(objectType, OffOtName); + RtlInitUnicodeString(&etwRegistrationName, L"EtwRegistration"); + + if (!RtlEqualUnicodeString(&objectTypeName, &etwRegistrationName, TRUE)) + { + ObDereferenceObject(etwRegEntry); + return STATUS_OBJECT_TYPE_MISMATCH; + } + + __try + { + switch (EtwRegInformationClass) + { + case EtwRegBasicInformation: + { + if (EtwRegInformation) + { + /* Check buffer length. */ + if (EtwRegInformationLength == sizeof(ETWREG_BASIC_INFORMATION)) + { + PETWREG_BASIC_INFORMATION basicInfo; + PVOID guidEntry; + + basicInfo = (PETWREG_BASIC_INFORMATION)EtwRegInformation; + + guidEntry = *(PVOID *)KVOFF(etwRegEntry, OffEreGuidEntry); + + if (guidEntry) + { + basicInfo->Guid = *(PGUID)KVOFF(guidEntry, OffEgeGuid); + } + else + { + memset(&basicInfo->Guid, 0, sizeof(GUID)); + } + + basicInfo->SessionId = 0; // TODO + } + else + { + status = STATUS_INFO_LENGTH_MISMATCH; + } + } + + if (ReturnLength) + *ReturnLength = sizeof(DRIVER_BASIC_INFORMATION); + } + break; + + default: + { + status = STATUS_INVALID_INFO_CLASS; + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + ObDereferenceObject(etwRegEntry); + + return status; +} diff --git a/2.x/trunk/KProcessHacker/version.c b/2.x/trunk/KProcessHacker/version.c index f7f785549..ea220f949 100644 --- a/2.x/trunk/KProcessHacker/version.c +++ b/2.x/trunk/KProcessHacker/version.c @@ -130,12 +130,12 @@ NTSTATUS KvInit() ProcessAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff; ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff; - OffEtClientId = 0x1ec; OffEpJob = 0x134; OffEpObjectTable = 0xc4; OffEpProtectedProcessOff = 0; OffEpProtectedProcessBit = 0; OffEpRundownProtect = 0x80; + OffEtClientId = 0x1ec; OffOhBody = 0x18; OffOtName = 0x40; OffOtIndex = 0x4c; @@ -189,12 +189,12 @@ NTSTATUS KvInit() ProcessAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff; ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff; - OffEtClientId = 0x1e4; OffEpJob = 0x120; OffEpObjectTable = 0xd4; OffEpProtectedProcessOff = 0; OffEpProtectedProcessBit = 0; OffEpRundownProtect = 0x90; + OffEtClientId = 0x1e4; OffOhBody = 0x18; OffOtName = 0x40; OffOtIndex = 0x4c; @@ -242,12 +242,14 @@ NTSTATUS KvInit() ProcessAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1fff; ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff; - OffEtClientId = 0x20c; + OffEgeGuid = 0xc; OffEpJob = 0x10c; OffEpObjectTable = 0xdc; OffEpProtectedProcessOff = 0x224; OffEpProtectedProcessBit = 0xb; OffEpRundownProtect = 0x98; + OffEreGuidEntry = 0x8; + OffEtClientId = 0x20c; OffOhBody = 0x18; INIT_SCAN( @@ -304,12 +306,14 @@ NTSTATUS KvInit() ProcessAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1fff; ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff; - OffEtClientId = 0x22c; + OffEgeGuid = 0xc; OffEpJob = 0x124; OffEpObjectTable = 0xf4; OffEpProtectedProcessOff = 0x26c; OffEpProtectedProcessBit = 0xb; OffEpRundownProtect = 0xb0; + OffEreGuidEntry = 0x8; + OffEtClientId = 0x22c; OffOhBody = 0x18; OffOtName = 0x8; OffOtIndex = 0x14; /* Now only a UCHAR, not a ULONG */ diff --git a/2.x/trunk/ProcessHacker/include/providers.h b/2.x/trunk/ProcessHacker/include/providers.h index ea6a0effe..fa28bc525 100644 --- a/2.x/trunk/ProcessHacker/include/providers.h +++ b/2.x/trunk/ProcessHacker/include/providers.h @@ -482,4 +482,23 @@ typedef struct _PH_MEMORY_ITEM PPH_STRING Name; } PH_MEMORY_ITEM, *PPH_MEMORY_ITEM; +typedef struct _PH_MEMORY_PROVIDER *PPH_MEMORY_PROVIDER; + +typedef BOOLEAN (NTAPI *PPH_MEMORY_PROVIDER_CALLBACK)( + __in PPH_MEMORY_PROVIDER Provider, + __in __assumeRefs(1) PPH_MEMORY_ITEM MemoryItem + ); + +typedef struct _PH_MEMORY_PROVIDER +{ + PPH_MEMORY_PROVIDER_CALLBACK Callback; + + HANDLE ProcessId; + HANDLE ProcessHandle; +} PH_MEMORY_PROVIDER, *PPH_MEMORY_PROVIDER; + +VOID PhMemoryProviderUpdate( + __in PPH_MEMORY_PROVIDER Provider + ); + #endif diff --git a/2.x/trunk/ProcessHacker/memprv.c b/2.x/trunk/ProcessHacker/memprv.c index 921c7e3eb..c0a1e4c6e 100644 --- a/2.x/trunk/ProcessHacker/memprv.c +++ b/2.x/trunk/ProcessHacker/memprv.c @@ -23,4 +23,9 @@ #define MEMPRV_PRIVATE #include +VOID PhMemoryProviderUpdate( + __in PPH_MEMORY_PROVIDER Provider + ) +{ +} diff --git a/2.x/trunk/phlib/hndlinfo.c b/2.x/trunk/phlib/hndlinfo.c index 119ac4521..f33199521 100644 --- a/2.x/trunk/phlib/hndlinfo.c +++ b/2.x/trunk/phlib/hndlinfo.c @@ -501,7 +501,29 @@ NTSTATUS PhpGetBestObjectName( NTSTATUS status; PPH_STRING bestObjectName = NULL; - if (PhStringEquals2(TypeName, L"File", TRUE)) + if (PhStringEquals2(TypeName, L"EtwRegistration", TRUE)) + { + if (PhKphHandle) + { + ETWREG_BASIC_INFORMATION basicInfo; + + status = KphQueryInformationEtwReg( + PhKphHandle, + ProcessHandle, + Handle, + EtwRegBasicInformation, + &basicInfo, + sizeof(ETWREG_BASIC_INFORMATION), + NULL + ); + + if (NT_SUCCESS(status)) + { + bestObjectName = PhFormatGuid(&basicInfo.Guid); + } + } + } + else if (PhStringEquals2(TypeName, L"File", TRUE)) { // Convert the file name to a DOS file name. bestObjectName = PhResolveDevicePrefix(ObjectName); diff --git a/2.x/trunk/phlib/include/kph.h b/2.x/trunk/phlib/include/kph.h index 597b62d06..e36205345 100644 --- a/2.x/trunk/phlib/include/kph.h +++ b/2.x/trunk/phlib/include/kph.h @@ -60,6 +60,7 @@ #define KPH_OPENDRIVER KPH_CTL_CODE(202) #define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(203) #define KPH_OPENTYPE KPH_CTL_CODE(204) +#define KPH_QUERYINFORMATIONETWREG KPH_CTL_CODE(205) // Process handle information @@ -107,6 +108,20 @@ typedef struct _DRIVER_SERVICE_KEY_NAME_INFORMATION UNICODE_STRING ServiceKeyName; } DRIVER_SERVICE_KEY_NAME_INFORMATION, *PDRIVER_SERVICE_KEY_NAME_INFORMATION; +// ETW registration object information + +typedef enum _ETWREG_INFORMATION_CLASS +{ + EtwRegBasicInformation, + MaxEtwRegInfoClass +} ETWREG_INFORMATION_CLASS; + +typedef struct _ETWREG_BASIC_INFORMATION +{ + GUID Guid; + ULONG_PTR SessionId; +} ETWREG_BASIC_INFORMATION, *PETWREG_BASIC_INFORMATION; + NTSTATUS KphInit(); NTSTATUS KphConnect( @@ -421,4 +436,14 @@ NTSTATUS KphOpenType( __in POBJECT_ATTRIBUTES ObjectAttributes ); +NTSTATUS KphQueryInformationEtwReg( + __in HANDLE KphHandle, + __in HANDLE ProcessHandle, + __in HANDLE EtwRegHandle, + __in ETWREG_INFORMATION_CLASS EtwRegInformationClass, + __out_bcount_opt(EtwRegInformationLength) PVOID EtwRegInformation, + __in ULONG EtwRegInformationLength, + __out_opt PULONG ReturnLength + ); + #endif diff --git a/2.x/trunk/phlib/kph.c b/2.x/trunk/phlib/kph.c index 9b77aa4e0..3cc0c2cec 100644 --- a/2.x/trunk/phlib/kph.c +++ b/2.x/trunk/phlib/kph.c @@ -1728,3 +1728,41 @@ NTSTATUS KphOpenType( NULL ); } + +NTSTATUS KphQueryInformationEtwReg( + __in HANDLE KphHandle, + __in HANDLE ProcessHandle, + __in HANDLE EtwRegHandle, + __in ETWREG_INFORMATION_CLASS EtwRegInformationClass, + __out_bcount_opt(EtwRegInformationLength) PVOID EtwRegInformation, + __in ULONG EtwRegInformationLength, + __out_opt PULONG ReturnLength + ) +{ + struct + { + HANDLE ProcessHandle; + HANDLE EtwRegHandle; + ETWREG_INFORMATION_CLASS EtwRegInformationClass; + PVOID EtwRegInformation; + ULONG EtwRegInformationLength; + PULONG ReturnLength; + } args; + + args.ProcessHandle = ProcessHandle; + args.EtwRegHandle = EtwRegHandle; + args.EtwRegInformationClass = EtwRegInformationClass; + args.EtwRegInformation = EtwRegInformation; + args.EtwRegInformationLength = EtwRegInformationLength; + args.ReturnLength = ReturnLength; + + return KphpDeviceIoControl( + KphHandle, + KPH_QUERYINFORMATIONETWREG, + &args, + sizeof(args), + NULL, + 0, + NULL + ); +}