diff --git a/2.x/trunk/KProcessHacker/handle.c b/2.x/trunk/KProcessHacker/handle.c
deleted file mode 100644
index 43b94fd9a..000000000
--- a/2.x/trunk/KProcessHacker/handle.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Process Hacker Driver -
- * handle table
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#include "include/handle.h"
-#include "include/handlep.h"
-
-NTSTATUS KphpAllocateHandleEntry(
- __in PKPH_HANDLE_TABLE HandleTable,
- __out PKPH_HANDLE_TABLE_ENTRY *Entry
- );
-
-NTSTATUS KphpFreeHandleEntry(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in PKPH_HANDLE_TABLE_ENTRY Entry
- );
-
-/* KphCreateHandleTable
- *
- * Creates a handle table.
- *
- * HandleTable: A variable which receives a pointer to the handle table.
- * MaximumHandles: The maximum number of handles that can be created.
- * SizeOfEntry: The size of each handle table entry. This value must be
- * divisible by 4.
- * Tag: The tag to use when allocating handle table resources.
- */
-NTSTATUS KphCreateHandleTable(
- __out PKPH_HANDLE_TABLE *HandleTable,
- __in ULONG MaximumHandles,
- __in ULONG SizeOfEntry,
- __in ULONG Tag
- )
-{
- PKPH_HANDLE_TABLE handleTable;
-
- /* Each handle entry must be at least the size of our
- * handle table entry definition.
- */
- if (SizeOfEntry < sizeof(KPH_HANDLE_TABLE_ENTRY))
- return STATUS_INVALID_PARAMETER_3;
- /* Handle entries must be 4-byte aligned. */
- if (SizeOfEntry % 4 != 0)
- return STATUS_INVALID_PARAMETER_3;
-
- /* Allocate storage for the handle table structure. */
- handleTable = ExAllocatePoolWithTag(
- PagedPool,
- sizeof(KPH_HANDLE_TABLE),
- Tag
- );
-
- if (!handleTable)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Allocate storage for the handle table itself. */
- handleTable->Table = ExAllocatePoolWithTag(
- PagedPool,
- MaximumHandles * SizeOfEntry,
- Tag
- );
-
- if (!handleTable->Table)
- {
- ExFreePoolWithTag(handleTable, Tag);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Initialize the rest of the table descriptor. */
- handleTable->Tag = Tag;
- handleTable->SizeOfEntry = SizeOfEntry;
- handleTable->NextHandle = (HANDLE)0;
- handleTable->FreeHandle = NULL;
- ExInitializeFastMutex(&handleTable->Mutex);
- handleTable->TableSize = MaximumHandles * SizeOfEntry;
-
- /* Zero the handle table. */
- memset(handleTable->Table, 0, handleTable->TableSize);
-
- /* Pass the pointer to the handle table back. */
- *HandleTable = handleTable;
-
- return STATUS_SUCCESS;
-}
-
-/* KphFreeHandleTable
- *
- * Frees all handle table resources.
- */
-VOID KphFreeHandleTable(
- __in PKPH_HANDLE_TABLE HandleTable
- )
-{
- ULONG i;
- ULONG tag;
-
- /* Free all handle values. */
- for (i = 0; i < HandleTable->TableSize / HandleTable->SizeOfEntry; i++)
- {
- KphCloseHandle(HandleTable, KphHandleFromIndex(i));
- }
-
- /* Save the handle table tag first. */
- tag = HandleTable->Tag;
- /* Free the table. */
- ExFreePoolWithTag(HandleTable->Table, tag);
- /* Free the descriptor. */
- ExFreePoolWithTag(HandleTable, tag);
-}
-
-/* KphCloseHandle
- *
- * Closes a handle, dereferencing the referenced object.
- */
-NTSTATUS KphCloseHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPH_HANDLE_TABLE_ENTRY entry;
- PVOID object;
-
- if (!KphValidHandle(HandleTable, Handle, &entry))
- return STATUS_INVALID_HANDLE;
-
- /* Save a pointer to the object referenced by the handle. */
- object = entry->Object;
- /* Free the handle. */
- status = KphpFreeHandleEntry(HandleTable, entry);
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Dereference the object. */
- KphDereferenceObject(object);
-
- return status;
-}
-
-/* KphCreateHandle
- *
- * Creates a handle and references an object.
- */
-NTSTATUS KphCreateHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in PVOID Object,
- __out PHANDLE Handle
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPH_HANDLE_TABLE_ENTRY entry;
-
- /* Allocate a handle. */
- status = KphpAllocateHandleEntry(HandleTable, &entry);
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Reference and set the object in the entry. */
- KphReferenceObject(Object);
- entry->Object = Object;
-
- /* Pass the handle back. */
- *Handle = KphGetHandleEntry(entry);
-
- return status;
-}
-
-/* KphReferenceObjectByHandle
- *
- * References an object from a handle.
- */
-NTSTATUS KphReferenceObjectByHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle,
- __in_opt PKPH_OBJECT_TYPE ObjectType,
- __out PVOID *Object
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPH_HANDLE_TABLE_ENTRY entry;
-
- if (!KphValidHandle(HandleTable, Handle, &entry))
- return STATUS_INVALID_HANDLE;
-
- /* Lock the entry. */
- if (!KphLockAllocatedHandleEntry(entry))
- return STATUS_INVALID_HANDLE;
-
- /* Check the type of object if the caller requested us
- * to do that.
- */
- if (ObjectType)
- {
- if (KphGetObjectType(entry->Object) != ObjectType)
- {
- /* Bad type. */
- KphUnlockHandleEntry(entry);
-
- return STATUS_OBJECT_TYPE_MISMATCH;
- }
- }
-
- /* Reference and pass the object back. */
- KphReferenceObject(entry->Object);
- *Object = entry->Object;
-
- KphUnlockHandleEntry(entry);
-
- return status;
-}
-
-/* KphValidHandle
- *
- * Checks if a handle is valid.
- */
-BOOLEAN KphValidHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle,
- __out_opt PKPH_HANDLE_TABLE_ENTRY *Entry
- )
-{
- PKPH_HANDLE_TABLE_ENTRY entry;
- BOOLEAN valid;
-
- entry = KphEntryFromHandle(HandleTable, Handle);
- valid =
- ((ULONG_PTR)entry >= (ULONG_PTR)HandleTable->Table) &&
- ((ULONG_PTR)entry + HandleTable->SizeOfEntry <=
- (ULONG_PTR)HandleTable->Table + HandleTable->TableSize);
-
- if (valid)
- *Entry = entry;
-
- return valid;
-}
-
-/* KphpAllocateHandleEntry
- *
- * Allocates a handle table entry.
- */
-NTSTATUS KphpAllocateHandleEntry(
- __in PKPH_HANDLE_TABLE HandleTable,
- __out PKPH_HANDLE_TABLE_ENTRY *Entry
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPH_HANDLE_TABLE_ENTRY entry = NULL;
-
- /* Prevent others from modifying the handle table. */
- ExAcquireFastMutex(&HandleTable->Mutex);
-
- /* Check the free list first. If we have a free entry,
- * claim it and update the free list. Otherwise, create
- * a new entry from the NextHandle value.
- */
- if (HandleTable->FreeHandle)
- {
- /* We have a free entry. Update the free list. */
- entry = HandleTable->FreeHandle;
- /* The next free entry goes into FreeHandle. */
- HandleTable->FreeHandle = KphGetNextFreeEntry(entry);
- }
- else
- {
- /* No free handles. We have to initialize a new one
- * based on the NextHandle value.
- */
- /* Make sure we don't go past the end of the table. */
- if (
- KphIndexFromHandle(HandleTable->NextHandle) *
- HandleTable->SizeOfEntry <=
- HandleTable->TableSize
- )
- {
- /* Get a pointer to the entry from the handle. */
- entry = KphEntryFromHandle(HandleTable, HandleTable->NextHandle);
- /* Increment the next handle value. */
- HandleTable->NextHandle = KphIncrementHandle(HandleTable->NextHandle);
- }
- else
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
-
- if (NT_SUCCESS(status))
- {
- /* Set the entry's handle value. */
- entry->Handle = KphHandleFromEntry(HandleTable, entry);
- KphSetAllocatedEntry(entry);
-
- *Entry = entry;
- }
-
- ExReleaseFastMutex(&HandleTable->Mutex);
-
- return status;
-}
-
-/* KphpFreeHandleEntry
- *
- * Frees a handle table entry.
- */
-NTSTATUS KphpFreeHandleEntry(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in PKPH_HANDLE_TABLE_ENTRY Entry
- )
-{
- ExAcquireFastMutex(&HandleTable->Mutex);
-
- /* Lock the entry. */
- if (!KphLockAllocatedHandleEntry(Entry))
- {
- /* Someone else has already freed the entry (or it was never allocated). */
- ExReleaseFastMutex(&HandleTable->Mutex);
- return STATUS_INVALID_HANDLE;
- }
-
- /* Mark the entry as unallocated. */
- KphClearAllocatedEntry(Entry);
-
- /* Add the entry to the free list. */
- KphSetNextFreeEntry(Entry, HandleTable->FreeHandle);
- HandleTable->FreeHandle = Entry;
-
- /* Zero the entry (except for the Value). */
- memset(&Entry->Object, 0, HandleTable->SizeOfEntry - sizeof(ULONG_PTR));
-
- /* Unlock the entry. */
- KphUnlockHandleEntry(Entry);
-
- ExReleaseFastMutex(&HandleTable->Mutex);
-
- return STATUS_SUCCESS;
-}
diff --git a/2.x/trunk/KProcessHacker/hook.c b/2.x/trunk/KProcessHacker/hook.c
deleted file mode 100644
index 3f775db5d..000000000
--- a/2.x/trunk/KProcessHacker/hook.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Process Hacker Driver -
- * hooks
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#include "include/hook.h"
-#include "include/sync.h"
-
-static KPH_PROCESSOR_LOCK HookProcessorLock;
-
-/* KphHookInit
- *
- * Initializes the hooking module.
- */
-NTSTATUS KphHookInit()
-{
- KphInitializeProcessorLock(&HookProcessorLock);
-
- return STATUS_SUCCESS;
-}
-
-/* KphInitializeHook
- *
- * Initializes a hook structure.
- */
-VOID KphInitializeHook(
- __out PKPH_HOOK Hook,
- __in PVOID Function,
- __in PVOID Target
- )
-{
- memset(Hook, 0, sizeof(KPH_HOOK));
- Hook->Function = Function;
- Hook->Target = Target;
-}
-
-/* KphHook
- *
- * Hooks a kernel-mode function.
- * WARNING: DO NOT HOOK A FUNCTION THAT IS CALLABLE ABOVE APC_LEVEL.
- *
- * Thread safety: Full
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphHook(
- __inout PKPH_HOOK Hook
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- MAPPED_MDL mappedMdl;
- PUCHAR function;
-
- status = KphpCreateMappedMdl(
- Hook->Function,
- 5,
- &mappedMdl
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- function = (PUCHAR)mappedMdl.Address;
-
- /* Acquire a lock on all other processors. */
- if (KphAcquireProcessorLock(&HookProcessorLock))
- {
- /* Note that this is completely safe even though we are at
- * DISPATCH_LEVEL because we are using the mapped MDL.
- */
- /* Copy the original five bytes (for unhooking). */
- memcpy(Hook->Bytes, function, 10);
- /* Hook the function by writing a jump instruction. */
- Hook->Hooked = TRUE;
- /* jmp Target */
- *function = 0xe9;
- *(PULONG_PTR)(function + 1) = (ULONG_PTR)Hook->Target - (ULONG_PTR)Hook->Function - 5;
-
- /* Release the processor lock. */
- KphReleaseProcessorLock(&HookProcessorLock);
- }
- else
- {
- dprintf("KphHook: Could not acquire processor lock!\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- KphpFreeMappedMdl(&mappedMdl);
-
- return status;
-}
-
-/* KphUnhook
- *
- * Unhooks a kernel-mode function.
- * WARNING: DO NOT UNHOOK A FUNCTION THAT IS CALLABLE ABOVE APC_LEVEL.
- *
- * Thread safety: Full
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphUnhook(
- __inout PKPH_HOOK Hook
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- MAPPED_MDL mappedMdl;
-
- if (!Hook->Hooked)
- return STATUS_UNSUCCESSFUL;
-
- status = KphpCreateMappedMdl(
- Hook->Function,
- 5,
- &mappedMdl
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Acquire a lock on all other processors. */
- if (KphAcquireProcessorLock(&HookProcessorLock))
- {
- /* Unpatch the function. */
- memcpy(mappedMdl.Address, Hook->Bytes, 5);
- Hook->Hooked = FALSE;
- /* Release the processor lock. */
- KphReleaseProcessorLock(&HookProcessorLock);
- }
- else
- {
- dprintf("KphUnhook: Could not acquire processor lock!\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- KphpFreeMappedMdl(&mappedMdl);
-
- return status;
-}
-
-/* KphObOpenCall
- *
- * Calls the original open procedure for an object type.
- *
- * AccessMode: If this argument is unavailable, specify KernelMode.
- */
-NTSTATUS NTAPI KphObOpenCall(
- __in PKPH_OB_OPEN_HOOK ObOpenHook,
- __in OB_OPEN_REASON OpenReason,
- __in KPROCESSOR_MODE AccessMode,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- )
-{
- /* If there wasn't any original open procedure, exit. */
- if (!ObOpenHook->Function)
- return STATUS_SUCCESS;
-
- if (WindowsVersion == WINDOWS_XP)
- {
- return ((OB_OPEN_METHOD_51)ObOpenHook->Function)(
- OpenReason,
- Process,
- Object,
- GrantedAccess,
- HandleCount
- );
- }
- else if (
- WindowsVersion == WINDOWS_VISTA ||
- WindowsVersion == WINDOWS_7
- )
- {
- return ((OB_OPEN_METHOD_60)ObOpenHook->Function)(
- OpenReason,
- AccessMode,
- Process,
- Object,
- GrantedAccess,
- HandleCount
- );
- }
- else
- {
- return STATUS_NOT_SUPPORTED;
- }
-}
-
-/* KphInitializeObOpenHook
- *
- * Initializes a hook structure.
- */
-VOID KphInitializeObOpenHook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook,
- __in POBJECT_TYPE ObjectType,
- __in PVOID Target51,
- __in PVOID Target60
- )
-{
- memset(ObOpenHook, 0, sizeof(KPH_OB_OPEN_HOOK));
- ObOpenHook->ObjectType = ObjectType;
- ObOpenHook->Target51 = Target51;
- ObOpenHook->Target60 = Target60;
-}
-
-/* KphObOpenHook
- *
- * Hooks the open procedure for an object type.
- *
- * Thread safety: Full
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphObOpenHook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- MAPPED_MDL mappedMdl;
- PVOID *openProcedure;
-
- status = KphpCreateMappedMdl(
- KVOFF(ObOpenHook->ObjectType, OffOtiOpenProcedure),
- sizeof(PVOID),
- &mappedMdl
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- openProcedure = (PVOID *)mappedMdl.Address;
-
- /* Acquire a lock on all other processors. */
- if (KphAcquireProcessorLock(&HookProcessorLock))
- {
- /* Save the original open procedure pointer. */
- ObOpenHook->Function = *openProcedure;
-
- /* Choose the correct target open procedure and hook. */
- if (WindowsVersion == WINDOWS_XP)
- {
- if (ObOpenHook->Target51)
- *openProcedure = ObOpenHook->Target51;
- else
- status = STATUS_INVALID_PARAMETER;
- }
- else if (
- WindowsVersion == WINDOWS_VISTA ||
- WindowsVersion == WINDOWS_7
- )
- {
- if (ObOpenHook->Target60)
- *openProcedure = ObOpenHook->Target60;
- else
- status = STATUS_INVALID_PARAMETER;
- }
- else
- {
- status = STATUS_NOT_SUPPORTED;
- }
-
- ObOpenHook->Hooked = TRUE;
-
- /* Release the processor lock. */
- KphReleaseProcessorLock(&HookProcessorLock);
- }
- else
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- KphpFreeMappedMdl(&mappedMdl);
-
- return status;
-}
-
-/* KphObOpenUnhook
- *
- * Unhooks the open procedure for an object type.
- *
- * Thread safety: Full
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphObOpenUnhook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- MAPPED_MDL mappedMdl;
- PVOID *openProcedure;
-
- if (!ObOpenHook->Hooked)
- return STATUS_UNSUCCESSFUL;
-
- status = KphpCreateMappedMdl(
- KVOFF(ObOpenHook->ObjectType, OffOtiOpenProcedure),
- sizeof(PVOID),
- &mappedMdl
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- openProcedure = (PVOID *)mappedMdl.Address;
-
- /* Acquire a lock on all other processors. */
- if (KphAcquireProcessorLock(&HookProcessorLock))
- {
- /* Restore the original open procedure pointer. */
- *openProcedure = ObOpenHook->Function;
- ObOpenHook->Hooked = FALSE;
-
- /* Release the processor lock. */
- KphReleaseProcessorLock(&HookProcessorLock);
- }
- else
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- KphpFreeMappedMdl(&mappedMdl);
-
- return status;
-}
-
-/* KphpCreateMappedMdl
- *
- * Creates and maps a MDL.
- *
- * Thread safety: Full
- * IRQL: Any
- */
-NTSTATUS KphpCreateMappedMdl(
- __in PVOID Address,
- __in ULONG Length,
- __out PMAPPED_MDL MappedMdl
- )
-{
- PMDL mdl;
-
- MappedMdl->Mdl = NULL;
- MappedMdl->Address = NULL;
-
- mdl = IoAllocateMdl(Address, Length, FALSE, FALSE, NULL);
-
- if (mdl == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- MmBuildMdlForNonPagedPool(mdl);
- mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
- MappedMdl->Address = MmMapLockedPagesSpecifyCache(
- mdl,
- KernelMode,
- MmNonCached,
- NULL,
- FALSE,
- HighPagePriority
- );
- MappedMdl->Mdl = mdl;
-
- if (!MappedMdl->Address)
- {
- KphpFreeMappedMdl(MappedMdl);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return STATUS_SUCCESS;
-}
-
-/* KphpFreeMappedMdl
- *
- * Unmaps and frees a MDL.
- *
- * Thread safety: Full
- * IRQL: Any
- */
-VOID KphpFreeMappedMdl(
- __in PMAPPED_MDL MappedMdl
- )
-{
- if (MappedMdl->Mdl != NULL)
- {
- if (MappedMdl->Address != NULL)
- {
- MmUnmapLockedPages(MappedMdl->Address, MappedMdl->Mdl);
- MappedMdl->Address = NULL;
- }
-
- IoFreeMdl(MappedMdl->Mdl);
- MappedMdl->Mdl = NULL;
- }
-}
diff --git a/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys b/2.x/trunk/KProcessHacker/i386/kprocesshacker.sys
index 4788d67ea..7ee2c6349 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/ex.h b/2.x/trunk/KProcessHacker/include/ex.h
index bfd06ccbe..0303ced48 100644
--- a/2.x/trunk/KProcessHacker/include/ex.h
+++ b/2.x/trunk/KProcessHacker/include/ex.h
@@ -23,8 +23,6 @@
#ifndef _EX_H
#define _EX_H
-#include "types.h"
-
/* HACK - version.c dependency */
#define WINDOWS_XP 51
#define WINDOWS_SERVER_2003 52
diff --git a/2.x/trunk/KProcessHacker/include/handle.h b/2.x/trunk/KProcessHacker/include/handle.h
deleted file mode 100644
index 710205b3e..000000000
--- a/2.x/trunk/KProcessHacker/include/handle.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Process Hacker Driver -
- * handle table
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _HANDLE_H
-#define _HANDLE_H
-
-#include "kph.h"
-#include "ref.h"
-
-struct _KPH_HANDLE_TABLE;
-typedef struct _KPH_HANDLE_TABLE *PKPH_HANDLE_TABLE;
-
-typedef struct _KPH_HANDLE_TABLE_ENTRY
-{
- union
- {
- HANDLE Handle;
- ULONG_PTR Value;
- struct _KPH_HANDLE_TABLE_ENTRY *NextFree;
- };
- PVOID Object;
-} KPH_HANDLE_TABLE_ENTRY, *PKPH_HANDLE_TABLE_ENTRY;
-
-NTSTATUS KphCreateHandleTable(
- __out PKPH_HANDLE_TABLE *HandleTable,
- __in ULONG MaximumHandles,
- __in ULONG SizeOfEntry,
- __in ULONG Tag
- );
-
-VOID KphFreeHandleTable(
- __in PKPH_HANDLE_TABLE HandleTable
- );
-
-NTSTATUS KphCloseHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle
- );
-
-NTSTATUS KphCreateHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in PVOID Object,
- __out PHANDLE Handle
- );
-
-NTSTATUS KphReferenceObjectByHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle,
- __in_opt PKPH_OBJECT_TYPE ObjectType,
- __out PVOID *Object
- );
-
-BOOLEAN KphValidHandle(
- __in PKPH_HANDLE_TABLE HandleTable,
- __in HANDLE Handle,
- __out_opt PKPH_HANDLE_TABLE_ENTRY *Entry
- );
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/handlep.h b/2.x/trunk/KProcessHacker/include/handlep.h
deleted file mode 100644
index a6cd445ee..000000000
--- a/2.x/trunk/KProcessHacker/include/handlep.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Process Hacker Driver -
- * handle table
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _HANDLEP_H
-#define _HANDLEP_H
-
-#define _HANDLE_PRIVATE
-#include "handle.h"
-#include "sync.h"
-
-#define KPH_HANDLE_INCREMENT 4
-#define KPH_HANDLE_LOCKED 0x1
-#define KPH_HANDLE_LOCKED_SHIFT 0
-#define KPH_HANDLE_ALLOCATED 0x2
-#define KPH_HANDLE_FLAGS 0x3
-
-#define KphGetFlagsEntry(Entry) ((Entry)->Value & KPH_HANDLE_FLAGS)
-#define KphGetHandleEntry(Entry) ((HANDLE)((Entry)->Value & ~KPH_HANDLE_FLAGS))
-#define KphIncrementHandle(Handle) ((HANDLE)((ULONG_PTR)(Handle) + KPH_HANDLE_INCREMENT))
-
-#define KphIsAllocatedEntry(Entry) ((Entry)->Value & KPH_HANDLE_ALLOCATED)
-#define KphClearAllocatedEntry(Entry) ((Entry)->Value &= ~KPH_HANDLE_ALLOCATED)
-#define KphSetAllocatedEntry(Entry) ((Entry)->Value |= KPH_HANDLE_ALLOCATED)
-
-#define KphGetNextFreeEntry(Entry) ((PKPH_HANDLE_TABLE_ENTRY)((Entry)->Value & ~KPH_HANDLE_FLAGS))
-#define KphSetNextFreeEntry(Entry, NextFree) ((Entry)->Value = ((ULONG_PTR)(NextFree) | KphGetFlagsEntry(Entry)))
-
-#define KphHandleFromIndex(Index) ((HANDLE)((ULONG_PTR)(Index) * KPH_HANDLE_INCREMENT))
-#define KphHandleFromIndexEx(Index, Flags) ((HANDLE)(((Index) * KPH_HANDLE_INCREMENT) | (Flags)))
-#define KphIndexFromHandle(Handle) (((ULONG_PTR)(Handle) & ~KPH_HANDLE_FLAGS) / KPH_HANDLE_INCREMENT)
-
-#define KphEntryFromHandle(HandleTable, Handle) KphEntryFromIndex((HandleTable), KphIndexFromHandle(Handle))
-#define KphEntryFromIndex(HandleTable, Index) \
- ((PKPH_HANDLE_TABLE_ENTRY)((ULONG_PTR)(HandleTable)->Table + (Index) * (HandleTable)->SizeOfEntry))
-#define KphHandleFromEntry(HandleTable, Entry) KphHandleFromIndex(KphIndexFromEntry((HandleTable), (Entry)))
-#define KphHandleFromEntryEx(HandleTable, Entry, Flags) \
- KphHandleFromIndexEx(KphIndexFromEntry((HandleTable), (Entry)), (Flags))
-#define KphIndexFromEntry(HandleTable, Entry) \
- (((ULONG_PTR)(Entry) - (ULONG_PTR)(HandleTable)->Table) / (HandleTable)->SizeOfEntry)
-
-typedef struct _KPH_HANDLE_TABLE
-{
- /* The pool tag used for this descriptor and the table itself. */
- ULONG Tag;
- /* The size of each handle table entry. */
- ULONG SizeOfEntry;
- /* The next handle value to use. */
- HANDLE NextHandle;
- /* The free list of handle table entries. */
- struct _KPH_HANDLE_TABLE_ENTRY *FreeHandle;
-
- /* A fast mutex guarding writes to the handle table. */
- FAST_MUTEX Mutex;
- /* The size of the table, in bytes. */
- ULONG TableSize;
- /* The actual handle table. */
- PVOID Table;
-} KPH_HANDLE_TABLE, *PKPH_HANDLE_TABLE;
-
-FORCEINLINE BOOLEAN KphLockHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- );
-
-FORCEINLINE BOOLEAN KphLockAllocatedHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- );
-
-FORCEINLINE VOID KphUnlockHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- );
-
-/* KphLockHandle
- *
- * Locks a handle table entry for exclusive access. Do not
- * modify the lowest bit of the entry's value while you
- * hold the lock.
- *
- * Return value: TRUE if the entry is allocated, otherwise FALSE.
- */
-FORCEINLINE BOOLEAN KphLockHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- )
-{
- /* Acquire the spinlock. */
- KphAcquireBitSpinLock((PLONG)&Entry->Value, KPH_HANDLE_LOCKED_SHIFT);
-
- /* Return whether the entry is allocated. */
- return !!(Entry->Value & KPH_HANDLE_ALLOCATED);
-}
-
-/* KphLockAllocatedHandle
- *
- * Locks a handle table entry for exclusive access. Do not
- * modify the lowest bit of the entry's value while you
- * hold the lock.
- * The function will not lock the handle if it is unallocated.
- *
- * Return value: TRUE if the entry was locked, otherwise FALSE.
- */
-FORCEINLINE BOOLEAN KphLockAllocatedHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- )
-{
- if (!KphLockHandleEntry(Entry))
- {
- KphUnlockHandleEntry(Entry);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* KphUnlockHandle
- *
- * Unlocks a handle table entry.
- */
-FORCEINLINE VOID KphUnlockHandleEntry(
- __inout PKPH_HANDLE_TABLE_ENTRY Entry
- )
-{
- /* Unlock the spinlock. */
- KphReleaseBitSpinLock((PLONG)&Entry->Value, KPH_HANDLE_LOCKED_SHIFT);
-}
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/hook.h b/2.x/trunk/KProcessHacker/include/hook.h
deleted file mode 100644
index 12ec3d3f9..000000000
--- a/2.x/trunk/KProcessHacker/include/hook.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Process Hacker Driver -
- * hooks
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _HOOK_H
-#define _HOOK_H
-
-#include "kph.h"
-#include "ob.h"
-
-#define KPH_DEFINE_HOOK_CALL(Name, Arguments, Hook) \
- __declspec(naked) Name(Arguments) \
- { \
- __asm lea eax, Hook \
- __asm mov eax, [eax+KPH_HOOK.Function] \
- __asm add eax, 5 \
- __asm push ebp \
- __asm mov ebp, esp \
- __asm jmp eax \
- } \
-
-typedef struct _KPH_HOOK
-{
- /* The address of the hooked function.
- Should NOT be a function that is callable above PASSIVE_LEVEL. */
- PVOID Function;
- /* The address of the new function. */
- PVOID Target;
- /* Whether the function is hooked. */
- BOOLEAN Hooked;
- /* The original first 10 bytes. */
- CHAR Bytes[10];
-} KPH_HOOK, *PKPH_HOOK;
-
-typedef struct _KPH_OB_OPEN_HOOK
-{
- /* The object type that is being hooked. */
- POBJECT_TYPE ObjectType;
- /* The original open procedure. */
- PVOID Function;
- /* The new open procedure for NT 5.1 (XP). */
- OB_OPEN_METHOD_51 Target51;
- /* The new open procedure for NT 6.1 and above (Vista, 7 or higher). */
- OB_OPEN_METHOD_60 Target60;
- /* Whether the open procedure is hooked. */
- BOOLEAN Hooked;
-} KPH_OB_OPEN_HOOK, *PKPH_OB_OPEN_HOOK;
-
-NTSTATUS KphHookInit();
-
-VOID KphInitializeHook(
- __out PKPH_HOOK Hook,
- __in PVOID Function,
- __in PVOID Target
- );
-
-NTSTATUS KphHook(
- __inout PKPH_HOOK Hook
- );
-
-NTSTATUS KphUnhook(
- __inout PKPH_HOOK Hook
- );
-
-NTSTATUS NTAPI KphObOpenCall(
- __in PKPH_OB_OPEN_HOOK ObOpenHook,
- __in OB_OPEN_REASON OpenReason,
- __in KPROCESSOR_MODE AccessMode,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- );
-
-VOID KphInitializeObOpenHook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook,
- __in POBJECT_TYPE ObjectType,
- __in PVOID Target51,
- __in PVOID Target60
- );
-
-NTSTATUS KphObOpenHook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook
- );
-
-NTSTATUS KphObOpenUnhook(
- __inout PKPH_OB_OPEN_HOOK ObOpenHook
- );
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/io.h b/2.x/trunk/KProcessHacker/include/io.h
index bc98fb151..624c27dda 100644
--- a/2.x/trunk/KProcessHacker/include/io.h
+++ b/2.x/trunk/KProcessHacker/include/io.h
@@ -23,8 +23,6 @@
#ifndef _IO_H
#define _IO_H
-#include "types.h"
-
extern POBJECT_TYPE *IoAdapterObjectType;
extern POBJECT_TYPE *IoControllerObjectType;
extern POBJECT_TYPE *IoDeviceHandlerObjectType; /* not used anymore */
diff --git a/2.x/trunk/KProcessHacker/include/ke.h b/2.x/trunk/KProcessHacker/include/ke.h
index 741c1b00b..998a27b96 100644
--- a/2.x/trunk/KProcessHacker/include/ke.h
+++ b/2.x/trunk/KProcessHacker/include/ke.h
@@ -23,8 +23,6 @@
#ifndef _KE_H
#define _KE_H
-#include "types.h"
-
/* APCs */
typedef enum _KAPC_ENVIRONMENT
diff --git a/2.x/trunk/KProcessHacker/include/kph.h b/2.x/trunk/KProcessHacker/include/kph.h
index 99c7a8e8d..dfb8cc7c9 100644
--- a/2.x/trunk/KProcessHacker/include/kph.h
+++ b/2.x/trunk/KProcessHacker/include/kph.h
@@ -23,16 +23,23 @@
#ifndef _KPH_H
#define _KPH_H
-#include "types.h"
+#include
+
#include "debug.h"
#include "ref.h"
+#include "util.h"
#include "version.h"
+#include "ex.h"
+#include "io.h"
#include "ke.h"
#include "mm.h"
+#include "ob.h"
#include "ps.h"
-#include "trace.h"
+#include "se.h"
#include "zw.h"
+
+#include "trace.h"
#define MAX_UINTEGER(Bits) ((1 << (Bits)) - 1)
#define BITS_UCHAR 8
@@ -74,7 +81,6 @@ EXT POBJECT_TYPE *ObDirectoryObjectType EQNULL;
EXT POBJECT_TYPE *ObTypeObjectType EQNULL;
EXT PKSERVICE_TABLE_DESCRIPTOR __KeServiceDescriptorTable EQNULL;
-EXT PVOID __KiFastCallEntry EQNULL;
EXT _NtClose __NtClose EQNULL;
EXT _ObGetObjectType ObGetObjectType EQNULL;
EXT _PsGetProcessJob PsGetProcessJob EQNULL;
@@ -180,8 +186,8 @@ NTSTATUS OpenProcess(
);
NTSTATUS SetProcessToken(
- __in HANDLE sourcePid,
- __in HANDLE targetPid
+ __in HANDLE SourcePid,
+ __in HANDLE TargetPid
);
/* KProcessHacker */
diff --git a/2.x/trunk/KProcessHacker/include/kprocesshacker.h b/2.x/trunk/KProcessHacker/include/kprocesshacker.h
index 0df5a7326..703b074e9 100644
--- a/2.x/trunk/KProcessHacker/include/kprocesshacker.h
+++ b/2.x/trunk/KProcessHacker/include/kprocesshacker.h
@@ -23,11 +23,6 @@
#ifndef KPROCESSHACKER_H
#define KPROCESSHACKER_H
-#include "include/kph.h"
-#include "include/handle.h"
-#include "include/ref.h"
-#include "include/sync.h"
-
/* KPH Configuration */
//#define KPH_REQUIRE_DEBUG_PRIVILEGE
@@ -35,8 +30,8 @@
/* Device */
#define KPH_DEVICE_TYPE (0x9999)
-#define KPH_DEVICE_NAME (L"\\Device\\KProcessHacker")
-#define KPH_DEVICE_DOS_NAME (L"\\DosDevices\\KProcessHacker")
+#define KPH_DEVICE_NAME (L"\\Device\\KProcessHacker2")
+#define KPH_DEVICE_DOS_NAME (L"\\DosDevices\\KProcessHacker2")
/* Features */
@@ -46,63 +41,56 @@
/* Control Codes */
#define KPH_CTL_CODE(x) CTL_CODE(KPH_DEVICE_TYPE, 0x800 + x, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define KPH_CLOSEHANDLE KPH_CTL_CODE(0)
-#define KPH_SSQUERYCLIENTENTRY KPH_CTL_CODE(1)
-#define KPH_RESERVED1 KPH_CTL_CODE(2)
-#define KPH_OPENPROCESS KPH_CTL_CODE(3)
-#define KPH_OPENTHREAD KPH_CTL_CODE(4)
-#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(5)
-#define KPH_GETPROCESSPROTECTED KPH_CTL_CODE(6)
-#define KPH_SETPROCESSPROTECTED KPH_CTL_CODE(7)
-#define KPH_TERMINATEPROCESS KPH_CTL_CODE(8)
-#define KPH_SUSPENDPROCESS KPH_CTL_CODE(9)
-#define KPH_RESUMEPROCESS KPH_CTL_CODE(10)
-#define KPH_READVIRTUALMEMORY KPH_CTL_CODE(11)
-#define KPH_WRITEVIRTUALMEMORY KPH_CTL_CODE(12)
-#define KPH_SETPROCESSTOKEN KPH_CTL_CODE(13)
-#define KPH_GETTHREADSTARTADDRESS KPH_CTL_CODE(14)
-#define KPH_SETHANDLEATTRIBUTES KPH_CTL_CODE(15)
-#define KPH_GETHANDLEOBJECTNAME KPH_CTL_CODE(16)
-#define KPH_OPENPROCESSJOB KPH_CTL_CODE(17)
-#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(18)
-#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(19)
-#define KPH_GETTHREADWIN32THREAD KPH_CTL_CODE(20)
-#define KPH_DUPLICATEOBJECT KPH_CTL_CODE(21)
-#define KPH_ZWQUERYOBJECT KPH_CTL_CODE(22)
-#define KPH_GETPROCESSID KPH_CTL_CODE(23)
-#define KPH_GETTHREADID KPH_CTL_CODE(24)
-#define KPH_TERMINATETHREAD KPH_CTL_CODE(25)
-#define KPH_GETFEATURES KPH_CTL_CODE(26)
-#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(27)
-#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(28)
-#define KPH_PROTECTADD KPH_CTL_CODE(29)
-#define KPH_PROTECTREMOVE KPH_CTL_CODE(30)
-#define KPH_PROTECTQUERY KPH_CTL_CODE(31)
-#define KPH_UNSAFEREADVIRTUALMEMORY KPH_CTL_CODE(32)
-#define KPH_SETEXECUTEOPTIONS KPH_CTL_CODE(33)
-#define KPH_QUERYPROCESSHANDLES KPH_CTL_CODE(34)
-#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(35)
-#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(36)
-#define KPH_DANGEROUSTERMINATETHREAD KPH_CTL_CODE(37)
-#define KPH_OPENTYPE KPH_CTL_CODE(38)
-#define KPH_OPENDRIVER KPH_CTL_CODE(39)
-#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(40)
-#define KPH_OPENDIRECTORYOBJECT KPH_CTL_CODE(41)
-#define KPH_SSREF KPH_CTL_CODE(42)
-#define KPH_SSUNREF KPH_CTL_CODE(43)
-#define KPH_SSCREATECLIENTENTRY KPH_CTL_CODE(44)
-#define KPH_SSCREATERULESETENTRY KPH_CTL_CODE(45)
-#define KPH_SSREMOVERULE KPH_CTL_CODE(46)
-#define KPH_SSADDPROCESSIDRULE KPH_CTL_CODE(47)
-#define KPH_SSADDTHREADIDRULE KPH_CTL_CODE(48)
-#define KPH_SSADDPREVIOUSMODERULE KPH_CTL_CODE(49)
-#define KPH_SSADDNUMBERRULE KPH_CTL_CODE(50)
-#define KPH_SSENABLECLIENTENTRY KPH_CTL_CODE(51)
-#define KPH_OPENNAMEDOBJECT KPH_CTL_CODE(52)
-#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(53)
-#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(54)
-#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(55)
-#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(56)
+
+/* General */
+#define KPH_GETFEATURES KPH_CTL_CODE(0)
+
+/* Processes */
+#define KPH_OPENPROCESS KPH_CTL_CODE(50)
+#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(51)
+#define KPH_OPENPROCESSJOB KPH_CTL_CODE(52)
+#define KPH_SUSPENDPROCESS KPH_CTL_CODE(53)
+#define KPH_RESUMEPROCESS KPH_CTL_CODE(54)
+#define KPH_TERMINATEPROCESS KPH_CTL_CODE(55)
+#define KPH_READVIRTUALMEMORY KPH_CTL_CODE(56)
+#define KPH_WRITEVIRTUALMEMORY KPH_CTL_CODE(57)
+#define KPH_UNSAFEREADVIRTUALMEMORY KPH_CTL_CODE(58)
+#define KPH_GETPROCESSPROTECTED KPH_CTL_CODE(59)
+#define KPH_SETPROCESSPROTECTED KPH_CTL_CODE(60)
+#define KPH_SETEXECUTEOPTIONS KPH_CTL_CODE(61)
+#define KPH_SETPROCESSTOKEN KPH_CTL_CODE(62)
+#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(63)
+#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(64)
+#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(65)
+#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(66)
+
+/* Threads */
+#define KPH_OPENTHREAD KPH_CTL_CODE(100)
+#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(101)
+#define KPH_TERMINATETHREAD KPH_CTL_CODE(102)
+#define KPH_DANGEROUSTERMINATETHREAD KPH_CTL_CODE(103)
+#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(104)
+#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(105)
+#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(106)
+#define KPH_GETTHREADWIN32THREAD KPH_CTL_CODE(107)
+#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(108)
+
+/* Handles */
+#define KPH_QUERYPROCESSHANDLES KPH_CTL_CODE(150)
+#define KPH_GETHANDLEOBJECTNAME KPH_CTL_CODE(151)
+#define KPH_ZWQUERYOBJECT KPH_CTL_CODE(152)
+#define KPH_DUPLICATEOBJECT KPH_CTL_CODE(153)
+#define KPH_SETHANDLEATTRIBUTES KPH_CTL_CODE(154)
+#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(155)
+#define KPH_GETPROCESSID KPH_CTL_CODE(156)
+#define KPH_GETTHREADID KPH_CTL_CODE(157)
+
+/* Objects */
+#define KPH_OPENNAMEDOBJECT KPH_CTL_CODE(200)
+#define KPH_OPENDIRECTORYOBJECT KPH_CTL_CODE(201)
+#define KPH_OPENDRIVER KPH_CTL_CODE(202)
+#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(203)
+#define KPH_OPENTYPE KPH_CTL_CODE(204)
/* Standard Driver Routines */
@@ -114,57 +102,4 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphUnsupported(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-/* Clients */
-
-#define TAG_CLIENT_HANDLETABLE ('HChP')
-#define KPH_CLIENT_SSMAXCOUNT 1000
-#define KPH_CLIENT_MAXHANDLES 100
-
-typedef struct _KPH_CLIENT_ENTRY
-{
- LIST_ENTRY ClientListEntry;
- HANDLE ProcessId;
- PKPH_HANDLE_TABLE HandleTable;
-
- KPH_GUARDED_LOCK SsLock;
- /* The number of times the client has "started" the system service logger. */
- LONG SsStartCount;
-} KPH_CLIENT_ENTRY, *PKPH_CLIENT_ENTRY;
-
-/* Functions */
-
-VOID SsRef(LONG count);
-VOID SsUnref(LONG count);
-
-VOID NTAPI ClientEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- );
-
-PKPH_CLIENT_ENTRY CreateClientEntry(
- __in HANDLE ProcessId
- );
-
-PKPH_CLIENT_ENTRY ReferenceClientEntry(
- __in_opt HANDLE ProcessId
- );
-
-NTSTATUS CloseClientHandle(
- __in_opt HANDLE ProcessId,
- __in HANDLE Handle
- );
-
-NTSTATUS CreateClientHandle(
- __in_opt HANDLE ProcessId,
- __in PVOID Object,
- __out PHANDLE Handle
- );
-
-NTSTATUS ReferenceClientHandle(
- __in_opt HANDLE ProcessId,
- __in HANDLE Handle,
- __in PKPH_OBJECT_TYPE ObjectType,
- __out PVOID *Object
- );
-
#endif
\ No newline at end of file
diff --git a/2.x/trunk/KProcessHacker/include/ob.h b/2.x/trunk/KProcessHacker/include/ob.h
index 783629c12..6b1c3f4c7 100644
--- a/2.x/trunk/KProcessHacker/include/ob.h
+++ b/2.x/trunk/KProcessHacker/include/ob.h
@@ -23,9 +23,6 @@
#ifndef _OB_H
#define _OB_H
-#include "types.h"
-#include "ex.h"
-
#define OBJECT_TO_OBJECT_HEADER(o) \
CONTAINING_RECORD((o), OBJECT_HEADER, Body)
diff --git a/2.x/trunk/KProcessHacker/include/protect.h b/2.x/trunk/KProcessHacker/include/protect.h
deleted file mode 100644
index b714ab1b0..000000000
--- a/2.x/trunk/KProcessHacker/include/protect.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Process Hacker Driver -
- * process protection
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _PROTECT_H
-#define _PROTECT_H
-
-#include "hook.h"
-
-#define TAG_PROTECTION_ENTRY ('rPhP')
-
-#define OBOPENOBJECTBYPOINTER_ARGS \
- PVOID Object, \
- ULONG HandleAttributes, \
- PACCESS_STATE PassedAccessState, \
- ACCESS_MASK DesiredAccess, \
- POBJECT_TYPE ObjectType, \
- KPROCESSOR_MODE AccessMode, \
- PHANDLE Handle
-
-typedef struct _KPH_PROCESS_ENTRY
-{
- LIST_ENTRY ListEntry;
- PEPROCESS Process;
- PEPROCESS CreatorProcess;
- HANDLE Tag;
- LOGICAL AllowKernelMode;
- ACCESS_MASK ProcessAllowMask;
- ACCESS_MASK ThreadAllowMask;
-} KPH_PROCESS_ENTRY, *PKPH_PROCESS_ENTRY;
-
-NTSTATUS NTAPI KphNewObOpenObjectByPointer(OBOPENOBJECTBYPOINTER_ARGS);
-NTSTATUS NTAPI KphOldObOpenObjectByPointer(OBOPENOBJECTBYPOINTER_ARGS);
-
-NTSTATUS NTAPI KphNewOpenProcedure51(
- __in OB_OPEN_REASON OpenReason,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- );
-
-NTSTATUS NTAPI KphNewOpenProcedure60(
- __in OB_OPEN_REASON OpenReason,
- __in KPROCESSOR_MODE AccessMode,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- );
-
-NTSTATUS KphProtectInit();
-NTSTATUS KphProtectDeinit();
-
-PKPH_PROCESS_ENTRY KphProtectAddEntry(
- __in PEPROCESS Process,
- __in HANDLE Tag,
- __in LOGICAL AllowKernelMode,
- __in ACCESS_MASK ProcessAllowMask,
- __in ACCESS_MASK ThreadAllowMask
- );
-
-PKPH_PROCESS_ENTRY KphProtectFindEntry(
- __in PEPROCESS Process,
- __in HANDLE Tag,
- __out_opt PKPH_PROCESS_ENTRY ProcessEntryCopy
- );
-
-BOOLEAN KphProtectRemoveByProcess(
- __in PEPROCESS Process
- );
-
-ULONG KphProtectRemoveByTag(
- __in HANDLE Tag
- );
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/ps.h b/2.x/trunk/KProcessHacker/include/ps.h
index 62b7309f2..4dc365d4e 100644
--- a/2.x/trunk/KProcessHacker/include/ps.h
+++ b/2.x/trunk/KProcessHacker/include/ps.h
@@ -23,12 +23,6 @@
#ifndef _PS_H
#define _PS_H
-#include "types.h"
-#include "ex.h"
-#include "mm.h"
-#include "ob.h"
-#include "se.h"
-
#define TAG_CAPTURE_STACK_BACKTRACE ('tShP')
#define PROCESS_TERMINATE (0x0001)
diff --git a/2.x/trunk/KProcessHacker/include/ref.h b/2.x/trunk/KProcessHacker/include/ref.h
index 03f9fdb9e..b27a51321 100644
--- a/2.x/trunk/KProcessHacker/include/ref.h
+++ b/2.x/trunk/KProcessHacker/include/ref.h
@@ -23,8 +23,6 @@
#ifndef _REF_H
#define _REF_H
-#include "kph.h"
-
/* Object flags */
#define KPHOBJ_RAISE_ON_FAIL 0x00000001
#define KPHOBJ_PAGED_POOL 0x00000002
diff --git a/2.x/trunk/KProcessHacker/include/refp.h b/2.x/trunk/KProcessHacker/include/refp.h
index d31fa034e..e60784fb5 100644
--- a/2.x/trunk/KProcessHacker/include/refp.h
+++ b/2.x/trunk/KProcessHacker/include/refp.h
@@ -23,10 +23,6 @@
#ifndef _REFP_H
#define _REFP_H
-#define _REF_PRIVATE
-#include "ref.h"
-#include "sync.h"
-
#define TAG_KPHOBJ ('bOhP')
#define KphObjectToObjectHeader(Object) ((PKPH_OBJECT_HEADER)CONTAINING_RECORD((PCHAR)(Object), KPH_OBJECT_HEADER, Body))
diff --git a/2.x/trunk/KProcessHacker/include/se.h b/2.x/trunk/KProcessHacker/include/se.h
index 947d59f5f..a8be47d1e 100644
--- a/2.x/trunk/KProcessHacker/include/se.h
+++ b/2.x/trunk/KProcessHacker/include/se.h
@@ -23,12 +23,14 @@
#ifndef _SE_H
#define _SE_H
-#include "types.h"
-
extern POBJECT_TYPE *SeTokenObjectType;
+#ifdef _X86_
/* Was 0x38 on Vista, appears to be 0xc8 on 7. */
#define AUX_ACCESS_DATA_SIZE (0xc8)
+#else
+#define AUX_ACCESS_DATA_SIZE (0xe0)
+#endif
typedef PVOID PAUX_ACCESS_DATA;
diff --git a/2.x/trunk/KProcessHacker/include/sync.h b/2.x/trunk/KProcessHacker/include/sync.h
deleted file mode 100644
index e344ea75e..000000000
--- a/2.x/trunk/KProcessHacker/include/sync.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Process Hacker Driver -
- * synchronization code
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _SYNC_H
-#define _SYNC_H
-
-#include "kph.h"
-#include "ex.h"
-
-/* General synchronization macros */
-
-/* KphEqualSpin
- *
- * Spins until the first value is equal to the second
- * value.
- */
-FORCEINLINE VOID KphSpinUntilEqual(
- __inout PLONG Value,
- __in LONG Value2
- )
-{
- while (InterlockedCompareExchange(
- Value,
- Value2,
- Value2
- ) != Value2)
- YieldProcessor();
-}
-
-/* KphNotEqualSpin
- *
- * Spins until the first value is not equal to the second
- * value.
- */
-FORCEINLINE VOID KphSpinUntilNotEqual(
- __inout PLONG Value,
- __in LONG Value2
- )
-{
- while (InterlockedCompareExchange(
- Value,
- Value2,
- Value2
- ) == Value2)
- YieldProcessor();
-}
-
-/* Spin Locks */
-
-/* KphAcquireBitSpinLock
- *
- * Uses the specified bit as a spinlock and acquires the
- * lock in the given value.
- */
-FORCEINLINE VOID KphAcquireBitSpinLock(
- __inout PLONG Value,
- __in LONG Bit
- )
-{
- while (InterlockedBitTestAndSet(Value, Bit))
- YieldProcessor();
-}
-
-/* KphReleaseBitSpinLock
- *
- * Uses the specified bit as a spinlock and releases the
- * lock in the given value.
- */
-FORCEINLINE VOID KphReleaseBitSpinLock(
- __inout PLONG Value,
- __in LONG Bit
- )
-{
- InterlockedBitTestAndReset(Value, Bit);
-}
-
-/* Guarded Locks */
-/* Guarded locks are small spinlocks. Code within
- * synchronized regions run at APC_LEVEL. They also contain
- * a signal which can used to implement rundown routines.
- */
-
-#define KPH_GUARDED_LOCK_ACTIVE 0x80000000
-#define KPH_GUARDED_LOCK_ACTIVE_SHIFT 31
-#define KPH_GUARDED_LOCK_SIGNALED 0x40000000
-#define KPH_GUARDED_LOCK_SIGNALED_SHIFT 30
-#define KPH_GUARDED_LOCK_FLAGS 0xc0000000
-
-typedef struct _KPH_GUARDED_LOCK
-{
- LONG Value;
-} KPH_GUARDED_LOCK, *PKPH_GUARDED_LOCK;
-
-#define KphAcquireGuardedLock KphfAcquireGuardedLock
-VOID FASTCALL KphfAcquireGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- );
-
-#define KphReleaseGuardedLock KphfReleaseGuardedLock
-VOID FASTCALL KphfReleaseGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- );
-
-/* KphInitializeGuardedLock
- *
- * Initializes a guarded lock.
- *
- * IRQL: Any
- */
-FORCEINLINE VOID KphInitializeGuardedLock(
- __out PKPH_GUARDED_LOCK Lock,
- __in BOOLEAN Signaled
- )
-{
- Lock->Value = 0;
-
- if (Signaled)
- Lock->Value |= KPH_GUARDED_LOCK_SIGNALED;
-}
-
-/* KphClearGuardedLock
- *
- * Clears the signal state of a guarded lock, assuming
- * that the current thread has acquired it.
- *
- * IRQL: Any
- */
-FORCEINLINE VOID KphClearGuardedLock(
- __in PKPH_GUARDED_LOCK Lock
- )
-{
- Lock->Value &= ~KPH_GUARDED_LOCK_SIGNALED;
-}
-
-/* KphSignalGuardedLock
- *
- * Signals a guarded lock.
- *
- * IRQL: Any
- */
-FORCEINLINE VOID KphSignalGuardedLock(
- __in PKPH_GUARDED_LOCK Lock
- )
-{
- Lock->Value |= KPH_GUARDED_LOCK_SIGNALED;
-}
-
-/* KphSignaledGuardedLock
- *
- * Determines whether a guarded lock is signaled.
- *
- * IRQL: Any
- */
-FORCEINLINE BOOLEAN KphSignaledGuardedLock(
- __in PKPH_GUARDED_LOCK Lock
- )
-{
- return !!(Lock->Value & KPH_GUARDED_LOCK_SIGNALED);
-}
-
-/* KphAcquireAndClearGuardedLock
- *
- * Acquires a guarded lock, clear its signal, and raises the IRQL to APC_LEVEL.
- *
- * IRQL: <= APC_LEVEL
- */
-FORCEINLINE VOID KphAcquireAndClearGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphAcquireGuardedLock(Lock);
- KphClearGuardedLock(Lock);
-}
-
-/* KphAcquireAndSignalGuardedLock
- *
- * Acquires a guarded lock, signals it, and raises the IRQL to APC_LEVEL.
- *
- * IRQL: <= APC_LEVEL
- */
-FORCEINLINE VOID KphAcquireAndSignalGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphAcquireGuardedLock(Lock);
- KphSignalGuardedLock(Lock);
-}
-
-/* KphAcquireNonSignaledGuardedLock
- *
- * Acquires a guarded lock and raises the IRQL to APC_LEVEL,
- * making sure the lock is not signaled. If it is, the
- * lock is not acquired.
- *
- * Return value: whether the lock was acquired.
- * IRQL: <= APC_LEVEL
- */
-FORCEINLINE BOOLEAN KphAcquireNonSignaledGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphAcquireGuardedLock(Lock);
-
- if (Lock->Value & KPH_GUARDED_LOCK_SIGNALED)
- {
- KphReleaseGuardedLock(Lock);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* KphAcquireSignaledGuardedLock
- *
- * Acquires a guarded lock and raises the IRQL to APC_LEVEL,
- * making sure the lock is signaled. If it is not, the
- * lock is not acquired.
- *
- * Return value: whether the lock was acquired.
- * IRQL: <= APC_LEVEL
- */
-FORCEINLINE BOOLEAN KphAcquireSignaledGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphAcquireGuardedLock(Lock);
-
- if (!(Lock->Value & KPH_GUARDED_LOCK_SIGNALED))
- {
- KphReleaseGuardedLock(Lock);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* KphReleaseAndClearGuardedLock
- *
- * Releases a guarded lock, clears its signal, and restores the old IRQL.
- *
- * IRQL: >= APC_LEVEL
- */
-FORCEINLINE VOID KphReleaseAndClearGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphClearGuardedLock(Lock);
- KphReleaseGuardedLock(Lock);
-}
-
-/* KphReleaseAndSignalGuardedLock
- *
- * Releases a guarded lock, signals it, and restores the old IRQL.
- *
- * IRQL: >= APC_LEVEL
- */
-FORCEINLINE VOID KphReleaseAndSignalGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KphSignalGuardedLock(Lock);
- KphReleaseGuardedLock(Lock);
-}
-
-/* Processor Locks */
-/* Processor locks prevent code from executing on all other
- * processors. Code within synchronized regions run at
- * DISPATCH_LEVEL.
- */
-
-#define TAG_SYNC_DPC ('DShP')
-
-typedef struct _KPH_PROCESSOR_LOCK
-{
- /* Synchronizes access to the processor lock. */
- KPH_GUARDED_LOCK Lock;
- /* Storage allocated for DPCs. */
- PKDPC Dpcs;
- /* The number of currently acquired processors. */
- LONG AcquiredProcessors;
- /* The signal for acquired processors to be released. */
- LONG ReleaseSignal;
- /* The old IRQL. */
- KIRQL OldIrql;
- /* Whether the processor lock has been acquired. */
- BOOLEAN Acquired;
-} KPH_PROCESSOR_LOCK, *PKPH_PROCESSOR_LOCK;
-
-BOOLEAN KphAcquireProcessorLock(
- __inout PKPH_PROCESSOR_LOCK ProcessorLock
- );
-
-VOID KphInitializeProcessorLock(
- __out PKPH_PROCESSOR_LOCK ProcessorLock
- );
-
-VOID KphReleaseProcessorLock(
- __inout PKPH_PROCESSOR_LOCK ProcessorLock
- );
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/sysservice.h b/2.x/trunk/KProcessHacker/include/sysservice.h
deleted file mode 100644
index 787847c33..000000000
--- a/2.x/trunk/KProcessHacker/include/sysservice.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Process Hacker Driver -
- * system service logging
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _SYSSERVICE_H
-#define _SYSSERVICE_H
-
-#include "kph.h"
-#include "sysservicedata.h"
-
-/* Define opaque object types */
-
-struct _KPHSS_CLIENT_ENTRY;
-typedef struct _KPHSS_CLIENT_ENTRY *PKPHSS_CLIENT_ENTRY;
-struct _KPHSS_RULESET_ENTRY;
-typedef struct _KPHSS_RULESET_ENTRY *PKPHSS_RULESET_ENTRY;
-struct _KPHSS_RULE_ENTRY;
-typedef struct _KPHSS_RULE_ENTRY *PKPHSS_RULE_ENTRY;
-
-/* Information types */
-
-typedef struct _KPHSS_CLIENT_INFORMATION
-{
- HANDLE ProcessId;
- PVOID BufferBase;
- ULONG BufferSize;
-
- ULONG NumberOfBlocksWritten;
- ULONG NumberOfBlocksDropped;
-} KPHSS_CLIENT_INFORMATION, *PKPHSS_CLIENT_INFORMATION;
-
-/* Object types */
-
-#ifndef _SYSSERVICE_PRIVATE
-extern PKPH_OBJECT_TYPE KphSsClientEntryType;
-extern PKPH_OBJECT_TYPE KphSsRuleSetEntryType;
-extern PKPH_OBJECT_TYPE KphSsRuleEntryType;
-#endif
-
-/* Ruleset types */
-
-typedef enum _KPHSS_RULESET_ACTION
-{
- LogRuleSetAction,
- MaxRuleSetAction
-} KPHSS_RULESET_ACTION;
-
-/* Rule types */
-
-typedef enum _KPHSS_FILTER_TYPE
-{
- IncludeFilterType,
- ExcludeFilterType,
- MaxFilterType
-} KPHSS_FILTER_TYPE;
-
-typedef enum _KPHSS_RULE_TYPE
-{
- ProcessIdRuleType = 0,
- ThreadIdRuleType,
- PreviousModeRuleType,
- NumberRuleType,
- MaxRuleType
-} KPHSS_RULE_TYPE;
-
-/* Block types */
-
-#define KPHSS_BLOCK_SUCCESS(Status) (NT_SUCCESS(Status) && (Status) != STATUS_TIMEOUT)
-
-typedef enum _KPHSS_BLOCK_TYPE
-{
- ResetBlockType,
- EventBlockType,
- ArgumentBlockType,
- ProcessBlockType,
- ModuleBlockType
-} KPHSS_BLOCK_TYPE;
-
-typedef struct _KPHSS_BLOCK_HEADER
-{
- USHORT Size; /* a.k.a. NextEntryOffset */
- USHORT Type;
-} KPHSS_BLOCK_HEADER, *PKPHSS_BLOCK_HEADER;
-
-typedef struct _KPHSS_RESET_BLOCK
-{
- KPHSS_BLOCK_HEADER Header;
-} KPHSS_RESET_BLOCK, *PKPHSS_RESET_BLOCK;
-
-#define TAG_EVENT_BLOCK ('BEhP')
-
-#define KPHSS_EVENT_PROBE_ARGUMENTS_FAILED 0x00000001
-#define KPHSS_EVENT_COPY_ARGUMENTS_FAILED 0x00000002
-#define KPHSS_EVENT_KERNEL_MODE 0x00000004
-#define KPHSS_EVENT_USER_MODE 0x00000008
-
-typedef struct _KPHSS_EVENT_BLOCK
-{
- KPHSS_BLOCK_HEADER Header;
- USHORT Flags;
- LARGE_INTEGER Time;
- CLIENT_ID ClientId;
-
- /* The system service number. */
- ULONG Number;
- /* The number of ULONG arguments to the system service. */
- USHORT NumberOfArguments;
- USHORT ArgumentsOffset; /* ULONG[] */
-
- /* The number of PVOIDs in the trace. */
- USHORT TraceCount;
- USHORT TraceOffset; /* PVOID[] */
-} KPHSS_EVENT_BLOCK, *PKPHSS_EVENT_BLOCK;
-
-/* Argument Blocks
- *
- * These blocks provide additional information about
- * arguments.
- */
-
-#define TAG_ARGUMENT_BLOCK ('BAhP')
-
-#define KPHSS_ARGUMENT_BLOCK_OVERHEAD \
- FIELD_OFFSET(KPHSS_ARGUMENT_BLOCK, Normal)
-#define KPHSS_ARGUMENT_BLOCK_SIZE(InnerSize) \
- (KPHSS_ARGUMENT_BLOCK_OVERHEAD + (InnerSize))
-
-typedef struct _KPHSS_ARGUMENT_BLOCK
-{
- KPHSS_BLOCK_HEADER Header;
- UCHAR Index;
- UCHAR Type; /* KPHSS_ARGUMENT_TYPE */
-
- union
- {
- ULONG Normal;
-
- LARGE_INTEGER Simple;
- KPHSS_HANDLE Handle;
- KPHSS_STRING String;
- KPHSS_WSTRING WString;
- KPHSS_ANSI_STRING AnsiString;
- KPHSS_UNICODE_STRING UnicodeString;
- KPHSS_OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId;
- CONTEXT Context;
- KPHSS_INITIAL_TEB InitialTeb;
- GUID Guid;
- KPHSS_BYTES Bytes;
- };
-} KPHSS_ARGUMENT_BLOCK, *PKPHSS_ARGUMENT_BLOCK;
-
-/* Process Blocks
- *
- * These blocks notify the client of a new process.
- */
-
-#define TAG_PROCESS_BLOCK ('BPhP')
-
-typedef struct _KPHSS_PROCESS_BLOCK
-{
- KPHSS_BLOCK_HEADER Header;
-
- HANDLE ProcessId;
- USHORT NameOffset; /* KPHSS_WSTRING */
- USHORT ImageFileNameOffset; /* KPHSS_WSTRING */
-} KPHSS_PROCESS_BLOCK, *PKPHSS_PROCESS_BLOCK;
-
-/* Module Blocks
- *
- * These blocks provide information about modules
- * loaded by a process.
- */
-
-#define TAG_MODULE_BLOCK ('BMhP')
-
-typedef struct _KPHSS_MODULE_BLOCK
-{
- KPHSS_BLOCK_HEADER Header;
-
- HANDLE ProcessId;
- PVOID ModuleBase;
- ULONG ModuleSize;
- USHORT FileNameOffset; /* KPHSS_WSTRING */
-} KPHSS_MODULE_BLOCK, *PKPHSS_MODULE_BLOCK;
-
-/* Functions */
-
-NTSTATUS KphSsLogInit();
-NTSTATUS KphSsLogDeinit();
-NTSTATUS KphSsLogStart();
-NTSTATUS KphSsLogStop();
-
-NTSTATUS KphSsCreateClientEntry(
- __out PKPHSS_CLIENT_ENTRY *ClientEntry,
- __in HANDLE ProcessHandle,
- __in HANDLE ReadSemaphoreHandle,
- __in HANDLE WriteSemaphoreHandle,
- __in PVOID BufferBase,
- __in ULONG BufferSize,
- __in KPROCESSOR_MODE AccessMode
- );
-
-NTSTATUS KphSsEnableClientEntry(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in BOOLEAN Enable
- );
-
-NTSTATUS KphSsQueryClientEntry(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __out_bcount_opt(ClientInformationLength) PKPHSS_CLIENT_INFORMATION ClientInformation,
- __in ULONG ClientInformationLength,
- __out_opt PULONG ReturnLength,
- __in KPROCESSOR_MODE AccessMode
- );
-
-NTSTATUS KphSsCreateRuleSetEntry(
- __out PKPHSS_RULESET_ENTRY *RuleSetEntry,
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in KPHSS_FILTER_TYPE DefaultFilterType,
- __in KPHSS_RULESET_ACTION Action
- );
-
-HANDLE KphSsGetHandleRule(
- __in PKPHSS_RULE_ENTRY RuleEntry
- );
-
-NTSTATUS KphSsRemoveRule(
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in HANDLE RuleEntryHandle
- );
-
-NTSTATUS KphSsAddProcessIdRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in HANDLE ProcessId
- );
-
-NTSTATUS KphSsAddThreadIdRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in HANDLE ThreadId
- );
-
-NTSTATUS KphSsAddPreviousModeRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphSsAddNumberRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in ULONG Number
- );
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/sysservicedata.h b/2.x/trunk/KProcessHacker/include/sysservicedata.h
deleted file mode 100644
index a2553c33c..000000000
--- a/2.x/trunk/KProcessHacker/include/sysservicedata.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Process Hacker Driver -
- * system service logging (data)
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _SYSSERVICEDATA_H
-#define _SYSSERVICEDATA_H
-
-#include "kph.h"
-
-#define TAG_CALL_ENTRY ('cShP')
-
-typedef enum _KPHSS_ARGUMENT_TYPE
-{
- /* Having argument info for out variables is very rare
- * because usually the caller does not fill in anything
- * in the variable. In some cases, however, the caller
- * does specify a length (usually Length, or MaximumLength).
- *
- * Note that with the exception of a few types such as
- * HANDLE, all types listed here are POINTER TYPES
- * (although a handle is the size of a pointer). This
- * is because non-pointer arguments are already recorded
- * in the event block.
- */
-
- /* Anything passed by value */
- NormalArgument = 0,
-
- /* PBOOLEAN */
- Int8Argument,
- /* P(U)SHORT */
- Int16Argument,
- /* P(U)LONG */
- Int32Argument,
- /* P(U)LARGE_INTEGER */
- Int64Argument,
- /* HANDLE */
- /* Only object manager handles, no fake handles. */
- HandleArgument,
- /* PSTR */
- StringArgument,
- /* PWSTR */
- WStringArgument,
- /* PANSI_STRING */
- AnsiStringArgument,
- /* PUNICODE_STRING */
- UnicodeStringArgument,
- /* POBJECT_ATTRIBUTES */
- ObjectAttributesArgument,
- /* PCLIENT_ID */
- ClientIdArgument,
- /* PCONTEXT */
- ContextArgument,
- /* PINITIAL_TEB */
- InitialTebArgument,
- /* PGUID */
- GuidArgument,
- /* PVOID */
- BytesArgument
-} KPHSS_ARGUMENT_TYPE;
-
-typedef struct _KPHSS_HANDLE
-{
- CLIENT_ID ClientId;
- USHORT TypeNameOffset; /* KPHSS_WSTRING */
- USHORT NameOffset; /* KPHSS_WSTRING */
-} KPHSS_HANDLE, *PKPHSS_HANDLE;
-
-typedef struct _KPHSS_STRING
-{
- USHORT Length;
- CHAR Buffer[1];
-} KPHSS_STRING, *PKPHSS_STRING;
-
-typedef struct _KPHSS_WSTRING
-{
- USHORT Length;
- WCHAR Buffer[1];
-} KPHSS_WSTRING, *PKPHSS_WSTRING;
-
-typedef struct _KPHSS_ANSI_STRING
-{
- USHORT Length;
- USHORT MaximumLength;
- PSTR Pointer;
- CHAR Buffer[1];
-} KPHSS_ANSI_STRING, *PKPHSS_ANSI_STRING;
-
-typedef struct _KPHSS_UNICODE_STRING
-{
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Pointer;
- WCHAR Buffer[1];
-} KPHSS_UNICODE_STRING, *PKPHSS_UNICODE_STRING;
-
-typedef struct _KPHSS_OBJECT_ATTRIBUTES
-{
- union
- {
- OBJECT_ATTRIBUTES ObjectAttributes;
- struct
- {
- ULONG Length;
- HANDLE RootDirectory;
- PUNICODE_STRING ObjectName;
- ULONG Attributes;
- PVOID SecurityDescriptor;
- PVOID SecurityQualityOfService;
- };
- };
-
- USHORT RootDirectoryOffset; /* KPHSS_HANDLE */
- USHORT ObjectNameOffset; /* KPHSS_UNICODE_STRING */
-} KPHSS_OBJECT_ATTRIBUTES, *PKPHSS_OBJECT_ATTRIBUTES;
-
-typedef struct _KPHSS_INITIAL_TEB
-{
- struct
- {
- PVOID OldStackBase;
- PVOID OldStackLimit;
- } OldInitialTeb;
- PVOID StackBase;
- PVOID StackLimit;
- PVOID StackAllocationBase;
-} KPHSS_INITIAL_TEB, *PKPHSS_INITIAL_TEB;
-
-typedef struct _KPHSS_BYTES
-{
- USHORT Length;
- CHAR Buffer[1];
-} KPHSS_BYTES, *PKPHSS_BYTES;
-
-#ifndef _SYSSERVICEDATA_PRIVATE
-extern RTL_GENERIC_TABLE KphSsCallTable;
-#endif
-
-#define KPHSS_MAXIMUM_ARGUMENT_BLOCKS 20
-
-typedef struct _KPHSS_CALL_ENTRY
-{
- PULONG Number;
- PSTR Name;
- ULONG NumberOfArguments;
- KPHSS_ARGUMENT_TYPE Arguments[KPHSS_MAXIMUM_ARGUMENT_BLOCKS];
-} KPHSS_CALL_ENTRY, *PKPHSS_CALL_ENTRY;
-
-VOID KphSsDataInit();
-VOID KphSsDataDeinit();
-
-PKPHSS_CALL_ENTRY KphSsLookupCallEntry(
- __in ULONG Number
- );
-
-#endif
\ No newline at end of file
diff --git a/2.x/trunk/KProcessHacker/include/sysservicep.h b/2.x/trunk/KProcessHacker/include/sysservicep.h
deleted file mode 100644
index 5b7e0c133..000000000
--- a/2.x/trunk/KProcessHacker/include/sysservicep.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Process Hacker Driver -
- * system service logging
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#ifndef _SYSSERVICEP_H
-#define _SYSSERVICEP_H
-
-#define _SYSSERVICE_PRIVATE
-#include "sysservice.h"
-#include "ex.h"
-#include "ref.h"
-
-/* PKPHPSS_KIFASTCALLENTRYPROC
- *
- * Represents a function called by KphpSsNewKiFastCallEntry.
- */
-typedef VOID (NTAPI *PKPHPSS_KIFASTCALLENTRYPROC)(
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments,
- __in PKSERVICE_TABLE_DESCRIPTOR ServiceTable,
- __in PKTHREAD Thread
- );
-
-/* Client entries
- *
- * Client entries describe a process and a circular buffer which
- * receives logging events.
- */
-
-typedef struct _KPHSS_CLIENT_ENTRY
-{
- PEPROCESS Process;
- BOOLEAN Enabled;
-
- /* Buffer */
- PKSEMAPHORE ReadSemaphore;
- PKSEMAPHORE WriteSemaphore;
- FAST_MUTEX BufferMutex;
- PVOID BufferBase;
- ULONG BufferSize;
- ULONG BufferCursor;
-
- /* Statistics */
- ULONG NumberOfBlocksWritten; /* excludes reset blocks */
- ULONG NumberOfBlocksDropped;
-} KPHSS_CLIENT_ENTRY, *PKPHSS_CLIENT_ENTRY;
-
-/* Rulesets
- *
- * Rulesets contain a list of rules and an action to take if a
- * system service matches the set of rules.
- */
-
-#define KPHSS_RULESET_ENTRY(ListEntry) \
- CONTAINING_RECORD((ListEntry), KPHSS_RULESET_ENTRY, RuleSetListEntry)
-#define KPHSS_RULESET_ENTRY_LIMIT 10
-#define KPHSS_RULE_HANDLE_INCREMENT 4
-
-typedef struct _KPHSS_RULESET_ENTRY
-{
- LIST_ENTRY RuleSetListEntry;
- /* The client is referenced. */
- PKPHSS_CLIENT_ENTRY Client;
-
- KPHSS_RULESET_ACTION Action;
- KPHSS_FILTER_TYPE DefaultFilterType;
-
- ULONG NextRuleHandle;
- EX_PUSH_LOCK RuleListPushLock;
- /* A list of rules. Each rule is referenced when stored. */
- LIST_ENTRY RuleListHead;
-} KPHSS_RULESET_ENTRY, *PKPHSS_RULESET_ENTRY;
-
-/* Rules */
-
-#define KPHSS_RULE_ENTRY(ListEntry) \
- CONTAINING_RECORD((ListEntry), KPHSS_RULE_ENTRY, RuleListEntry)
-
-typedef struct _KPHSS_RULE_ENTRY
-{
- BOOLEAN Initialized;
- HANDLE Handle;
- LIST_ENTRY RuleListEntry;
-
- KPHSS_FILTER_TYPE FilterType;
- KPHSS_RULE_TYPE RuleType;
-
- union
- {
- struct
- {
- HANDLE ProcessId;
- } ProcessIdRule;
- struct
- {
- HANDLE ThreadId;
- } ThreadIdRule;
- struct
- {
- KPROCESSOR_MODE PreviousMode;
- } PreviousModeRule;
- struct
- {
- ULONG Number;
- } NumberRule;
- };
-} KPHSS_RULE_ENTRY, *PKPHSS_RULE_ENTRY;
-
-typedef enum _KPHSS_SEQUENCE_MODE
-{
- NoSequence,
- StartSequence,
- InSequence,
- EndSequence
-} KPHSS_SEQUENCE_MODE;
-
-#define TAG_CAPTURE_TEMP_BUFFER ('tChP')
-#define CAPTURE_HANDLE_BUFFER_SIZE 0x400
-#define CAPTURE_UNICODE_STRING_MAX_SIZE 0x400
-#define CAPTURE_BYTES_MAX_SIZE 0x400
-
-/* Functions */
-
-VOID NTAPI KphpSsClientEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- );
-
-VOID NTAPI KphpSsRuleSetEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- );
-
-NTSTATUS KphpSsAddRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in KPHSS_RULE_TYPE RuleType
- );
-
-NTSTATUS KphpSsCreateEventBlock(
- __out PKPHSS_EVENT_BLOCK *EventBlock,
- __in PKTHREAD Thread,
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments
- );
-
-VOID KphpSsFreeEventBlock(
- __in PKPHSS_EVENT_BLOCK EventBlock
- );
-
-NTSTATUS KphpSsCaptureSimpleArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PVOID Argument,
- __in KPHSS_ARGUMENT_TYPE Type,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCaptureHandleArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in HANDLE Argument,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCaptureUnicodeStringArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PUNICODE_STRING Argument,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCaptureObjectAttributesArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in POBJECT_ATTRIBUTES Argument,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCaptureClientIdArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PCLIENT_ID Argument,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCaptureBytesArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PVOID Argument,
- __in ULONG Length,
- __in KPROCESSOR_MODE PreviousMode
- );
-
-NTSTATUS KphpSsCreateArgumentBlock(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in ULONG Number,
- __in ULONG Argument,
- __in ULONG Index,
- __in_opt KPHSS_ARGUMENT_TYPE Type,
- __in_opt PVOID Context
- );
-
-PKPHSS_ARGUMENT_BLOCK KphpSsAllocateArgumentBlock(
- __in ULONG InnerSize,
- __in KPHSS_ARGUMENT_TYPE Type
- );
-
-VOID KphpSsFreeArgumentBlock(
- __in PKPHSS_ARGUMENT_BLOCK ArgumentBlock
- );
-
-NTSTATUS KphpSsWriteBlock(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in_opt PKPHSS_BLOCK_HEADER Block,
- __in KPHSS_SEQUENCE_MODE SequenceMode
- );
-
-VOID NTAPI KphpSsLogSystemServiceCall(
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments,
- __in PKSERVICE_TABLE_DESCRIPTOR ServiceTable,
- __in PKTHREAD Thread
- );
-
-VOID NTAPI KphpSsNewKiFastCallEntry();
-
-/* KphpSsMatchRuleSetEntry
- *
- * Determines if a ruleset is relevant to an event.
- *
- * Note: This function is inlined for performance reasons.
- */
-BOOLEAN FORCEINLINE KphpSsMatchRuleSetEntry(
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments,
- __in PKSERVICE_TABLE_DESCRIPTOR ServiceTable,
- __in PKTHREAD Thread,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- PLIST_ENTRY currentListEntry;
- ULONG i;
- BOOLEAN ruleTypeUsedArray[MaxRuleType];
- BOOLEAN ruleTypeIncludeArray[MaxRuleType];
- BOOLEAN ruleTypeExcludeArray[MaxRuleType];
- BOOLEAN ruleTypeFailedArray[MaxRuleType];
- BOOLEAN isRuleSetMatch;
-
- /* Due to the lack of proper boolean expression support,
- * we are going to have these rules:
- *
- * * Each rule type has four arrays. The standard
- * filtering rules apply to each rule type,
- * except that on an include we increment the value
- * in the include array and on an exclude we
- * increment the value in the exclude array. On a
- * failed include we increment the value in the
- * failed array.
- * * When we're done matching the rules, we'll look
- * at the default filter type. If it's Include,
- * we assume the ruleset matches. If it's Exclude,
- * we assume the ruleset fails.
- * * We will go through each rule type and look at
- * the two arrays. See the code for further
- * information.
- */
-
- /* Initialize the arrays. */
- for (i = 0; i < MaxRuleType; i++)
- {
- ruleTypeUsedArray[i] = FALSE;
- ruleTypeIncludeArray[i] = FALSE;
- ruleTypeExcludeArray[i] = FALSE;
- ruleTypeFailedArray[i] = FALSE;
- }
-
- KeEnterCriticalRegion();
- ExAcquirePushLockShared(&RuleSetEntry->RuleListPushLock);
-
- currentListEntry = RuleSetEntry->RuleListHead.Flink;
-
- while (currentListEntry != &RuleSetEntry->RuleListHead)
- {
- PKPHSS_RULE_ENTRY ruleEntry = KPHSS_RULE_ENTRY(currentListEntry);
- BOOLEAN isRuleMatch = FALSE;
-
- /* Check if the rule is initialized, and if
- * the rule type has already been failed -
- * Exclude filter types take precedence.
- */
- if (
- !ruleEntry->Initialized ||
- ruleTypeExcludeArray[ruleEntry->RuleType]
- )
- {
- currentListEntry = currentListEntry->Flink;
- continue;
- }
-
- /* Attempt to match the rule. All rule types are
- * considered in this one function.
- */
- switch (ruleEntry->RuleType)
- {
- case ProcessIdRuleType:
- if (PsGetProcessId(IoThreadToProcess(Thread)) ==
- ruleEntry->ProcessIdRule.ProcessId)
- isRuleMatch = TRUE;
- break;
- case ThreadIdRuleType:
- if (PsGetThreadId(Thread) == ruleEntry->ThreadIdRule.ThreadId)
- isRuleMatch = TRUE;
- break;
- case PreviousModeRuleType:
- if (PreviousMode == ruleEntry->PreviousModeRule.PreviousMode)
- isRuleMatch = TRUE;
- break;
- case NumberRuleType:
- if (Number == ruleEntry->NumberRule.Number)
- isRuleMatch = TRUE;
- break;
- }
-
- /* Now that we have attempted to match the rule, we
- * must look at the rule filter type to determine
- * what to do.
- */
- if (isRuleMatch)
- {
- if (ruleEntry->FilterType == IncludeFilterType)
- {
- ruleTypeIncludeArray[ruleEntry->RuleType] = TRUE;
- }
- else if (ruleEntry->FilterType == ExcludeFilterType)
- {
- ruleTypeExcludeArray[ruleEntry->RuleType] = TRUE;
- }
- }
- else
- {
- if (ruleEntry->FilterType == IncludeFilterType)
- {
- ruleTypeFailedArray[ruleEntry->RuleType] = TRUE;
- }
- }
-
- /* Declare that we have used the rule type. */
- ruleTypeUsedArray[ruleEntry->RuleType] = TRUE;
-
- currentListEntry = currentListEntry->Flink;
- }
-
- ExReleasePushLock(&RuleSetEntry->RuleListPushLock);
- KeLeaveCriticalRegion();
-
- /* Look at the default filter type. If it's Include,
- * we assume the ruleset matches. Otherwise, we
- * assume it fails.
- */
- if (RuleSetEntry->DefaultFilterType == IncludeFilterType)
- {
- isRuleSetMatch = TRUE;
- }
- else if (RuleSetEntry->DefaultFilterType == ExcludeFilterType)
- {
- isRuleSetMatch = FALSE;
- }
-
- /* Go through the rule type match/failed arrays. */
-
- for (i = 0; i < MaxRuleType; i++)
- {
- /* Make sure this rule type has been used. */
- if (!ruleTypeUsedArray[i])
- continue;
-
- /* The ordering of these if statements are
- * extremely important. The order of precedence
- * is: exclude, include, failed include. Failed include
- * doesn't apply if we're using the Include default
- * filter type, though.
- */
- if (ruleTypeExcludeArray[i])
- {
- isRuleSetMatch = FALSE;
- break;
- }
- else if (ruleTypeIncludeArray[i])
- {
- isRuleSetMatch = TRUE;
- }
- else if (
- ruleTypeFailedArray[i] &&
- RuleSetEntry->DefaultFilterType != IncludeFilterType
- )
- {
- isRuleSetMatch = FALSE;
- break;
- }
- }
-
- return isRuleSetMatch;
-}
-
-/* KphpSsProcessSpecificArguments
- *
- * Creates argument blocks for specific system calls.
- *
- * Note: This function is inlined for performance reasons.
- */
-VOID FORCEINLINE KphpSsProcessSpecificArguments(
- __in PKPHSS_ARGUMENT_BLOCK *ArgumentBlocks,
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status;
-
- /* For safety reasons, system call no. 0 is not supported. */
- if (Number == 0)
- return;
-
- /* Wrap in SEH because we will be accessing the arguments. */
-
- __try
- {
- if (Number == SsNtDeviceIoControlFile)
- {
- /* Create an argument block for the input buffer. */
- if (!NT_SUCCESS(KphpSsCreateArgumentBlock(
- &ArgumentBlocks[6],
- Number,
- Arguments[6],
- 6,
- BytesArgument,
- (PVOID)Arguments[7]
- )))
- ArgumentBlocks[6] = NULL;
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- // Nothing
- }
-}
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/test.h b/2.x/trunk/KProcessHacker/include/test.h
index 49dc96095..fc7dde4b9 100644
--- a/2.x/trunk/KProcessHacker/include/test.h
+++ b/2.x/trunk/KProcessHacker/include/test.h
@@ -23,8 +23,6 @@
#ifndef _TEST_H
#define _TEST_H
-#include "kph.h"
-
VOID KphTestPushLock();
#endif
diff --git a/2.x/trunk/KProcessHacker/include/trace.h b/2.x/trunk/KProcessHacker/include/trace.h
index 6b707ede5..a17a9d5d2 100644
--- a/2.x/trunk/KProcessHacker/include/trace.h
+++ b/2.x/trunk/KProcessHacker/include/trace.h
@@ -23,8 +23,6 @@
#ifndef _TRACE_H
#define _TRACE_H
-#include "types.h"
-
/* Stack Tracing */
/* Sensible limit that may or may not correspond to the actual Windows value. */
diff --git a/2.x/trunk/KProcessHacker/include/types.h b/2.x/trunk/KProcessHacker/include/types.h
deleted file mode 100644
index e1ca291c1..000000000
--- a/2.x/trunk/KProcessHacker/include/types.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _TYPES_H
-#define _TYPES_H
-
-#include
-#include "version.h"
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/include/util.h b/2.x/trunk/KProcessHacker/include/util.h
index b62b0d22e..cfb4f435e 100644
--- a/2.x/trunk/KProcessHacker/include/util.h
+++ b/2.x/trunk/KProcessHacker/include/util.h
@@ -23,8 +23,6 @@
#ifndef _UTIL_H
#define _UTIL_H
-#include "kph.h"
-
/* Streams
*
* Streams are small buffer management structures. They
diff --git a/2.x/trunk/KProcessHacker/include/version.h b/2.x/trunk/KProcessHacker/include/version.h
index 00d6ba5ab..2029eab43 100644
--- a/2.x/trunk/KProcessHacker/include/version.h
+++ b/2.x/trunk/KProcessHacker/include/version.h
@@ -23,8 +23,6 @@
#ifndef _VERSION_H
#define _VERSION_H
-#include "kph.h"
-
#define WINDOWS_XP 51
#define WINDOWS_SERVER_2003 52
#define WINDOWS_VISTA 60
@@ -59,10 +57,6 @@ PVOID KvScanProc(
PKV_SCANPROC ScanProc
);
-PVOID KvVerifyPrologue(
- PVOID Address
- );
-
#ifdef EXT
#undef EXT
#endif
@@ -84,13 +78,11 @@ EXT ACCESS_MASK ThreadAllAccess;
/* Structures
* Et: ETHREAD
* Ep: EPROCESS
+ * Oh: OBJECT_HEADER
* Ot: OBJECT_TYPE
* Oti: OBJECT_TYPE_INITIALIZER, offset measured from an OBJECT_TYPE
*/
EXT ULONG OffEtClientId;
-EXT ULONG OffEtSpareByteForSs;
-EXT ULONG OffEtStartAddress;
-EXT ULONG OffEtWin32StartAddress;
EXT ULONG OffEpJob;
EXT ULONG OffEpObjectTable;
EXT ULONG OffEpProtectedProcessOff;
@@ -99,143 +91,10 @@ EXT ULONG OffEpRundownProtect;
EXT ULONG OffOhBody;
EXT ULONG OffOtName;
EXT ULONG OffOtiGenericMapping;
-EXT ULONG OffOtiOpenProcedure;
/* Functions
*/
-EXT KV_SCANPROC KiFastCallEntryScan SCANNULL;
-EXT KV_SCANPROC PsExitSpecialApcScan SCANNULL;
EXT KV_SCANPROC PsTerminateProcessScan SCANNULL;
EXT KV_SCANPROC PspTerminateThreadByPointerScan SCANNULL;
-/* System Call Numbers
- */
-EXT ULONG SsNtAddAtom;
-EXT ULONG SsNtAlertResumeThread;
-EXT ULONG SsNtAlertThread;
-EXT ULONG SsNtAllocateLocallyUniqueId;
-EXT ULONG SsNtAllocateUserPhysicalPages;
-EXT ULONG SsNtAllocateUuids;
-EXT ULONG SsNtAllocateVirtualMemory;
-EXT ULONG SsNtApphelpCacheControl;
-EXT ULONG SsNtAreMappedFilesTheSame;
-EXT ULONG SsNtAssignProcessToJobObject;
-EXT ULONG SsNtCallbackReturn;
-EXT ULONG SsNtCancelDeviceWakeupRequest;
-EXT ULONG SsNtCancelIoFile;
-EXT ULONG SsNtCancelTimer;
-EXT ULONG SsNtClearEvent;
-EXT ULONG SsNtClose;
-EXT ULONG SsNtContinue;
-EXT ULONG SsNtCreateDebugObject;
-EXT ULONG SsNtCreateDirectoryObject;
-EXT ULONG SsNtCreateEvent;
-EXT ULONG SsNtCreateEventPair;
-EXT ULONG SsNtCreateFile;
-EXT ULONG SsNtCreateIoCompletion;
-EXT ULONG SsNtCreateJobObject;
-EXT ULONG SsNtCreateJobSet;
-EXT ULONG SsNtCreateKey;
-EXT ULONG SsNtCreateKeyedEvent;
-EXT ULONG SsNtCreateMailslotFile;
-EXT ULONG SsNtCreateMutant;
-EXT ULONG SsNtCreateNamedPipeFile;
-EXT ULONG SsNtCreatePagingFile;
-EXT ULONG SsNtCreatePort;
-EXT ULONG SsNtCreatePrivateNamespace;
-EXT ULONG SsNtCreateProcess;
-EXT ULONG SsNtCreateProcessEx;
-EXT ULONG SsNtCreateProfile;
-EXT ULONG SsNtCreateSection;
-EXT ULONG SsNtCreateSemaphore;
-EXT ULONG SsNtCreateSymbolicLinkObject;
-EXT ULONG SsNtCreateThread;
-EXT ULONG SsNtCreateTimer;
-EXT ULONG SsNtCreateToken;
-EXT ULONG SsNtCreateUserProcess;
-EXT ULONG SsNtCreateWaitablePort;
-EXT ULONG SsNtDebugActiveProcess;
-EXT ULONG SsNtDebugContinue;
-EXT ULONG SsNtDelayExecution;
-EXT ULONG SsNtDeleteAtom;
-EXT ULONG SsNtDeleteBootEntry;
-EXT ULONG SsNtDeleteDriverEntry;
-EXT ULONG SsNtDeleteFile;
-EXT ULONG SsNtDeleteKey;
-EXT ULONG SsNtDeleteObjectAuditAlarm;
-EXT ULONG SsNtDeletePrivateNamespace;
-EXT ULONG SsNtDeleteValueKey;
-EXT ULONG SsNtDeviceIoControlFile;
-EXT ULONG SsNtDisplayString;
-EXT ULONG SsNtDuplicateObject;
-EXT ULONG SsNtDuplicateToken;
-EXT ULONG SsNtEnumerateBootEntries;
-EXT ULONG SsNtEnumerateDriverEntries;
-EXT ULONG SsNtEnumerateKey;
-EXT ULONG SsNtEnumerateSystemEnvironmentValuesEx;
-EXT ULONG SsNtEnumerateValueKey;
-EXT ULONG SsNtExtendSection;
-EXT ULONG SsNtFilterToken;
-EXT ULONG SsNtFindAtom;
-EXT ULONG SsNtFlushBuffersFile;
-EXT ULONG SsNtFlushInstructionCache;
-EXT ULONG SsNtFlushKey;
-EXT ULONG SsNtFlushProcessWriteBuffers;
-EXT ULONG SsNtFlushVirtualMemory;
-EXT ULONG SsNtFlushWriteBuffer;
-EXT ULONG SsNtFreeUserPhysicalPages;
-EXT ULONG SsNtFreeVirtualMemory;
-EXT ULONG SsNtFsControlFile;
-EXT ULONG SsNtGetContextThread;
-EXT ULONG SsNtGetCurrentProcessorNumber;
-EXT ULONG SsNtGetDevicePowerState;
-EXT ULONG SsNtGetNextProcess;
-EXT ULONG SsNtGetNextThread;
-EXT ULONG SsNtGetPlugPlayEvent;
-EXT ULONG SsNtGetWriteWatch;
-EXT ULONG SsNtImpersonateAnonymousToken;
-EXT ULONG SsNtImpersonateClientOfPort;
-EXT ULONG SsNtImpersonateThread;
-EXT ULONG SsNtInitiatePowerAction;
-EXT ULONG SsNtIsProcessInJob;
-EXT ULONG SsNtIsSystemResumeAutomatic;
-EXT ULONG SsNtListenPort;
-EXT ULONG SsNtLoadDriver;
-EXT ULONG SsNtLoadKey;
-EXT ULONG SsNtLoadKey2;
-EXT ULONG SsNtLockFile;
-EXT ULONG SsNtLockVirtualMemory;
-EXT ULONG SsNtMakePermanentObject;
-EXT ULONG SsNtMakeTemporaryObject;
-EXT ULONG SsNtMapUserPhysicalPages;
-EXT ULONG SsNtMapUserPhysicalPagesScatter;
-EXT ULONG SsNtMapViewOfSection;
-EXT ULONG SsNtModifyBootEntry;
-EXT ULONG SsNtModifyDriverEntry;
-EXT ULONG SsNtNotifyChangeDirectoryFile;
-EXT ULONG SsNtNotifyChangeKey;
-EXT ULONG SsNtNotifyChangeMultipleKeys;
-EXT ULONG SsNtOpenDirectoryObject;
-EXT ULONG SsNtOpenEvent;
-EXT ULONG SsNtOpenEventPair;
-EXT ULONG SsNtOpenFile;
-EXT ULONG SsNtOpenIoCompletion;
-EXT ULONG SsNtOpenJobObject;
-EXT ULONG SsNtOpenKey;
-EXT ULONG SsNtOpenKeyedEvent;
-EXT ULONG SsNtOpenMutant;
-EXT ULONG SsNtOpenObjectAuditAlarm;
-EXT ULONG SsNtOpenProcess;
-EXT ULONG SsNtOpenProcessToken;
-EXT ULONG SsNtOpenProcessTokenEx;
-EXT ULONG SsNtOpenSection;
-EXT ULONG SsNtOpenSemaphore;
-EXT ULONG SsNtOpenSymbolicLinkObject;
-EXT ULONG SsNtOpenThread;
-EXT ULONG SsNtOpenThreadToken;
-EXT ULONG SsNtOpenThreadTokenEx;
-EXT ULONG SsNtOpenTimer;
-EXT ULONG SsNtReadFile;
-EXT ULONG SsNtWriteFile;
-
#endif
diff --git a/2.x/trunk/KProcessHacker/include/zw.h b/2.x/trunk/KProcessHacker/include/zw.h
index db943135f..93f0efb3d 100644
--- a/2.x/trunk/KProcessHacker/include/zw.h
+++ b/2.x/trunk/KProcessHacker/include/zw.h
@@ -23,8 +23,6 @@
#ifndef _ZW_H
#define _ZW_H
-#include "types.h"
-
NTSTATUS NTAPI ZwOpenProcessToken(
__in HANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
diff --git a/2.x/trunk/KProcessHacker/io.c b/2.x/trunk/KProcessHacker/io.c
index c8a55d68b..cd1e9c4d0 100644
--- a/2.x/trunk/KProcessHacker/io.c
+++ b/2.x/trunk/KProcessHacker/io.c
@@ -20,7 +20,7 @@
* along with Process Hacker. If not, see .
*/
-#include "include/io.h"
+#include "include/kph.h"
VOID KphpCopyInfoUnicodeString(
__out PVOID Information,
diff --git a/2.x/trunk/KProcessHacker/kph.c b/2.x/trunk/KProcessHacker/kph.c
index 8bc172a0f..a48bb9765 100644
--- a/2.x/trunk/KProcessHacker/kph.c
+++ b/2.x/trunk/KProcessHacker/kph.c
@@ -92,11 +92,6 @@ NTSTATUS KphNtInit()
}
/* Scan for functions. */
- if (KiFastCallEntryScan.Initialized)
- {
- __KiFastCallEntry = KvScanProc(&KiFastCallEntryScan);
- dfprintf("KiFastCallEntry+x: %#x\n", __KiFastCallEntry);
- }
if (PsTerminateProcessScan.Initialized)
{
__PsTerminateProcess = KvScanProc(&PsTerminateProcessScan);
@@ -348,14 +343,20 @@ NTSTATUS OpenProcess(
__in HANDLE ProcessId
)
{
- OBJECT_ATTRIBUTES objAttr = { 0 };
+ OBJECT_ATTRIBUTES oa;
CLIENT_ID clientId;
- objAttr.Length = sizeof(objAttr);
+ InitializeObjectAttributes(
+ &oa,
+ NULL,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
clientId.UniqueThread = 0;
clientId.UniqueProcess = ProcessId;
- return KphOpenProcess(ProcessHandle, DesiredAccess, &objAttr, &clientId, KernelMode);
+ return KphOpenProcess(ProcessHandle, DesiredAccess, &oa, &clientId, KernelMode);
}
/* SetProcessToken
@@ -364,19 +365,19 @@ NTSTATUS OpenProcess(
* primary token of source process.
*/
NTSTATUS SetProcessToken(
- __in HANDLE sourcePid,
- __in HANDLE targetPid
+ __in HANDLE SourcePid,
+ __in HANDLE TargetPid
)
{
NTSTATUS status;
HANDLE source;
- if (NT_SUCCESS(status = OpenProcess(&source, PROCESS_QUERY_INFORMATION, sourcePid)))
+ if (NT_SUCCESS(status = OpenProcess(&source, PROCESS_QUERY_INFORMATION, SourcePid)))
{
HANDLE target;
if (NT_SUCCESS(status = OpenProcess(&target, PROCESS_QUERY_INFORMATION |
- PROCESS_SET_INFORMATION, targetPid)))
+ PROCESS_SET_INFORMATION, TargetPid)))
{
HANDLE sourceToken;
@@ -384,11 +385,17 @@ NTSTATUS SetProcessToken(
&sourceToken, UserMode)))
{
HANDLE dupSourceToken;
- OBJECT_ATTRIBUTES objectAttributes = { 0 };
+ OBJECT_ATTRIBUTES oa;
- objectAttributes.Length = sizeof(objectAttributes);
+ InitializeObjectAttributes(
+ &oa,
+ NULL,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
- if (NT_SUCCESS(status = ZwDuplicateToken(sourceToken, TOKEN_ASSIGN_PRIMARY, &objectAttributes,
+ if (NT_SUCCESS(status = ZwDuplicateToken(sourceToken, TOKEN_ASSIGN_PRIMARY, &oa,
FALSE, TokenPrimary, &dupSourceToken)))
{
PROCESS_ACCESS_TOKEN token;
diff --git a/2.x/trunk/KProcessHacker/kprocesshacker.c b/2.x/trunk/KProcessHacker/kprocesshacker.c
index 5a470578f..da7c9f94c 100644
--- a/2.x/trunk/KProcessHacker/kprocesshacker.c
+++ b/2.x/trunk/KProcessHacker/kprocesshacker.c
@@ -20,14 +20,8 @@
* along with Process Hacker. If not, see .
*/
-#include "include/kprocesshacker.h"
-#include "include/debug.h"
-
#include "include/kph.h"
-#include "include/protect.h"
-#include "include/ps.h"
-#include "include/sysservice.h"
-#include "include/version.h"
+#include "include/kprocesshacker.h"
#define CHECK_IN_LENGTH \
if (inLength < sizeof(*args)) \
@@ -50,16 +44,6 @@
PDRIVER_OBJECT KphDriverObject;
-static PKPH_OBJECT_TYPE ClientEntryType;
-static LIST_ENTRY ClientListHead;
-static EX_PUSH_LOCK ClientListLock;
-
-static BOOLEAN ProtectionInitialized = FALSE;
-static FAST_MUTEX ProtectionMutex;
-
-static ULONG SsStartCount = 0;
-static FAST_MUTEX SsMutex;
-
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DriverEntry)
#pragma alloc_text(PAGE, DriverUnload)
@@ -93,12 +77,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/* Initialize NT KPH. */
status = KphNtInit();
- if (!NT_SUCCESS(status))
- return status;
-
- /* Initialize hooking. */
- status = KphHookInit();
-
if (!NT_SUCCESS(status))
return status;
@@ -108,15 +86,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
if (!NT_SUCCESS(status))
return status;
- /* Initialize system service logging. */
- status = KphSsLogInit();
-
- if (!NT_SUCCESS(status))
- {
- KphRefDeinit();
- return status;
- }
-
/* Initialize trace databases. */
status = KphTraceDatabaseInitialization();
@@ -126,28 +95,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
return status;
}
- /* Initialize client list structures. */
- InitializeListHead(&ClientListHead);
- ExInitializePushLock(&ClientListLock);
-
- status = KphCreateObjectType(
- &ClientEntryType,
- PagedPool,
- 0,
- ClientEntryDeleteProcedure
- );
-
- if (!NT_SUCCESS(status))
- {
- KphRefDeinit();
- return status;
- }
-
- /* Initialize process protection. */
- ExInitializeFastMutex(&ProtectionMutex);
- /* Initialize the system service logging mutex. */
- ExInitializeFastMutex(&SsMutex);
-
RtlInitUnicodeString(&deviceName, KPH_DEVICE_NAME);
RtlInitUnicodeString(&dosDeviceName, KPH_DEVICE_DOS_NAME);
@@ -183,23 +130,6 @@ VOID DriverUnload(PDRIVER_OBJECT DriverObject)
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
- ExAcquireFastMutex(&ProtectionMutex);
-
- if (ProtectionInitialized)
- {
- KphProtectDeinit();
- ProtectionInitialized = FALSE;
- }
-
- ExReleaseFastMutex(&ProtectionMutex);
-
- /* Make sure system service logging is disabled. */
- if (SsStartCount > 0)
- SsUnref(SsStartCount);
-
- /* Free system service logging structures. */
- KphSsLogDeinit();
-
/* Free all objects in the object manager. */
KphRefDeinit();
@@ -220,17 +150,7 @@ NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
#endif
- /* Add a client entry. Note that we don't dereference it because
- * we keep one reference for it being on the client list.
- */
- if (!CreateClientEntry(NULL))
- {
- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
dprintf("Client (PID %d) connected\n", PsGetCurrentProcessId());
- dprintf("Base IOCTL is 0x%08x\n", KPH_CTL_CODE(0));
return status;
}
@@ -238,369 +158,45 @@ NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS KphDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
- PKPH_CLIENT_ENTRY clientEntry;
-
- ExAcquireFastMutex(&ProtectionMutex);
-
- if (ProtectionInitialized)
- {
- ULONG count = KphProtectRemoveByTag(PsGetCurrentProcessId());
- dprintf("Removed %d protection entries\n", count);
- }
-
- ExReleaseFastMutex(&ProtectionMutex);
-
- /* Get the current client entry and dereference it twice to remove it. */
- clientEntry = ReferenceClientEntry(NULL);
-
- if (clientEntry)
- KphDereferenceObjectEx(clientEntry, 2, FALSE);
dprintf("Client (PID %d) disconnected\n", PsGetCurrentProcessId());
return status;
}
-VOID InitProtection()
-{
- ExAcquireFastMutex(&ProtectionMutex);
-
- if (!ProtectionInitialized)
- {
- if (NT_SUCCESS(KphProtectInit()))
- ProtectionInitialized = TRUE;
- }
-
- ExReleaseFastMutex(&ProtectionMutex);
-}
-
-VOID SsRef(LONG count)
-{
- LONG oldRefCount;
-
- ASSERT(count >= 0);
-
- if (count == 0)
- return;
-
- ExAcquireFastMutex(&SsMutex);
-
- /* Add references. */
- oldRefCount = InterlockedExchangeAdd(&SsStartCount, count);
- ASSERT(oldRefCount >= 0);
-
- /* Start system service logging if this was the first bunch of references. */
- if (oldRefCount == 0)
- KphSsLogStart();
-
- ExReleaseFastMutex(&SsMutex);
-}
-
-VOID SsUnref(LONG count)
-{
- LONG oldRefCount;
-
- ASSERT(count >= 0);
-
- if (count == 0)
- return;
-
- ExAcquireFastMutex(&SsMutex);
-
- oldRefCount = InterlockedExchangeAdd(&SsStartCount, -count);
- ASSERT(oldRefCount > 0);
-
- if (oldRefCount - count == 0)
- KphSsLogStop();
-
- ExReleaseFastMutex(&SsMutex);
-}
-
-VOID NTAPI ClientEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- )
-{
- PKPH_CLIENT_ENTRY entry = (PKPH_CLIENT_ENTRY)Object;
-
- /* Lower the SS start count. */
- SsUnref(entry->SsStartCount);
-
- /* Free the handle table. */
- KphFreeHandleTable(entry->HandleTable);
-
- /* Remove the entry from the client list. */
- KeEnterCriticalRegion();
- ExAcquirePushLockExclusive(&ClientListLock);
- RemoveEntryList(&entry->ClientListEntry);
- ExReleasePushLock(&ClientListLock);
- KeLeaveCriticalRegion();
-}
-
-PKPH_CLIENT_ENTRY CreateClientEntry(
- __in_opt HANDLE ProcessId
- )
-{
- PKPH_CLIENT_ENTRY entry;
- PKPH_HANDLE_TABLE handleTable;
-
- /* If the PID wasn't specified, use the current one. */
- if (!ProcessId)
- ProcessId = PsGetCurrentProcessId();
-
- if (!NT_SUCCESS(KphCreateHandleTable(
- &handleTable,
- KPH_CLIENT_MAXHANDLES,
- sizeof(KPH_HANDLE_TABLE_ENTRY),
- TAG_CLIENT_HANDLETABLE
- )))
- return NULL;
-
- if (!NT_SUCCESS(KphCreateObject(
- &entry,
- sizeof(KPH_CLIENT_ENTRY),
- 0,
- ClientEntryType,
- 0
- )))
- {
- KphFreeHandleTable(handleTable);
- return NULL;
- }
-
- /* Initialize the entry. */
- entry->ProcessId = ProcessId;
- entry->HandleTable = handleTable;
- KphInitializeGuardedLock(&entry->SsLock, FALSE);
- entry->SsStartCount = 0;
-
- /* Insert the entry into the client list. */
- KeEnterCriticalRegion();
- ExAcquirePushLockExclusive(&ClientListLock);
- InsertHeadList(&ClientListHead, &entry->ClientListEntry);
- ExReleasePushLock(&ClientListLock);
- KeLeaveCriticalRegion();
-
- return entry;
-}
-
-PKPH_CLIENT_ENTRY ReferenceClientEntry(
- __in_opt HANDLE ProcessId
- )
-{
- PLIST_ENTRY entry = ClientListHead.Flink;
-
- /* If the PID wasn't specified, use the current one. */
- if (!ProcessId)
- ProcessId = PsGetCurrentProcessId();
-
- KeEnterCriticalRegion();
- ExAcquirePushLockShared(&ClientListLock);
-
- /* Find the client entry. */
- while (entry != &ClientListHead)
- {
- PKPH_CLIENT_ENTRY clientEntry =
- CONTAINING_RECORD(entry, KPH_CLIENT_ENTRY, ClientListEntry);
-
- if (clientEntry->ProcessId == ProcessId)
- {
- PKPH_CLIENT_ENTRY returnEntry = NULL;
-
- /* Reference and return the entry. */
- if (KphReferenceObjectSafe(clientEntry))
- {
- returnEntry = clientEntry;
- }
-
- ExReleasePushLock(&ClientListLock);
- KeLeaveCriticalRegion();
-
- return returnEntry;
- }
-
- entry = entry->Flink;
- }
-
- ExReleasePushLock(&ClientListLock);
- KeLeaveCriticalRegion();
-
- return NULL;
-}
-
-NTSTATUS CloseClientHandle(
- __in_opt HANDLE ProcessId,
- __in HANDLE Handle
- )
-{
- NTSTATUS status;
- PKPH_CLIENT_ENTRY clientEntry;
-
- clientEntry = ReferenceClientEntry(ProcessId);
-
- if (!clientEntry)
- return STATUS_UNSUCCESSFUL;
-
- status = KphCloseHandle(clientEntry->HandleTable, Handle);
- KphDereferenceObject(clientEntry);
-
- return status;
-}
-
-NTSTATUS CreateClientHandle(
- __in_opt HANDLE ProcessId,
- __in PVOID Object,
- __out PHANDLE Handle
- )
-{
- NTSTATUS status;
- PKPH_CLIENT_ENTRY clientEntry;
-
- clientEntry = ReferenceClientEntry(ProcessId);
-
- if (!clientEntry)
- return STATUS_UNSUCCESSFUL;
-
- status = KphCreateHandle(clientEntry->HandleTable, Object, Handle);
- KphDereferenceObject(clientEntry);
-
- return status;
-}
-
-NTSTATUS ReferenceClientHandle(
- __in_opt HANDLE ProcessId,
- __in HANDLE Handle,
- __in PKPH_OBJECT_TYPE ObjectType,
- __out PVOID *Object
- )
-{
- NTSTATUS status;
- PKPH_CLIENT_ENTRY clientEntry;
-
- clientEntry = ReferenceClientEntry(ProcessId);
-
- if (!clientEntry)
- return STATUS_UNSUCCESSFUL;
-
- status = KphReferenceObjectByHandle(
- clientEntry->HandleTable,
- Handle,
- ObjectType,
- Object
- );
- KphDereferenceObject(clientEntry);
-
- return status;
-}
-
-PCHAR GetIoControlName(ULONG ControlCode)
+PCHAR KphpGetControlCodeName(ULONG ControlCode)
{
switch (ControlCode)
{
- case KPH_CLOSEHANDLE:
- return "Client Close Handle";
- case KPH_SSQUERYCLIENTENTRY:
- return "SsQueryClientEntry";
+ case KPH_GETFEATURES:
+ return "KphGetFeatures";
+
case KPH_OPENPROCESS:
return "KphOpenProcess";
- case KPH_OPENTHREAD:
- return "KphOpenThread";
case KPH_OPENPROCESSTOKEN:
- return "KphOpenProcessTokenEx";
- case KPH_GETPROCESSPROTECTED:
- return "Get Process Protected";
- case KPH_SETPROCESSPROTECTED:
- return "Set Process Protected";
- case KPH_TERMINATEPROCESS:
- return "KphTerminateProcess";
+ return "KphOpenProcessToken";
+ case KPH_OPENPROCESSJOB:
+ return "KphOpenProcessJob";
case KPH_SUSPENDPROCESS:
return "KphSuspendProcess";
case KPH_RESUMEPROCESS:
return "KphResumeProcess";
+ case KPH_TERMINATEPROCESS:
+ return "KphTerminateProcess";
case KPH_READVIRTUALMEMORY:
return "KphReadVirtualMemory";
case KPH_WRITEVIRTUALMEMORY:
return "KphWriteVirtualMemory";
- case KPH_SETPROCESSTOKEN:
- return "Set Process Token";
- case KPH_GETTHREADSTARTADDRESS:
- return "Get Thread Start Address";
- case KPH_SETHANDLEATTRIBUTES:
- return "Set Handle Attributes";
- case KPH_GETHANDLEOBJECTNAME:
- return "Get Handle Object Name";
- case KPH_OPENPROCESSJOB:
- return "KphOpenProcessJob";
- case KPH_GETCONTEXTTHREAD:
- return "KphGetContextThread";
- case KPH_SETCONTEXTTHREAD:
- return "KphSetContextThread";
- case KPH_GETTHREADWIN32THREAD:
- return "KphGetThreadWin32Thread";
- case KPH_DUPLICATEOBJECT:
- return "KphDuplicateObject";
- case KPH_ZWQUERYOBJECT:
- return "ZwQueryObject";
- case KPH_GETPROCESSID:
- return "KphGetProcessId";
- case KPH_GETTHREADID:
- return "KphGetThreadId";
- case KPH_TERMINATETHREAD:
- return "KphTerminateThread";
- case KPH_GETFEATURES:
- return "Get Features";
- case KPH_SETHANDLEGRANTEDACCESS:
- return "KphSetHandleGrantedAccess";
- case KPH_ASSIGNIMPERSONATIONTOKEN:
- return "KphAssignImpersonationToken";
- case KPH_PROTECTADD:
- return "Add Process Protection";
- case KPH_PROTECTREMOVE:
- return "Remove Process Protection";
- case KPH_PROTECTQUERY:
- return "Query Process Protection";
case KPH_UNSAFEREADVIRTUALMEMORY:
return "KphUnsafeReadVirtualMemory";
+ case KPH_GETPROCESSPROTECTED:
+ return "KphGetProcessProtected";
+ case KPH_SETPROCESSPROTECTED:
+ return "KphSetProcessProtected";
case KPH_SETEXECUTEOPTIONS:
- return "Set Execute Options";
- case KPH_QUERYPROCESSHANDLES:
- return "KphQueryProcessHandles";
- case KPH_OPENTHREADPROCESS:
- return "KphOpenThreadProcess";
- case KPH_CAPTURESTACKBACKTRACETHREAD:
- return "KphCaptureStackBackTraceThread";
- case KPH_DANGEROUSTERMINATETHREAD:
- return "KphDangerousTerminateThread";
- case KPH_OPENTYPE:
- return "KphOpenType";
- case KPH_OPENDRIVER:
- return "KphOpenDriver";
- case KPH_QUERYINFORMATIONDRIVER:
- return "KphQueryInformationDriver";
- case KPH_OPENDIRECTORYOBJECT:
- return "KphOpenDirectoryObject";
- case KPH_SSREF:
- return "SsRef";
- case KPH_SSUNREF:
- return "SsUnref";
- case KPH_SSCREATECLIENTENTRY:
- return "SsCreateClientEntry";
- case KPH_SSCREATERULESETENTRY:
- return "SsCreateRuleSetEntry";
- case KPH_SSREMOVERULE:
- return "SsRemoveRule";
- case KPH_SSADDPROCESSIDRULE:
- return "SsAddProcessIdRule";
- case KPH_SSADDTHREADIDRULE:
- return "SsAddThreadIdRule";
- case KPH_SSADDPREVIOUSMODERULE:
- return "SsAddPreviousModeRule";
- case KPH_SSADDNUMBERRULE:
- return "SsAddNumberRule";
- case KPH_SSENABLECLIENTENTRY:
- return "SsEnableClientEntry";
- case KPH_OPENNAMEDOBJECT:
- return "KphOpenNamedObject";
+ return "KphSetExecuteOptions";
+ case KPH_SETPROCESSTOKEN:
+ return "KphSetProcessToken";
case KPH_QUERYINFORMATIONPROCESS:
return "KphQueryInformationProcess";
case KPH_QUERYINFORMATIONTHREAD:
@@ -609,6 +205,54 @@ PCHAR GetIoControlName(ULONG ControlCode)
return "KphSetInformationProcess";
case KPH_SETINFORMATIONTHREAD:
return "KphSetInformationThread";
+
+ case KPH_OPENTHREAD:
+ return "KphOpenThread";
+ case KPH_OPENTHREADPROCESS:
+ return "KphOpenThreadProcess";
+ case KPH_TERMINATETHREAD:
+ return "KphTerminateThread";
+ case KPH_DANGEROUSTERMINATETHREAD:
+ return "KphDangerousTerminateThread";
+ case KPH_GETCONTEXTTHREAD:
+ return "KphGetContextThread";
+ case KPH_SETCONTEXTTHREAD:
+ return "KphSetContextThread";
+ case KPH_CAPTURESTACKBACKTRACETHREAD:
+ return "KphCaptureStackBackTraceThread";
+ case KPH_GETTHREADWIN32THREAD:
+ return "KphGetThreadWin32Thread";
+ case KPH_ASSIGNIMPERSONATIONTOKEN:
+ return "KphAssignImpersonationToken";
+
+ case KPH_QUERYPROCESSHANDLES:
+ return "KphQueryProcessHandles";
+ case KPH_GETHANDLEOBJECTNAME:
+ return "KphGetHandleObjectName";
+ case KPH_ZWQUERYOBJECT:
+ return "KphZwQueryObject";
+ case KPH_DUPLICATEOBJECT:
+ return "KphDuplicateObject";
+ case KPH_SETHANDLEATTRIBUTES:
+ return "KphSetHandleAttributes";
+ case KPH_SETHANDLEGRANTEDACCESS:
+ return "KphSetHandleGrantedAccess";
+ case KPH_GETPROCESSID:
+ return "KphGetProcessId";
+ case KPH_GETTHREADID:
+ return "KphGetThreadId";
+
+ case KPH_OPENNAMEDOBJECT:
+ return "KphOpenNamedObject";
+ case KPH_OPENDIRECTORYOBJECT:
+ return "KphOpenDirectoryObject";
+ case KPH_OPENDRIVER:
+ return "KphOpenDriver";
+ case KPH_QUERYINFORMATIONDRIVER:
+ return "KphQueryInformationDriver";
+ case KPH_OPENTYPE:
+ return "KphOpenType";
+
default:
return "Unknown";
}
@@ -647,68 +291,34 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
outLength = ioStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
controlCode = ioStackIrp->Parameters.DeviceIoControl.IoControlCode;
- dprintf("IoControl 0x%08x (%s)\n", controlCode, GetIoControlName(controlCode));
+ dprintf("IoControl 0x%08x (%s)\n", controlCode, KphpGetControlCodeName(controlCode));
/* 1-byte packing for KPH input/output structures. */
#include
switch (controlCode)
{
- /* Client Close Handle
+ /* Get Features
*
- * Closes a handle opened by the client.
+ * Gets the features supported by the driver.
*/
- case KPH_CLOSEHANDLE:
+ case KPH_GETFEATURES:
{
struct
{
- HANDLE Handle;
- } *args = dataBuffer;
- PKPH_CLIENT_ENTRY clientEntry;
+ ULONG Features;
+ } *ret = dataBuffer;
+ ULONG features = 0;
- CHECK_IN_LENGTH;
+ CHECK_OUT_LENGTH;
- status = CloseClientHandle(NULL, args->Handle);
- }
- break;
-
- /* SsQueryClientEntry
- *
- * Queries information about a client entry.
- */
- case KPH_SSQUERYCLIENTENTRY:
- {
- struct
- {
- HANDLE ClientEntryHandle;
- PKPHSS_CLIENT_INFORMATION ClientInformation;
- ULONG ClientInformationLength;
- PULONG ReturnLength;
- } *args = dataBuffer;
- PKPHSS_CLIENT_ENTRY clientEntry;
+ if (__PsTerminateProcess)
+ features |= KPHF_PSTERMINATEPROCESS;
+ if (__PspTerminateThreadByPointer)
+ features |= KPHF_PSPTERMINATETHREADBPYPOINTER;
- CHECK_IN_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->ClientEntryHandle,
- KphSsClientEntryType,
- &clientEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Query the client entry. */
- status = KphSsQueryClientEntry(
- clientEntry,
- args->ClientInformation,
- args->ClientInformationLength,
- args->ReturnLength,
- UserMode
- );
- KphDereferenceObject(clientEntry);
+ ret->Features = features;
+ retLength = sizeof(*ret);
}
break;
@@ -752,46 +362,6 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
- /* KphOpenThread
- *
- * Opens the specified thread. This call will never fail unless:
- * 1. PsLookupProcessThreadByCid, ObOpenObjectByPointer or some lower-level
- * function is hooked, or
- * 2. The thread's process is protected.
- */
- case KPH_OPENTHREAD:
- {
- struct
- {
- HANDLE ThreadId;
- ACCESS_MASK DesiredAccess;
- } *args = dataBuffer;
- struct
- {
- HANDLE ThreadHandle;
- } *ret = dataBuffer;
- OBJECT_ATTRIBUTES objectAttributes = { 0 };
- CLIENT_ID clientId;
-
- CHECK_IN_OUT_LENGTH;
-
- clientId.UniqueThread = args->ThreadId;
- clientId.UniqueProcess = 0;
- status = KphOpenThread(
- &ret->ThreadHandle,
- args->DesiredAccess,
- &objectAttributes,
- &clientId,
- KernelMode
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- retLength = sizeof(*ret);
- }
- break;
-
/* KphOpenProcessToken
*
* Opens the specified process' token. This call will never fail unless
@@ -826,6 +396,175 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
+ /* KphOpenProcessJob
+ *
+ * Opens the job object that the process is assigned to. If the process is
+ * not assigned to any job object, the call will fail with STATUS_PROCESS_NOT_IN_JOB.
+ */
+ case KPH_OPENPROCESSJOB:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ ACCESS_MASK DesiredAccess;
+ } *args = dataBuffer;
+ struct
+ {
+ HANDLE JobHandle;
+ } *ret = dataBuffer;
+
+ CHECK_IN_OUT_LENGTH;
+
+ status = KphOpenProcessJob(args->ProcessHandle, args->DesiredAccess, &ret->JobHandle, KernelMode);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphSuspendProcess
+ *
+ * Suspends the specified process. This call will fail on Windows XP
+ * and below.
+ */
+ case KPH_SUSPENDPROCESS:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphSuspendProcess(args->ProcessHandle);
+ }
+ break;
+
+ /* KphResumeProcess
+ *
+ * Resumes the specified process. This call will fail on Windows XP
+ * and below.
+ */
+ case KPH_RESUMEPROCESS:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphResumeProcess(args->ProcessHandle);
+ }
+ break;
+
+ /* KphTerminateProcess
+ *
+ * Terminates the specified process. This call will never fail unless
+ * PsTerminateProcess could not be located and Zw/NtTerminateProcess
+ * is hooked, or an attempt was made to terminate the current process.
+ * In that case, the call will fail with STATUS_CANT_TERMINATE_SELF.
+ */
+ case KPH_TERMINATEPROCESS:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ NTSTATUS ExitStatus;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphTerminateProcess(args->ProcessHandle, args->ExitStatus);
+ }
+ break;
+
+ /* KphReadVirtualMemory
+ *
+ * Reads process memory.
+ */
+ case KPH_READVIRTUALMEMORY:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ PVOID BaseAddress;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PULONG ReturnLength;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphReadVirtualMemory(
+ args->ProcessHandle,
+ args->BaseAddress,
+ args->Buffer,
+ args->BufferLength,
+ args->ReturnLength,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphWriteVirtualMemory
+ *
+ * Writes to process memory.
+ */
+ case KPH_WRITEVIRTUALMEMORY:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ PVOID BaseAddress;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PULONG ReturnLength;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphWriteVirtualMemory(
+ args->ProcessHandle,
+ args->BaseAddress,
+ args->Buffer,
+ args->BufferLength,
+ args->ReturnLength,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphUnsafeReadVirtualMemory
+ *
+ * Reads process memory or kernel memory.
+ */
+ case KPH_UNSAFEREADVIRTUALMEMORY:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ PVOID BaseAddress;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PULONG ReturnLength;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphUnsafeReadVirtualMemory(
+ args->ProcessHandle,
+ args->BaseAddress,
+ args->Buffer,
+ args->BufferLength,
+ args->ReturnLength,
+ UserMode
+ );
+ }
+ break;
+
/* Get Process Protected
*
* Gets whether the process is protected.
@@ -898,786 +637,6 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
- /* KphTerminateProcess
- *
- * Terminates the specified process. This call will never fail unless
- * PsTerminateProcess could not be located and Zw/NtTerminateProcess
- * is hooked, or an attempt was made to terminate the current process.
- * In that case, the call will fail with STATUS_CANT_TERMINATE_SELF.
- */
- case KPH_TERMINATEPROCESS:
- {
- struct
- {
- HANDLE ProcessHandle;
- NTSTATUS ExitStatus;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphTerminateProcess(args->ProcessHandle, args->ExitStatus);
- }
- break;
-
- /* KphSuspendProcess
- *
- * Suspends the specified process. This call will fail on Windows XP
- * and below.
- */
- case KPH_SUSPENDPROCESS:
- {
- struct
- {
- HANDLE ProcessHandle;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphSuspendProcess(args->ProcessHandle);
- }
- break;
-
- /* KphResumeProcess
- *
- * Resumes the specified process. This call will fail on Windows XP
- * and below.
- */
- case KPH_RESUMEPROCESS:
- {
- struct
- {
- HANDLE ProcessHandle;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphResumeProcess(args->ProcessHandle);
- }
- break;
-
- /* KphReadVirtualMemory
- *
- * Reads process memory.
- */
- case KPH_READVIRTUALMEMORY:
- {
- struct
- {
- HANDLE ProcessHandle;
- PVOID BaseAddress;
- PVOID Buffer;
- ULONG BufferLength;
- PULONG ReturnLength;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphReadVirtualMemory(
- args->ProcessHandle,
- args->BaseAddress,
- args->Buffer,
- args->BufferLength,
- args->ReturnLength,
- UserMode
- );
- }
- break;
-
- /* KphWriteVirtualMemory
- *
- * Writes to process memory.
- */
- case KPH_WRITEVIRTUALMEMORY:
- {
- struct
- {
- HANDLE ProcessHandle;
- PVOID BaseAddress;
- PVOID Buffer;
- ULONG BufferLength;
- PULONG ReturnLength;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphWriteVirtualMemory(
- args->ProcessHandle,
- args->BaseAddress,
- args->Buffer,
- args->BufferLength,
- args->ReturnLength,
- UserMode
- );
- }
- break;
-
- /* Set Process Token
- *
- * Assigns the primary token of a source process to a target process.
- */
- case KPH_SETPROCESSTOKEN:
- {
- struct
- {
- HANDLE SourceProcessId;
- HANDLE TargetProcessId;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = SetProcessToken(args->SourceProcessId, args->TargetProcessId);
- }
- break;
-
- /* Get Thread Start Address
- *
- * Gets the specified thread's start address.
- */
- case KPH_GETTHREADSTARTADDRESS:
- {
- struct
- {
- HANDLE ThreadHandle;
- } *args = dataBuffer;
- struct
- {
- PVOID StartAddress;
- } *ret = dataBuffer;
- PETHREAD threadObject;
-
- CHECK_IN_OUT_LENGTH;
-
- status = ObReferenceObjectByHandle(args->ThreadHandle, 0, *PsThreadType, KernelMode, &threadObject, NULL);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Get the Win32StartAddress */
- if (!(ret->StartAddress = *(PVOID *)KVOFF(threadObject, OffEtWin32StartAddress)))
- {
- /* If that failed, get the StartAddress */
- ret->StartAddress = *(PVOID *)KVOFF(threadObject, OffEtStartAddress);
- }
-
- ObDereferenceObject(threadObject);
- retLength = sizeof(*ret);
- }
- break;
-
- /* Set Handle Attributes
- *
- * Sets handle flags in the specified process.
- */
- case KPH_SETHANDLEATTRIBUTES:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- ULONG Flags;
- } *args = dataBuffer;
- KPH_ATTACH_STATE attachState;
- OBJECT_HANDLE_FLAG_INFORMATION handleFlags = { 0 };
-
- CHECK_IN_LENGTH;
-
- status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- if (args->Flags & OBJ_PROTECT_CLOSE)
- handleFlags.ProtectFromClose = TRUE;
- if (args->Flags & OBJ_INHERIT)
- handleFlags.Inherit = TRUE;
-
- status = ObSetHandleAttributes(args->Handle, &handleFlags, UserMode);
- KphDetachProcess(&attachState);
- }
- break;
-
- /* Get Handle Object Name
- *
- * Gets the name of the specified handle. The handle can be remote; in
- * that case a valid process handle must be passed. Otherwise, set the
- * process handle to -1 (NtCurrentProcess()).
- */
- case KPH_GETHANDLEOBJECTNAME:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } *args = dataBuffer;
- KPH_ATTACH_STATE attachState;
- PVOID object;
-
- CHECK_IN_LENGTH;
-
- status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* See the block for KPH_ZWQUERYOBJECT for information. */
- if (attachState.Process == PsInitialSystemProcess)
- MakeKernelHandle(args->Handle);
-
- status = ObReferenceObjectByHandle(args->Handle, 0, NULL, KernelMode, &object, NULL);
- KphDetachProcess(&attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- status = KphQueryNameObject(object, (PUNICODE_STRING)dataBuffer, outLength, &retLength);
- ObDereferenceObject(object);
-
- /* Check if the return length is greater than the length of the user buffer.
- * If so, it means the user needs to provide a larger buffer. In that case,
- * store the length in the Unicode string structure.
- */
- if (retLength > outLength)
- {
- if (outLength >= sizeof(UNICODE_STRING))
- {
- ((PUNICODE_STRING)dataBuffer)->Length = (USHORT)retLength;
- retLength = sizeof(UNICODE_STRING);
- }
- }
- }
- break;
-
- /* KphOpenProcessJob
- *
- * Opens the job object that the process is assigned to. If the process is
- * not assigned to any job object, the call will fail with STATUS_PROCESS_NOT_IN_JOB.
- */
- case KPH_OPENPROCESSJOB:
- {
- struct
- {
- HANDLE ProcessHandle;
- ACCESS_MASK DesiredAccess;
- } *args = dataBuffer;
- struct
- {
- HANDLE JobHandle;
- } *ret = dataBuffer;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphOpenProcessJob(args->ProcessHandle, args->DesiredAccess, &ret->JobHandle, KernelMode);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphGetContextThread
- *
- * Gets the context of the specified thread.
- */
- case KPH_GETCONTEXTTHREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- PCONTEXT ThreadContext;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphGetContextThread(args->ThreadHandle, args->ThreadContext, UserMode);
- }
- break;
-
- /* KphSetContextThread
- *
- * Sets the context of the specified thread.
- */
- case KPH_SETCONTEXTTHREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- PCONTEXT ThreadContext;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphSetContextThread(args->ThreadHandle, args->ThreadContext, UserMode);
- }
- break;
-
- /* KphGetThreadWin32Thread
- *
- * Gets a pointer to the specified thread's Win32Thread structure.
- */
- case KPH_GETTHREADWIN32THREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- } *args = dataBuffer;
- struct
- {
- PVOID Win32Thread;
- } *ret = dataBuffer;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphGetThreadWin32Thread(args->ThreadHandle, &ret->Win32Thread, KernelMode);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphDuplicateObject
- *
- * Duplicates the specified handle from the source process to the target process.
- * Do not use this call to duplicate file handles; it may freeze indefinitely if
- * the file is a named pipe.
- */
- case KPH_DUPLICATEOBJECT:
- {
- struct
- {
- HANDLE SourceProcessHandle;
- HANDLE SourceHandle;
- HANDLE TargetProcessHandle;
- PHANDLE TargetHandle;
- ACCESS_MASK DesiredAccess;
- ULONG HandleAttributes;
- ULONG Options;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphDuplicateObject(
- args->SourceProcessHandle,
- args->SourceHandle,
- args->TargetProcessHandle,
- args->TargetHandle,
- args->DesiredAccess,
- args->HandleAttributes,
- args->Options,
- UserMode
- );
- }
- break;
-
- /* ZwQueryObject
- *
- * Performs ZwQueryObject in the context of another process.
- */
- case KPH_ZWQUERYOBJECT:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- OBJECT_INFORMATION_CLASS ObjectInformationClass;
- } *args = dataBuffer;
- struct
- {
- NTSTATUS Status;
- ULONG ReturnLength;
- PVOID BufferBase;
- CHAR Buffer[1];
- } *ret = dataBuffer;
- NTSTATUS status2 = STATUS_SUCCESS;
- KPH_ATTACH_STATE attachState;
- BOOLEAN attached;
-
- if (inLength < sizeof(*args) || outLength < sizeof(*ret) - sizeof(CHAR))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- goto IoControlEnd;
- }
-
- status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Are we attached to the system process? If we are,
- * we must set the high bit in the handle to indicate
- * that it is a kernel handle - a new check for this
- * was added in Windows 7.
- */
- if (attachState.Process == PsInitialSystemProcess)
- MakeKernelHandle(args->Handle);
-
- status2 = ZwQueryObject(
- args->Handle,
- args->ObjectInformationClass,
- ret->Buffer,
- outLength - (sizeof(*ret) - sizeof(CHAR)),
- &retLength
- );
- KphDetachProcess(&attachState);
-
- ret->ReturnLength = retLength;
- ret->BufferBase = ret->Buffer;
-
- if (NT_SUCCESS(status2))
- retLength += sizeof(*ret) - sizeof(CHAR);
- else
- retLength = sizeof(*ret) - sizeof(CHAR);
-
- ret->Status = status2;
- }
- break;
-
- /* KphGetProcessId
- *
- * Gets the process ID of a process handle in the context of another process.
- */
- case KPH_GETPROCESSID:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } *args = dataBuffer;
- struct
- {
- HANDLE ProcessId;
- } *ret = dataBuffer;
- KPH_ATTACH_STATE attachState;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- if (attachState.Process == PsInitialSystemProcess)
- MakeKernelHandle(args->Handle);
-
- ret->ProcessId = KphGetProcessId(args->Handle);
- KphDetachProcess(&attachState);
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphGetThreadId
- *
- * Gets the thread ID of a thread handle in the context of another process.
- */
- case KPH_GETTHREADID:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } *args = dataBuffer;
- struct
- {
- HANDLE ThreadId;
- HANDLE ProcessId;
- } *ret = dataBuffer;
- KPH_ATTACH_STATE attachState;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- if (attachState.Process == PsInitialSystemProcess)
- MakeKernelHandle(args->Handle);
-
- ret->ThreadId = KphGetThreadId(args->Handle, &ret->ProcessId);
- KphDetachProcess(&attachState);
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphTerminateThread
- *
- * Terminates the specified thread. This call will fail if
- * PspTerminateThreadByPointer could not be located or if an attempt
- * was made to terminate the current thread. In that case, the call
- * will return STATUS_CANT_TERMINATE_SELF.
- */
- case KPH_TERMINATETHREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- NTSTATUS ExitStatus;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphTerminateThread(args->ThreadHandle, args->ExitStatus);
- }
- break;
-
- /* Get Features
- *
- * Gets the features supported by the driver.
- */
- case KPH_GETFEATURES:
- {
- struct
- {
- ULONG Features;
- } *ret = dataBuffer;
- ULONG features = 0;
-
- CHECK_OUT_LENGTH;
-
- if (__PsTerminateProcess)
- features |= KPHF_PSTERMINATEPROCESS;
- if (__PspTerminateThreadByPointer)
- features |= KPHF_PSPTERMINATETHREADBPYPOINTER;
-
- ret->Features = features;
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphSetHandleGrantedAccess
- *
- * Sets the granted access for a handle.
- */
- case KPH_SETHANDLEGRANTEDACCESS:
- {
- struct
- {
- HANDLE Handle;
- ACCESS_MASK GrantedAccess;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphSetHandleGrantedAccess(
- PsGetCurrentProcess(),
- args->Handle,
- args->GrantedAccess
- );
- }
- break;
-
- /* KphAssignImpersonationToken
- *
- * Assigns an impersonation token to a thread.
- */
- case KPH_ASSIGNIMPERSONATIONTOKEN:
- {
- struct
- {
- HANDLE ThreadHandle;
- HANDLE TokenHandle;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphAssignImpersonationToken(args->ThreadHandle, args->TokenHandle);
- }
- break;
-
- /* Add Process Protection */
- case KPH_PROTECTADD:
- {
- struct
- {
- HANDLE ProcessHandle;
- LOGICAL AllowKernelMode;
- ACCESS_MASK ProcessAllowMask;
- ACCESS_MASK ThreadAllowMask;
- } *args = dataBuffer;
- PEPROCESS processObject;
-
- CHECK_IN_LENGTH;
-
- /* We'll reference the process and then dereference it. That way
- * we can get the address of the object - that's all we need.
- */
-
- status = ObReferenceObjectByHandle(
- args->ProcessHandle,
- 0,
- *PsProcessType,
- KernelMode,
- &processObject,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- ObDereferenceObject(processObject);
-
- InitProtection();
-
- /* Don't protect the same process twice. */
- if (KphProtectFindEntry(processObject, NULL, NULL))
- {
- status = STATUS_NOT_SUPPORTED;
- goto IoControlEnd;
- }
-
- if (!KphProtectAddEntry(
- processObject,
- PsGetCurrentProcessId(),
- args->AllowKernelMode,
- args->ProcessAllowMask,
- args->ThreadAllowMask
- ))
- {
- status = STATUS_UNSUCCESSFUL;
- goto IoControlEnd;
- }
- }
- break;
-
- /* Remove Process Protection */
- case KPH_PROTECTREMOVE:
- {
- struct
- {
- HANDLE ProcessHandle;
- } *args = dataBuffer;
- PEPROCESS processObject;
-
- /* Can't remove anything if process protection hasn't been initialized -
- there isn't anything to remove. */
- if (!ProtectionInitialized)
- {
- status = STATUS_INVALID_PARAMETER;
- goto IoControlEnd;
- }
-
- CHECK_IN_LENGTH;
-
- status = ObReferenceObjectByHandle(
- args->ProcessHandle,
- 0,
- *PsProcessType,
- KernelMode,
- &processObject,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- ObDereferenceObject(processObject);
-
- if (!KphProtectRemoveByProcess(processObject))
- {
- status = STATUS_UNSUCCESSFUL;
- goto IoControlEnd;
- }
- }
- break;
-
- /* Query Process Protection */
- case KPH_PROTECTQUERY:
- {
- struct
- {
- HANDLE ProcessHandle;
- PLOGICAL AllowKernelMode;
- PACCESS_MASK ProcessAllowMask;
- PACCESS_MASK ThreadAllowMask;
- } *args = dataBuffer;
- PEPROCESS processObject;
- KPH_PROCESS_ENTRY processEntry;
-
- /* Can't query anything if process protection hasn't been initialized -
- there isn't anything to query. */
- if (!ProtectionInitialized)
- {
- status = STATUS_INVALID_PARAMETER;
- goto IoControlEnd;
- }
-
- CHECK_IN_LENGTH;
-
- __try
- {
- ProbeForWrite(args->AllowKernelMode, sizeof(LOGICAL), 1);
- ProbeForWrite(args->ProcessAllowMask, sizeof(ACCESS_MASK), 1);
- ProbeForWrite(args->ThreadAllowMask, sizeof(ACCESS_MASK), 1);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- status = GetExceptionCode();
- goto IoControlEnd;
- }
-
- status = ObReferenceObjectByHandle(
- args->ProcessHandle,
- 0,
- *PsProcessType,
- KernelMode,
- &processObject,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- ObDereferenceObject(processObject);
-
- if (!KphProtectFindEntry(processObject, NULL, &processEntry))
- {
- status = STATUS_UNSUCCESSFUL;
- goto IoControlEnd;
- }
-
- __try
- {
- *(args->AllowKernelMode) = processEntry.AllowKernelMode;
- *(args->ProcessAllowMask) = processEntry.ProcessAllowMask;
- *(args->ThreadAllowMask) = processEntry.ThreadAllowMask;
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- status = GetExceptionCode();
- }
- }
- break;
-
- /* KphUnsafeReadVirtualMemory
- *
- * Reads process memory or kernel memory.
- */
- case KPH_UNSAFEREADVIRTUALMEMORY:
- {
- struct
- {
- HANDLE ProcessHandle;
- PVOID BaseAddress;
- PVOID Buffer;
- ULONG BufferLength;
- PULONG ReturnLength;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphUnsafeReadVirtualMemory(
- args->ProcessHandle,
- args->BaseAddress,
- args->Buffer,
- args->BufferLength,
- args->ReturnLength,
- UserMode
- );
- }
- break;
-
/* Set Execute Options
*
* Sets NX status for a process.
@@ -1708,646 +667,21 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
- /* KphQueryProcessHandles
+ /* Set Process Token
*
- * Gets the handles in a process handle table.
+ * Assigns the primary token of a source process to a target process.
*/
- case KPH_QUERYPROCESSHANDLES:
+ case KPH_SETPROCESSTOKEN:
{
struct
{
- HANDLE ProcessHandle;
- PVOID Buffer;
- ULONG BufferLength;
- PULONG ReturnLength;
+ HANDLE SourceProcessId;
+ HANDLE TargetProcessId;
} *args = dataBuffer;
CHECK_IN_LENGTH;
- status = KphQueryProcessHandles(
- args->ProcessHandle,
- (PPROCESS_HANDLE_INFORMATION)args->Buffer,
- args->BufferLength,
- args->ReturnLength,
- UserMode
- );
- }
- break;
-
- /* KphOpenThreadProcess
- *
- * Opens the process associated with the specified thread.
- */
- case KPH_OPENTHREADPROCESS:
- {
- struct
- {
- HANDLE ThreadHandle;
- ACCESS_MASK DesiredAccess;
- } *args = dataBuffer;
- struct
- {
- HANDLE ProcessHandle;
- } *ret = dataBuffer;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphOpenThreadProcess(
- args->ThreadHandle,
- args->DesiredAccess,
- &ret->ProcessHandle,
- KernelMode
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- retLength = sizeof(*ret);
- }
- break;
-
- /* KphCaptureStackBackTraceThread
- *
- * Captures a kernel stack trace for the specified thread.
- */
- case KPH_CAPTURESTACKBACKTRACETHREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- ULONG FramesToSkip;
- ULONG FramesToCapture;
- PVOID *BackTrace;
- PULONG CapturedFrames;
- PULONG BackTraceHash;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphCaptureStackBackTraceThread(
- args->ThreadHandle,
- args->FramesToSkip,
- args->FramesToCapture,
- args->BackTrace,
- args->CapturedFrames,
- args->BackTraceHash,
- UserMode
- );
- }
- break;
-
- /* KphDangerousTerminateThread
- *
- * Terminates the specified thread. This operation may cause a bugcheck.
- */
- case KPH_DANGEROUSTERMINATETHREAD:
- {
- struct
- {
- HANDLE ThreadHandle;
- NTSTATUS ExitStatus;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphDangerousTerminateThread(args->ThreadHandle, args->ExitStatus);
- }
- break;
-
- /* KphOpenType
- *
- * Opens a type object.
- */
- case KPH_OPENTYPE:
- {
- struct
- {
- PHANDLE TypeHandle;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphOpenType(args->TypeHandle, args->ObjectAttributes, UserMode);
- }
- break;
-
- /* KphOpenDriver
- *
- * Opens a driver object.
- */
- case KPH_OPENDRIVER:
- {
- struct
- {
- PHANDLE DriverHandle;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphOpenDriver(args->DriverHandle, args->ObjectAttributes, UserMode);
- }
- break;
-
- /* KphQueryInformationDriver
- *
- * Queries information about a driver object.
- */
- case KPH_QUERYINFORMATIONDRIVER:
- {
- struct
- {
- HANDLE DriverHandle;
- DRIVER_INFORMATION_CLASS DriverInformationClass;
- PVOID DriverInformation;
- ULONG DriverInformationLength;
- PULONG ReturnLength;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphQueryInformationDriver(
- args->DriverHandle,
- args->DriverInformationClass,
- args->DriverInformation,
- args->DriverInformationLength,
- args->ReturnLength,
- UserMode
- );
- }
- break;
-
- /* KphOpenDirectoryObject
- *
- * Opens a directory object.
- */
- case KPH_OPENDIRECTORYOBJECT:
- {
- struct
- {
- PHANDLE DirectoryObjectHandle;
- ACCESS_MASK DesiredAccess;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphOpenDirectoryObject(
- args->DirectoryObjectHandle,
- args->DesiredAccess,
- args->ObjectAttributes,
- UserMode
- );
- }
- break;
-
- /* SsRef
- *
- * Adds a system service logging reference.
- */
- case KPH_SSREF:
- {
- PKPH_CLIENT_ENTRY clientEntry = ReferenceClientEntry(NULL);
-
- if (!clientEntry)
- {
- status = STATUS_INTERNAL_ERROR;
- goto IoControlEnd;
- }
-
- KphAcquireGuardedLock(&clientEntry->SsLock);
-
- if (clientEntry->SsStartCount < KPH_CLIENT_SSMAXCOUNT)
- {
- clientEntry->SsStartCount++;
- SsRef(1);
- }
- else
- {
- status = STATUS_UNSUCCESSFUL;
- }
-
- KphReleaseGuardedLock(&clientEntry->SsLock);
-
- KphDereferenceObject(clientEntry);
- }
- break;
-
- /* SsUnref
- *
- * Removes a system service logging reference.
- */
- case KPH_SSUNREF:
- {
- PKPH_CLIENT_ENTRY clientEntry = ReferenceClientEntry(NULL);
-
- if (!clientEntry)
- {
- status = STATUS_INTERNAL_ERROR;
- goto IoControlEnd;
- }
-
- KphAcquireGuardedLock(&clientEntry->SsLock);
-
- if (clientEntry->SsStartCount > 0)
- {
- clientEntry->SsStartCount--;
- SsUnref(1);
- }
- else
- {
- status = STATUS_UNSUCCESSFUL;
- }
-
- KphReleaseGuardedLock(&clientEntry->SsLock);
-
- KphDereferenceObject(clientEntry);
- }
- break;
-
- /* SsCreateClientEntry
- *
- * Creates a system service logging client entry.
- */
- case KPH_SSCREATECLIENTENTRY:
- {
- struct
- {
- HANDLE ProcessHandle;
- HANDLE EventHandle;
- HANDLE SemaphoreHandle;
- PVOID BufferBase;
- ULONG BufferSize;
- } *args = dataBuffer;
- struct
- {
- HANDLE ClientEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_CLIENT_ENTRY clientEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- status = KphSsCreateClientEntry(
- &clientEntry,
- args->ProcessHandle,
- args->EventHandle,
- args->SemaphoreHandle,
- args->BufferBase,
- args->BufferSize,
- UserMode
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- status = CreateClientHandle(NULL, clientEntry, &ret->ClientEntryHandle);
- KphDereferenceObject(clientEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsCreateRuleSetEntry
- *
- * Creates a system service logging ruleset entry.
- */
- case KPH_SSCREATERULESETENTRY:
- {
- struct
- {
- HANDLE ClientEntryHandle;
- KPHSS_FILTER_TYPE DefaultFilterType;
- KPHSS_RULESET_ACTION Action;
- } *args = dataBuffer;
- struct
- {
- HANDLE RuleSetEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_CLIENT_ENTRY clientEntry;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->ClientEntryHandle,
- KphSsClientEntryType,
- &clientEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Create the ruleset entry. */
- status = KphSsCreateRuleSetEntry(
- &ruleSetEntry,
- clientEntry,
- args->DefaultFilterType,
- args->Action
- );
- KphDereferenceObject(clientEntry);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Create and return a handle to the ruleset entry. */
- status = CreateClientHandle(NULL, ruleSetEntry, &ret->RuleSetEntryHandle);
- KphDereferenceObject(ruleSetEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsRemoveRule
- *
- * Removes a rule from a ruleset.
- */
- case KPH_SSREMOVERULE:
- {
- struct
- {
- HANDLE RuleSetEntryHandle;
- HANDLE RuleEntryHandle;
- } *args = dataBuffer;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
-
- CHECK_IN_LENGTH;
-
- /* Reference the ruleset entry. */
- status = ReferenceClientHandle(
- NULL,
- args->RuleSetEntryHandle,
- KphSsRuleSetEntryType,
- &ruleSetEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Remove the rule. */
- status = KphSsRemoveRule(ruleSetEntry, args->RuleEntryHandle);
- KphDereferenceObject(ruleSetEntry);
- }
- break;
-
- /* SsAddProcessIdRule
- *
- * Adds a process ID rule to a ruleset.
- */
- case KPH_SSADDPROCESSIDRULE:
- {
- struct
- {
- HANDLE RuleSetEntryHandle;
- KPHSS_FILTER_TYPE FilterType;
- HANDLE ProcessId;
- } *args = dataBuffer;
- struct
- {
- HANDLE RuleEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->RuleSetEntryHandle,
- KphSsRuleSetEntryType,
- &ruleSetEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Add a process ID rule. */
- status = KphSsAddProcessIdRule(
- &ruleEntry,
- ruleSetEntry,
- args->FilterType,
- args->ProcessId
- );
- KphDereferenceObject(ruleSetEntry);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Return the rule handle. */
- ret->RuleEntryHandle = KphSsGetHandleRule(ruleEntry);
- KphDereferenceObject(ruleEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsAddThreadIdRule
- *
- * Adds a thread ID rule to a ruleset.
- */
- case KPH_SSADDTHREADIDRULE:
- {
- struct
- {
- HANDLE RuleSetEntryHandle;
- KPHSS_FILTER_TYPE FilterType;
- HANDLE ThreadId;
- } *args = dataBuffer;
- struct
- {
- HANDLE RuleEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->RuleSetEntryHandle,
- KphSsRuleSetEntryType,
- &ruleSetEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Add a thread ID rule. */
- status = KphSsAddThreadIdRule(
- &ruleEntry,
- ruleSetEntry,
- args->FilterType,
- args->ThreadId
- );
- KphDereferenceObject(ruleSetEntry);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Return the rule handle. */
- ret->RuleEntryHandle = KphSsGetHandleRule(ruleEntry);
- KphDereferenceObject(ruleEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsAddPreviousModeRule
- *
- * Adds a previous mode rule to a ruleset.
- */
- case KPH_SSADDPREVIOUSMODERULE:
- {
- struct
- {
- HANDLE RuleSetEntryHandle;
- KPHSS_FILTER_TYPE FilterType;
- KPROCESSOR_MODE PreviousMode;
- } *args = dataBuffer;
- struct
- {
- HANDLE RuleEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->RuleSetEntryHandle,
- KphSsRuleSetEntryType,
- &ruleSetEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Add a previous mode rule. */
- status = KphSsAddPreviousModeRule(
- &ruleEntry,
- ruleSetEntry,
- args->FilterType,
- args->PreviousMode
- );
- KphDereferenceObject(ruleSetEntry);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Return the rule handle. */
- ret->RuleEntryHandle = KphSsGetHandleRule(ruleEntry);
- KphDereferenceObject(ruleEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsAddNumberRule
- *
- * Adds a system service number rule to a ruleset.
- */
- case KPH_SSADDNUMBERRULE:
- {
- struct
- {
- HANDLE RuleSetEntryHandle;
- KPHSS_FILTER_TYPE FilterType;
- ULONG Number;
- } *args = dataBuffer;
- struct
- {
- HANDLE RuleEntryHandle;
- } *ret = dataBuffer;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- CHECK_IN_OUT_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->RuleSetEntryHandle,
- KphSsRuleSetEntryType,
- &ruleSetEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Add a number rule. */
- status = KphSsAddNumberRule(
- &ruleEntry,
- ruleSetEntry,
- args->FilterType,
- args->Number
- );
- KphDereferenceObject(ruleSetEntry);
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Return the rule handle. */
- ret->RuleEntryHandle = KphSsGetHandleRule(ruleEntry);
- KphDereferenceObject(ruleEntry);
- retLength = sizeof(*ret);
- }
- break;
-
- /* SsEnableClientEntry
- *
- * Enables or disables a client entry.
- */
- case KPH_SSENABLECLIENTENTRY:
- {
- struct
- {
- HANDLE ClientEntryHandle;
- BOOLEAN Enable;
- } *args = dataBuffer;
- PKPHSS_CLIENT_ENTRY clientEntry;
-
- CHECK_IN_LENGTH;
-
- /* Reference the client entry. */
- status = ReferenceClientHandle(
- NULL,
- args->ClientEntryHandle,
- KphSsClientEntryType,
- &clientEntry
- );
-
- if (!NT_SUCCESS(status))
- goto IoControlEnd;
-
- /* Enable/disable the client entry. */
- status = KphSsEnableClientEntry(clientEntry, args->Enable);
- KphDereferenceObject(clientEntry);
- }
- break;
-
- /* KphOpenNamedObject
- *
- * Opens a named object of any type.
- */
- case KPH_OPENNAMEDOBJECT:
- {
- struct
- {
- PHANDLE Handle;
- ACCESS_MASK DesiredAccess;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } *args = dataBuffer;
-
- CHECK_IN_LENGTH;
-
- status = KphOpenNamedObject(
- args->Handle,
- args->DesiredAccess,
- args->ObjectAttributes,
- NULL,
- UserMode
- );
+ status = SetProcessToken(args->SourceProcessId, args->TargetProcessId);
}
break;
@@ -2385,6 +719,7 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
goto IoControlEnd;
}
+ /* Very unsafe and implementation dependent, but it should work. */
__try
{
status = ZwQueryInformationProcess(
@@ -2545,6 +880,635 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
break;
+ /* KphOpenThread
+ *
+ * Opens the specified thread. This call will never fail unless:
+ * 1. PsLookupProcessThreadByCid, ObOpenObjectByPointer or some lower-level
+ * function is hooked, or
+ * 2. The thread's process is protected.
+ */
+ case KPH_OPENTHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadId;
+ ACCESS_MASK DesiredAccess;
+ } *args = dataBuffer;
+ struct
+ {
+ HANDLE ThreadHandle;
+ } *ret = dataBuffer;
+ OBJECT_ATTRIBUTES objectAttributes = { 0 };
+ CLIENT_ID clientId;
+
+ CHECK_IN_OUT_LENGTH;
+
+ clientId.UniqueThread = args->ThreadId;
+ clientId.UniqueProcess = 0;
+ status = KphOpenThread(
+ &ret->ThreadHandle,
+ args->DesiredAccess,
+ &objectAttributes,
+ &clientId,
+ KernelMode
+ );
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphOpenThreadProcess
+ *
+ * Opens the process associated with the specified thread.
+ */
+ case KPH_OPENTHREADPROCESS:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ ACCESS_MASK DesiredAccess;
+ } *args = dataBuffer;
+ struct
+ {
+ HANDLE ProcessHandle;
+ } *ret = dataBuffer;
+
+ CHECK_IN_OUT_LENGTH;
+
+ status = KphOpenThreadProcess(
+ args->ThreadHandle,
+ args->DesiredAccess,
+ &ret->ProcessHandle,
+ KernelMode
+ );
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphTerminateThread
+ *
+ * Terminates the specified thread. This call will fail if
+ * PspTerminateThreadByPointer could not be located or if an attempt
+ * was made to terminate the current thread. In that case, the call
+ * will return STATUS_CANT_TERMINATE_SELF.
+ */
+ case KPH_TERMINATETHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ NTSTATUS ExitStatus;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphTerminateThread(args->ThreadHandle, args->ExitStatus);
+ }
+ break;
+
+ /* KphDangerousTerminateThread
+ *
+ * Terminates the specified thread. This operation may cause a bugcheck.
+ */
+ case KPH_DANGEROUSTERMINATETHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ NTSTATUS ExitStatus;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphDangerousTerminateThread(args->ThreadHandle, args->ExitStatus);
+ }
+ break;
+
+ /* KphGetContextThread
+ *
+ * Gets the context of the specified thread.
+ */
+ case KPH_GETCONTEXTTHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ PCONTEXT ThreadContext;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphGetContextThread(args->ThreadHandle, args->ThreadContext, UserMode);
+ }
+ break;
+
+ /* KphSetContextThread
+ *
+ * Sets the context of the specified thread.
+ */
+ case KPH_SETCONTEXTTHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ PCONTEXT ThreadContext;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphSetContextThread(args->ThreadHandle, args->ThreadContext, UserMode);
+ }
+ break;
+
+ /* KphCaptureStackBackTraceThread
+ *
+ * Captures a kernel stack trace for the specified thread.
+ */
+ case KPH_CAPTURESTACKBACKTRACETHREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ ULONG FramesToSkip;
+ ULONG FramesToCapture;
+ PVOID *BackTrace;
+ PULONG CapturedFrames;
+ PULONG BackTraceHash;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphCaptureStackBackTraceThread(
+ args->ThreadHandle,
+ args->FramesToSkip,
+ args->FramesToCapture,
+ args->BackTrace,
+ args->CapturedFrames,
+ args->BackTraceHash,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphGetThreadWin32Thread
+ *
+ * Gets a pointer to the specified thread's Win32Thread structure.
+ */
+ case KPH_GETTHREADWIN32THREAD:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ } *args = dataBuffer;
+ struct
+ {
+ PVOID Win32Thread;
+ } *ret = dataBuffer;
+
+ CHECK_IN_OUT_LENGTH;
+
+ status = KphGetThreadWin32Thread(args->ThreadHandle, &ret->Win32Thread, KernelMode);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphAssignImpersonationToken
+ *
+ * Assigns an impersonation token to a thread.
+ */
+ case KPH_ASSIGNIMPERSONATIONTOKEN:
+ {
+ struct
+ {
+ HANDLE ThreadHandle;
+ HANDLE TokenHandle;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphAssignImpersonationToken(args->ThreadHandle, args->TokenHandle);
+ }
+ break;
+
+ /* KphQueryProcessHandles
+ *
+ * Gets the handles in a process handle table.
+ */
+ case KPH_QUERYPROCESSHANDLES:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PULONG ReturnLength;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphQueryProcessHandles(
+ args->ProcessHandle,
+ (PPROCESS_HANDLE_INFORMATION)args->Buffer,
+ args->BufferLength,
+ args->ReturnLength,
+ UserMode
+ );
+ }
+ break;
+
+ /* Get Handle Object Name
+ *
+ * Gets the name of the specified handle. The handle can be remote; in
+ * that case a valid process handle must be passed. Otherwise, set the
+ * process handle to -1 (NtCurrentProcess()).
+ */
+ case KPH_GETHANDLEOBJECTNAME:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } *args = dataBuffer;
+ KPH_ATTACH_STATE attachState;
+ PVOID object;
+
+ CHECK_IN_LENGTH;
+
+ status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ /* See the block for KPH_ZWQUERYOBJECT for information. */
+ if (attachState.Process == PsInitialSystemProcess)
+ MakeKernelHandle(args->Handle);
+
+ status = ObReferenceObjectByHandle(args->Handle, 0, NULL, KernelMode, &object, NULL);
+ KphDetachProcess(&attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ status = KphQueryNameObject(object, (PUNICODE_STRING)dataBuffer, outLength, &retLength);
+ ObDereferenceObject(object);
+
+ /* Check if the return length is greater than the length of the user buffer.
+ * If so, it means the user needs to provide a larger buffer. In that case,
+ * store the length in the Unicode string structure.
+ */
+ if (retLength > outLength)
+ {
+ if (outLength >= sizeof(UNICODE_STRING))
+ {
+ ((PUNICODE_STRING)dataBuffer)->Length = (USHORT)retLength;
+ retLength = sizeof(UNICODE_STRING);
+ }
+ }
+ }
+ break;
+
+ /* ZwQueryObject
+ *
+ * Performs ZwQueryObject in the context of another process.
+ */
+ case KPH_ZWQUERYOBJECT:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ OBJECT_INFORMATION_CLASS ObjectInformationClass;
+ } *args = dataBuffer;
+ struct
+ {
+ NTSTATUS Status;
+ ULONG ReturnLength;
+ PVOID BufferBase;
+ CHAR Buffer[1];
+ } *ret = dataBuffer;
+ NTSTATUS status2 = STATUS_SUCCESS;
+ KPH_ATTACH_STATE attachState;
+ BOOLEAN attached;
+
+ if (inLength < sizeof(*args) || outLength < sizeof(*ret) - sizeof(CHAR))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ goto IoControlEnd;
+ }
+
+ status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ /* Are we attached to the system process? If we are,
+ * we must set the high bit in the handle to indicate
+ * that it is a kernel handle - a new check for this
+ * was added in Windows 7.
+ */
+ if (attachState.Process == PsInitialSystemProcess)
+ MakeKernelHandle(args->Handle);
+
+ status2 = ZwQueryObject(
+ args->Handle,
+ args->ObjectInformationClass,
+ ret->Buffer,
+ outLength - (sizeof(*ret) - sizeof(CHAR)),
+ &retLength
+ );
+ KphDetachProcess(&attachState);
+
+ ret->ReturnLength = retLength;
+ ret->BufferBase = ret->Buffer;
+
+ if (NT_SUCCESS(status2))
+ retLength += sizeof(*ret) - sizeof(CHAR);
+ else
+ retLength = sizeof(*ret) - sizeof(CHAR);
+
+ ret->Status = status2;
+ }
+ break;
+
+ /* KphDuplicateObject
+ *
+ * Duplicates the specified handle from the source process to the target process.
+ * Do not use this call to duplicate file handles; it may freeze indefinitely if
+ * the file is a named pipe.
+ */
+ case KPH_DUPLICATEOBJECT:
+ {
+ struct
+ {
+ HANDLE SourceProcessHandle;
+ HANDLE SourceHandle;
+ HANDLE TargetProcessHandle;
+ PHANDLE TargetHandle;
+ ACCESS_MASK DesiredAccess;
+ ULONG HandleAttributes;
+ ULONG Options;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphDuplicateObject(
+ args->SourceProcessHandle,
+ args->SourceHandle,
+ args->TargetProcessHandle,
+ args->TargetHandle,
+ args->DesiredAccess,
+ args->HandleAttributes,
+ args->Options,
+ UserMode
+ );
+ }
+ break;
+
+ /* Set Handle Attributes
+ *
+ * Sets handle flags in the specified process.
+ */
+ case KPH_SETHANDLEATTRIBUTES:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ ULONG Flags;
+ } *args = dataBuffer;
+ KPH_ATTACH_STATE attachState;
+ OBJECT_HANDLE_FLAG_INFORMATION handleFlags = { 0 };
+
+ CHECK_IN_LENGTH;
+
+ status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ if (args->Flags & OBJ_PROTECT_CLOSE)
+ handleFlags.ProtectFromClose = TRUE;
+ if (args->Flags & OBJ_INHERIT)
+ handleFlags.Inherit = TRUE;
+
+ status = ObSetHandleAttributes(args->Handle, &handleFlags, UserMode);
+ KphDetachProcess(&attachState);
+ }
+ break;
+
+ /* KphSetHandleGrantedAccess
+ *
+ * Sets the granted access for a handle.
+ */
+ case KPH_SETHANDLEGRANTEDACCESS:
+ {
+ struct
+ {
+ HANDLE Handle;
+ ACCESS_MASK GrantedAccess;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphSetHandleGrantedAccess(
+ PsGetCurrentProcess(),
+ args->Handle,
+ args->GrantedAccess
+ );
+ }
+ break;
+
+ /* KphGetProcessId
+ *
+ * Gets the process ID of a process handle in the context of another process.
+ */
+ case KPH_GETPROCESSID:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } *args = dataBuffer;
+ struct
+ {
+ HANDLE ProcessId;
+ } *ret = dataBuffer;
+ KPH_ATTACH_STATE attachState;
+
+ CHECK_IN_OUT_LENGTH;
+
+ status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ if (attachState.Process == PsInitialSystemProcess)
+ MakeKernelHandle(args->Handle);
+
+ ret->ProcessId = KphGetProcessId(args->Handle);
+ KphDetachProcess(&attachState);
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphGetThreadId
+ *
+ * Gets the thread ID of a thread handle in the context of another process.
+ */
+ case KPH_GETTHREADID:
+ {
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } *args = dataBuffer;
+ struct
+ {
+ HANDLE ThreadId;
+ HANDLE ProcessId;
+ } *ret = dataBuffer;
+ KPH_ATTACH_STATE attachState;
+
+ CHECK_IN_OUT_LENGTH;
+
+ status = KphAttachProcessHandle(args->ProcessHandle, &attachState);
+
+ if (!NT_SUCCESS(status))
+ goto IoControlEnd;
+
+ if (attachState.Process == PsInitialSystemProcess)
+ MakeKernelHandle(args->Handle);
+
+ ret->ThreadId = KphGetThreadId(args->Handle, &ret->ProcessId);
+ KphDetachProcess(&attachState);
+ retLength = sizeof(*ret);
+ }
+ break;
+
+ /* KphOpenNamedObject
+ *
+ * Opens a named object of any type.
+ */
+ case KPH_OPENNAMEDOBJECT:
+ {
+ struct
+ {
+ PHANDLE Handle;
+ ACCESS_MASK DesiredAccess;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphOpenNamedObject(
+ args->Handle,
+ args->DesiredAccess,
+ args->ObjectAttributes,
+ NULL,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphOpenDirectoryObject
+ *
+ * Opens a directory object.
+ */
+ case KPH_OPENDIRECTORYOBJECT:
+ {
+ struct
+ {
+ PHANDLE DirectoryObjectHandle;
+ ACCESS_MASK DesiredAccess;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphOpenDirectoryObject(
+ args->DirectoryObjectHandle,
+ args->DesiredAccess,
+ args->ObjectAttributes,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphOpenDriver
+ *
+ * Opens a driver object.
+ */
+ case KPH_OPENDRIVER:
+ {
+ struct
+ {
+ PHANDLE DriverHandle;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphOpenDriver(args->DriverHandle, args->ObjectAttributes, UserMode);
+ }
+ break;
+
+ /* KphQueryInformationDriver
+ *
+ * Queries information about a driver object.
+ */
+ case KPH_QUERYINFORMATIONDRIVER:
+ {
+ struct
+ {
+ HANDLE DriverHandle;
+ DRIVER_INFORMATION_CLASS DriverInformationClass;
+ PVOID DriverInformation;
+ ULONG DriverInformationLength;
+ PULONG ReturnLength;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphQueryInformationDriver(
+ args->DriverHandle,
+ args->DriverInformationClass,
+ args->DriverInformation,
+ args->DriverInformationLength,
+ args->ReturnLength,
+ UserMode
+ );
+ }
+ break;
+
+ /* KphOpenType
+ *
+ * Opens a type object.
+ */
+ case KPH_OPENTYPE:
+ {
+ struct
+ {
+ PHANDLE TypeHandle;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } *args = dataBuffer;
+
+ CHECK_IN_LENGTH;
+
+ status = KphOpenType(args->TypeHandle, args->ObjectAttributes, UserMode);
+ }
+ break;
+
default:
{
dprintf("Unrecognized IOCTL code 0x%08x\n", controlCode);
diff --git a/2.x/trunk/KProcessHacker/mm.c b/2.x/trunk/KProcessHacker/mm.c
index 84492ab34..ddd2e86f8 100644
--- a/2.x/trunk/KProcessHacker/mm.c
+++ b/2.x/trunk/KProcessHacker/mm.c
@@ -21,7 +21,6 @@
*/
#include "include/kph.h"
-#include "include/mm.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KphReadVirtualMemory)
diff --git a/2.x/trunk/KProcessHacker/ob.c b/2.x/trunk/KProcessHacker/ob.c
index e5325b95e..022191720 100644
--- a/2.x/trunk/KProcessHacker/ob.c
+++ b/2.x/trunk/KProcessHacker/ob.c
@@ -21,7 +21,6 @@
*/
#include "include/kph.h"
-#include "include/ob.h"
BOOLEAN KphpQueryProcessHandlesEnumCallback(
__inout PHANDLE_TABLE_ENTRY HandleTableEntry,
@@ -759,6 +758,20 @@ NTSTATUS ObDuplicateObject(
return STATUS_INVALID_PARAMETER;
}
+ /* Closing handles in the current process from kernel-mode is *bad* */
+ /* Example: the handle being closed is a handle to the file object
+ * on which this very request is being sent. Deadlock.
+ *
+ * If we add the current process check, the handle can't possibly
+ * be the one the request is being sent on, since system calls
+ * only operate on handles from the current process.
+ */
+ if (SourceProcess == PsGetCurrentProcess())
+ {
+ if (Options & DUPLICATE_CLOSE_SOURCE)
+ return STATUS_CANT_TERMINATE_SELF;
+ }
+
/* Check if we need to attach to the source process */
if (SourceProcess != PsGetCurrentProcess())
{
diff --git a/2.x/trunk/KProcessHacker/protect.c b/2.x/trunk/KProcessHacker/protect.c
deleted file mode 100644
index 406c32019..000000000
--- a/2.x/trunk/KProcessHacker/protect.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Process Hacker Driver -
- * process protection
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#include "include/protect.h"
-
-BOOLEAN KphpIsAccessAllowed(
- __in PVOID Object,
- __in KPROCESSOR_MODE AccessMode,
- __in ACCESS_MASK DesiredAccess
- );
-
-BOOLEAN KphpIsCurrentProcessProtected();
-
-VOID KphpProtectRemoveEntry(
- __in PKPH_PROCESS_ENTRY Entry
- );
-
-/* ProtectedProcessRundownProtect
- *
- * Rundown protection making sure this module doesn't deinitialize before all hook targets
- * have finished executing and no one is accessing the lookaside list.
- */
-static EX_RUNDOWN_REF ProtectedProcessRundownProtect;
-/* ProtectedProcessListHead
- *
- * The head of the process protection linked list. Each entry stores protection
- * information for a process.
- */
-static LIST_ENTRY ProtectedProcessListHead;
-/* ProtectedProcessListLock
- *
- * The spinlock which protects all accesses to the protected process list (even
- * the individual entries)
- */
-static KSPIN_LOCK ProtectedProcessListLock;
-/* ProtectedProcessLookasideList
- *
- * The lookaside list for protected process entries.
- */
-static NPAGED_LOOKASIDE_LIST ProtectedProcessLookasideList;
-
-static KPH_OB_OPEN_HOOK ProcessOpenHook = { 0 };
-static KPH_OB_OPEN_HOOK ThreadOpenHook = { 0 };
-
-/* KphProtectInit
- *
- * Initializes process protection.
- *
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphProtectInit()
-{
- NTSTATUS status;
-
- /* Initialize rundown protection. */
- ExInitializeRundownProtection(&ProtectedProcessRundownProtect);
- /* Initialize list structures. */
- InitializeListHead(&ProtectedProcessListHead);
- KeInitializeSpinLock(&ProtectedProcessListLock);
- ExInitializeNPagedLookasideList(
- &ProtectedProcessLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(KPH_PROCESS_ENTRY),
- TAG_PROTECTION_ENTRY,
- 0
- );
-
- /* Hook various functions. */
- /* Hooking the open procedure calls for processes and threads allows
- * us to intercept handle creation/duplication/inheritance. */
- KphInitializeObOpenHook(&ProcessOpenHook, *PsProcessType, KphNewOpenProcedure51, KphNewOpenProcedure60);
- if (!NT_SUCCESS(status = KphObOpenHook(&ProcessOpenHook)))
- return status;
- KphInitializeObOpenHook(&ThreadOpenHook, *PsThreadType, KphNewOpenProcedure51, KphNewOpenProcedure60);
- if (!NT_SUCCESS(status = KphObOpenHook(&ThreadOpenHook)))
- return status;
-
- return STATUS_SUCCESS;
-}
-
-/* KphProtectDeinit
- *
- * Removes process protection and frees associated structures.
- *
- * IRQL: <= APC_LEVEL
- */
-NTSTATUS KphProtectDeinit()
-{
- NTSTATUS status = STATUS_SUCCESS;
- KIRQL oldIrql;
- LARGE_INTEGER waitLi;
-
- /* Unhook. */
- status = KphObOpenUnhook(&ProcessOpenHook);
- status = KphObOpenUnhook(&ThreadOpenHook);
-
- /* Wait for all activity to finish. */
- ExWaitForRundownProtectionRelease(&ProtectedProcessRundownProtect);
- /* Wait for a bit (some regions of hook target functions
- are NOT guarded by rundown protection, e.g.
- prologues and epilogues). */
- waitLi.QuadPart = KPH_REL_TIMEOUT_IN_SEC(1);
- KeDelayExecutionThread(KernelMode, FALSE, &waitLi);
-
- /* Free all process protection entries. */
- ExDeleteNPagedLookasideList(&ProtectedProcessLookasideList);
-
- return status;
-}
-
-/* KphNewOpenProcedure51
- *
- * New process/thread open procedure for NT 5.1.
- */
-NTSTATUS NTAPI KphNewOpenProcedure51(
- __in OB_OPEN_REASON OpenReason,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- )
-{
- /* Simply call the 6.0 open procedure. */
- /* NOTE: GrantedAccess is always 0 on XP... */
- return KphNewOpenProcedure60(
- OpenReason,
- /* Assume worst case. */
- UserMode,
- Process,
- Object,
- GrantedAccess,
- HandleCount
- );
-}
-
-/* KphNewOpenProcedure60
- *
- * New process/thread open procedure for NT 6.0 and 6.1.
- */
-NTSTATUS NTAPI KphNewOpenProcedure60(
- __in OB_OPEN_REASON OpenReason,
- __in KPROCESSOR_MODE AccessMode,
- __in PEPROCESS Process,
- __in PVOID Object,
- __in ACCESS_MASK GrantedAccess,
- __in ULONG HandleCount
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- BOOLEAN accessAllowed = TRUE;
-
- /* Prevent the driver from unloading while this routine is executing. */
- if (!ExAcquireRundownProtection(&ProtectedProcessRundownProtect))
- {
- /* Should never happen. */
- return STATUS_INTERNAL_ERROR;
- }
-
- accessAllowed = KphpIsAccessAllowed(
- Object,
- AccessMode,
- /* Assume worst case if granted access not available. */
- !GrantedAccess ? (ACCESS_MASK)-1 : GrantedAccess
- );
-
- if (accessAllowed)
- {
- POBJECT_TYPE objectType = KphGetObjectTypeNt(Object);
-
- /* Call the original open procedure. There shouldn't be any for Windows XP,
- * while on Windows Vista and 7 it is used for implementing protected
- * processes (Big Content's DRM protection, not KProcessHacker's protection).
- */
- status = KphObOpenCall(
- objectType == *PsProcessType ? &ProcessOpenHook : &ThreadOpenHook,
- OpenReason,
- AccessMode,
- Process,
- Object,
- GrantedAccess,
- HandleCount
- );
- }
- else
- {
- dprintf("KphNewOpenProcedure60: Access denied.\n");
- status = STATUS_ACCESS_DENIED;
- }
-
- ExReleaseRundownProtection(&ProtectedProcessRundownProtect);
-
- return status;
-}
-
-/* KphProtectAddEntry
- *
- * Protects the specified process.
- *
- * Thread safety: Full
- * IRQL: <= DISPATCH_LEVEL
- */
-PKPH_PROCESS_ENTRY KphProtectAddEntry(
- __in PEPROCESS Process,
- __in HANDLE Tag,
- __in LOGICAL AllowKernelMode,
- __in ACCESS_MASK ProcessAllowMask,
- __in ACCESS_MASK ThreadAllowMask
- )
-{
- KIRQL oldIrql;
- PKPH_PROCESS_ENTRY entry;
-
- /* Prevent the lookaside list from being freed. */
- if (!ExAcquireRundownProtection(&ProtectedProcessRundownProtect))
- return NULL;
-
- entry = ExAllocateFromNPagedLookasideList(&ProtectedProcessLookasideList);
- /* Lookaside list no longer needed. */
- ExReleaseRundownProtection(&ProtectedProcessRundownProtect);
-
- if (!entry)
- return NULL;
-
- entry->Process = Process;
- entry->CreatorProcess = PsGetCurrentProcess();
- entry->Tag = Tag;
- entry->AllowKernelMode = AllowKernelMode;
- entry->ProcessAllowMask = ProcessAllowMask;
- entry->ThreadAllowMask = ThreadAllowMask;
-
- KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
- InsertHeadList(&ProtectedProcessListHead, &entry->ListEntry);
- KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
-
- return entry;
-}
-
-/* KphProtectFindEntry
- *
- * Finds process protection data.
- *
- * Thread safety: Full/Limited. The returned pointer is not guaranteed to
- * point to a valid process entry. However, the copied entry is safe to
- * read.
- * IRQL: <= DISPATCH_LEVEL
- */
-PKPH_PROCESS_ENTRY KphProtectFindEntry(
- __in PEPROCESS Process,
- __in HANDLE Tag,
- __out_opt PKPH_PROCESS_ENTRY ProcessEntryCopy
- )
-{
- KIRQL oldIrql;
- PLIST_ENTRY entry = ProtectedProcessListHead.Flink;
-
- KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
-
- while (entry != &ProtectedProcessListHead)
- {
- PKPH_PROCESS_ENTRY processEntry =
- CONTAINING_RECORD(entry, KPH_PROCESS_ENTRY, ListEntry);
-
- if (
- (Process != NULL && processEntry->Process == Process) ||
- (Tag != NULL && processEntry->Tag == Tag)
- )
- {
- /* Copy the entry if requested. */
- if (ProcessEntryCopy)
- memcpy(ProcessEntryCopy, processEntry, sizeof(KPH_PROCESS_ENTRY));
-
- KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
-
- return processEntry;
- }
-
- entry = entry->Flink;
- }
-
- KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
-
- return NULL;
-}
-
-/* KphProtectRemoveByProcess
- *
- * Removes protection from the specified process.
- *
- * Thread safety: Limited. Callers must synchronize remove calls such
- * as KphProtectRemoveByProcess and KphProtectRemoveByTag.
- * IRQL: <= DISPATCH_LEVEL
- */
-BOOLEAN KphProtectRemoveByProcess(
- __in PEPROCESS Process
- )
-{
- PKPH_PROCESS_ENTRY entry = KphProtectFindEntry(Process, NULL, NULL);
-
- if (!entry)
- return FALSE;
-
- KphpProtectRemoveEntry(entry);
-
- return TRUE;
-}
-
-/* KphProtectRemoveByTag
- *
- * Removes protection from all processes with the specified tag.
- *
- * Thread safety: Limited. Callers must synchronize remove calls such
- * as KphProtectRemoveByProcess and KphProtectRemoveByTag.
- * IRQL: <= DISPATCH_LEVEL
- */
-ULONG KphProtectRemoveByTag(
- __in HANDLE Tag
- )
-{
- KIRQL oldIrql;
- ULONG count = 0;
- PKPH_PROCESS_ENTRY entry;
-
- /* Keep removing entries until we can't find any more. */
- while (entry = KphProtectFindEntry(NULL, Tag, NULL))
- {
- KphpProtectRemoveEntry(entry);
- count++;
- }
-
- return count;
-}
-
-/* KphpIsAccessAllowed
- *
- * Checks if the specified access is allowed, according to process
- * protection rules.
- *
- * Thread safety: Full
- * IRQL: <= DISPATCH_LEVEL
- */
-BOOLEAN KphpIsAccessAllowed(
- __in PVOID Object,
- __in KPROCESSOR_MODE AccessMode,
- __in ACCESS_MASK DesiredAccess
- )
-{
- POBJECT_TYPE objectType;
- PEPROCESS processObject;
- BOOLEAN isThread = FALSE;
-
- objectType = KphGetObjectTypeNt(Object);
- /* It doesn't matter if it isn't actually a process because we won't be
- dereferencing it. */
- processObject = (PEPROCESS)Object;
- isThread = objectType == *PsThreadType;
-
- /* If this is a thread, get its parent process. */
- if (isThread)
- processObject = IoThreadToProcess((PETHREAD)Object);
-
- if (
- processObject != PsGetCurrentProcess() && /* let the caller open its own processes/threads */
- (objectType == *PsProcessType || objectType == *PsThreadType) /* only protect processes and threads */
- )
- {
- KPH_PROCESS_ENTRY processEntry;
-
- /* Search for and copy the corresponding process protection entry. */
- if (KphProtectFindEntry(processObject, NULL, &processEntry))
- {
- ACCESS_MASK mask =
- isThread ? processEntry.ThreadAllowMask : processEntry.ProcessAllowMask;
-
- /* The process/thread is protected. Check if the requested access is allowed. */
- if (
- /* check if kernel-mode is exempt from protection */
- !(processEntry.AllowKernelMode && AccessMode == KernelMode) &&
- /* allow the creator of the rule to bypass protection */
- processEntry.CreatorProcess != PsGetCurrentProcess() &&
- (DesiredAccess & mask) != DesiredAccess
- )
- {
- /* Access denied. */
- dprintf(
- "%d: Access denied: 0x%08x (%s)\n",
- PsGetCurrentProcessId(),
- DesiredAccess,
- isThread ? "Thread" : "Process"
- );
-
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-/* KphpIsCurrentProcessProtected
- *
- * Determines whether the current process is protected.
- *
- * Thread safety: Full
- * IRQL: <= DISPATCH_LEVEL
- */
-BOOLEAN KphpIsCurrentProcessProtected()
-{
- return KphProtectFindEntry(PsGetCurrentProcess(), NULL, NULL) != NULL;
-}
-
-/* KphpProtectRemoveEntry
- *
- * Removes and frees process protection data.
- *
- * Thread safety: Full
- * IRQL: <= DISPATCH_LEVEL
- */
-VOID KphpProtectRemoveEntry(
- __in PKPH_PROCESS_ENTRY Entry
- )
-{
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&ProtectedProcessListLock, &oldIrql);
- RemoveEntryList(&Entry->ListEntry);
-
- /* Prevent the lookaside list from being destroyed. */
- ExAcquireRundownProtection(&ProtectedProcessRundownProtect);
- ExFreeToNPagedLookasideList(
- &ProtectedProcessLookasideList,
- Entry
- );
- ExReleaseRundownProtection(&ProtectedProcessRundownProtect);
-
- KeReleaseSpinLock(&ProtectedProcessListLock, oldIrql);
-}
diff --git a/2.x/trunk/KProcessHacker/ps.c b/2.x/trunk/KProcessHacker/ps.c
index c5662d7e3..0ce9f4b4a 100644
--- a/2.x/trunk/KProcessHacker/ps.c
+++ b/2.x/trunk/KProcessHacker/ps.c
@@ -21,8 +21,6 @@
*/
#include "include/kph.h"
-#include "include/ke.h"
-#include "include/ps.h"
VOID NTAPI KphpCaptureStackBackTraceThreadSpecialApc(
PKAPC Apc,
@@ -1063,14 +1061,20 @@ NTSTATUS KphTerminateProcess(
{
/* Otherwise, we'll have to call ZwTerminateProcess - most hooks on this function
allow kernel-mode callers through. */
- OBJECT_ATTRIBUTES objectAttributes = { 0 };
+ OBJECT_ATTRIBUTES oa;
CLIENT_ID clientId;
HANDLE newProcessHandle;
- /* We have to open it again because ZwTerminateProcess only accepts kernel handles. */
+ InitializeObjectAttributes(
+ &oa,
+ NULL,
+ OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
clientId.UniqueThread = 0;
clientId.UniqueProcess = PsGetProcessId(processObject);
- status = KphOpenProcess(&newProcessHandle, 0x1, &objectAttributes, &clientId, KernelMode);
+ status = KphOpenProcess(&newProcessHandle, PROCESS_TERMINATE, &oa, &clientId, KernelMode);
ObDereferenceObject(processObject);
if (NT_SUCCESS(status))
@@ -1112,10 +1116,7 @@ NTSTATUS KphTerminateThread(
ObDereferenceObject(threadObject);
}
else
- {/*
- ObDereferenceObject(threadObject);
- status = PspTerminateThreadByPointer(PsGetCurrentThread(), ExitStatus); */
- /* Leads to bugs, so don't terminate self. */
+ {
ObDereferenceObject(threadObject);
return STATUS_CANT_TERMINATE_SELF;
}
diff --git a/2.x/trunk/KProcessHacker/ref.c b/2.x/trunk/KProcessHacker/ref.c
index 5476d6749..bb99d5608 100644
--- a/2.x/trunk/KProcessHacker/ref.c
+++ b/2.x/trunk/KProcessHacker/ref.c
@@ -20,6 +20,9 @@
* along with Process Hacker. If not, see .
*/
+#define _REF_PRIVATE
+#include "include/kph.h"
+#include "include/ref.h"
#include "include/refp.h"
/* A list of all objects created by the object manager. */
diff --git a/2.x/trunk/KProcessHacker/resource.rc b/2.x/trunk/KProcessHacker/resource.rc
index d38b333d6..8317e1c5f 100644
--- a/2.x/trunk/KProcessHacker/resource.rc
+++ b/2.x/trunk/KProcessHacker/resource.rc
@@ -1,7 +1,7 @@
#include
-#define VER_COMMA 1,10,0,0
-#define VER_STR "1.10\0"
+#define VER_COMMA 2,0,0,0
+#define VER_STR "2.0\0"
#define VER_FILEVERSION VER_COMMA
#define VER_FILEVERSION_STR VER_STR
diff --git a/2.x/trunk/KProcessHacker/se.c b/2.x/trunk/KProcessHacker/se.c
index ce09c6607..f6a97a0ed 100644
--- a/2.x/trunk/KProcessHacker/se.c
+++ b/2.x/trunk/KProcessHacker/se.c
@@ -21,7 +21,6 @@
*/
#include "include/kph.h"
-#include "include/se.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KphOpenProcessTokenEx)
diff --git a/2.x/trunk/KProcessHacker/sources b/2.x/trunk/KProcessHacker/sources
index ff6e07b5e..e7d9e7392 100644
--- a/2.x/trunk/KProcessHacker/sources
+++ b/2.x/trunk/KProcessHacker/sources
@@ -10,13 +10,7 @@ SOURCES= \
version.c \
\
kph.c \
- handle.c \
- hook.c \
- protect.c \
ref.c \
- sync.c \
- sysservice.c \
- sysservicedata.c \
test.c \
trace.c \
util.c \
diff --git a/2.x/trunk/KProcessHacker/sync.c b/2.x/trunk/KProcessHacker/sync.c
deleted file mode 100644
index 99bd46bf8..000000000
--- a/2.x/trunk/KProcessHacker/sync.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Process Hacker Driver -
- * synchronization code
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#include "include/sync.h"
-#include "include/debug.h"
-
-ULONG KphpCountBits(
- __in ULONG_PTR Number
- );
-
-VOID KphpProcessorLockDpc(
- __in PKDPC Dpc,
- __in PVOID DeferredContext,
- __in PVOID SystemArgument1,
- __in PVOID SystemArgument2
- );
-
-/* KphfAcquireGuardedLock
- *
- * Acquires a guarded lock and raises the IRQL to APC_LEVEL.
- *
- * IRQL: <= APC_LEVEL
- */
-VOID FASTCALL KphfAcquireGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KIRQL oldIrql;
-
- ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
- /* Raise to APC_LEVEL. */
- oldIrql = KeRaiseIrql(APC_LEVEL, &oldIrql);
-
- /* Acquire the spinlock. */
- KphAcquireBitSpinLock(&Lock->Value, KPH_GUARDED_LOCK_ACTIVE_SHIFT);
-
- /* Now that we have the lock, we must save the old IRQL. */
- /* Clear the old IRQL. */
- Lock->Value &= KPH_GUARDED_LOCK_FLAGS;
- /* Set the new IRQL. */
- Lock->Value |= oldIrql;
-}
-
-/* KphfReleaseGuardedLock
- *
- * Releases a guarded lock and restores the old IRQL.
- *
- * IRQL: >= APC_LEVEL
- */
-VOID FASTCALL KphfReleaseGuardedLock(
- __inout PKPH_GUARDED_LOCK Lock
- )
-{
- KIRQL oldIrql;
-
- ASSERT(KeGetCurrentIrql() >= APC_LEVEL);
-
- /* Get the old IRQL. */
- oldIrql = (KIRQL)(Lock->Value & ~KPH_GUARDED_LOCK_FLAGS);
- /* Unlock the spinlock. */
- KphReleaseBitSpinLock(&Lock->Value, KPH_GUARDED_LOCK_ACTIVE_SHIFT);
- /* Restore the old IRQL. */
- KeLowerIrql(oldIrql);
-}
-
-/* KphAcquireProcessorLock
- *
- * Raises the IRQL to DISPATCH_LEVEL and prevents threads from
- * executing on other processors until the processor lock is released.
- * Blocks if the supplied processor lock is already in use.
- *
- * ProcessorLock: A processor lock structure that is present in
- * non-paged memory.
- *
- * Comments:
- * Here is how the processor lock works:
- * 1. Tries to acquire the mutex in the processor lock, and
- * blocks until it can be obtained.
- * 2. Initializes a DPC for each processor on the computer.
- * 3. Raises the IRQL to DISPATCH_LEVEL to make sure the
- * code is not interrupted by a context switch.
- * 4. Queues each of the previously-initialized DPCs, except if
- * it is targeted at the current processor.
- * 5. Since DPCs run at DISPATCH_LEVEL, they have exclusive
- * control of the processor. As each runs, they increment
- * a counter in the processor lock. They then enter a loop.
- * 6. The routine waits for the counter to become n - 1,
- * signaling that all (other) processors have been acquired
- * (where n is the number of processors).
- * 7. It returns. Any code from here will be running in
- * DISPATCH_LEVEL and will be the only code running on the
- * machine.
- * Thread safety: Full
- * IRQL: <= APC_LEVEL
- */
-BOOLEAN KphAcquireProcessorLock(
- __inout PKPH_PROCESSOR_LOCK ProcessorLock
- )
-{
- ULONG i;
- ULONG numberProcessors;
- ULONG currentProcessor;
-
- /* Acquire the processor lock guarded lock. */
- KphAcquireGuardedLock(&ProcessorLock->Lock);
-
- /* Reset some state. */
- ASSERT(ProcessorLock->AcquiredProcessors == 0);
- ProcessorLock->AcquiredProcessors = 0;
- ProcessorLock->ReleaseSignal = 0; /* IMPORTANT */
-
- /* Get the number of processors. */
- numberProcessors = KphpCountBits(KeQueryActiveProcessors());
-
- /* If there's only one processor we can simply raise the IRQL and exit. */
- if (numberProcessors == 1)
- {
- dprintf("KphAcquireProcessorLock: Only one processor, raising IRQL and exiting...\n");
- KeRaiseIrql(DISPATCH_LEVEL, &ProcessorLock->OldIrql);
- ProcessorLock->Acquired = TRUE;
-
- return TRUE;
- }
-
- /* Allocate storage for the DPCs. */
- ProcessorLock->Dpcs = ExAllocatePoolWithTag(
- NonPagedPool,
- sizeof(KDPC) * numberProcessors,
- TAG_SYNC_DPC
- );
-
- if (!ProcessorLock->Dpcs)
- {
- dprintf("KphAcquireProcessorLock: Could not allocate storage for DPCs!\n");
- KphReleaseGuardedLock(&ProcessorLock->Lock);
- return FALSE;
- }
-
- /* Initialize the DPCs. */
- for (i = 0; i < numberProcessors; i++)
- {
- KeInitializeDpc(&ProcessorLock->Dpcs[i], KphpProcessorLockDpc, NULL);
- KeSetTargetProcessorDpc(&ProcessorLock->Dpcs[i], (CCHAR)i);
- KeSetImportanceDpc(&ProcessorLock->Dpcs[i], HighImportance);
- }
-
- /* Raise the IRQL to DISPATCH_LEVEL to prevent context switching. */
- KeRaiseIrql(DISPATCH_LEVEL, &ProcessorLock->OldIrql);
- /* Get the current processor number. */
- currentProcessor = KeGetCurrentProcessorNumber();
-
- /* Queue the DPCs (except on the current processor). */
- for (i = 0; i < numberProcessors; i++)
- if (i != currentProcessor)
- KeInsertQueueDpc(&ProcessorLock->Dpcs[i], ProcessorLock, NULL);
-
- /* Spinwait for all (other) processors to be acquired. */
- KphSpinUntilEqual(&ProcessorLock->AcquiredProcessors, numberProcessors - 1);
-
- dprintf("KphAcquireProcessorLock: All processors acquired.\n");
- ProcessorLock->Acquired = TRUE;
-
- return TRUE;
-}
-
-/* KphInitializeProcessorLock
- *
- * Initializes a processor lock.
- *
- * ProcessorLock: A processor lock structure that is present in
- * non-paged memory.
- *
- * IRQL: Any
- */
-VOID KphInitializeProcessorLock(
- __out PKPH_PROCESSOR_LOCK ProcessorLock
- )
-{
- KphInitializeGuardedLock(&ProcessorLock->Lock, FALSE);
- ProcessorLock->Dpcs = NULL;
- ProcessorLock->AcquiredProcessors = 0;
- ProcessorLock->ReleaseSignal = 0;
- ProcessorLock->OldIrql = PASSIVE_LEVEL;
- ProcessorLock->Acquired = FALSE;
-}
-
-/* KphReleaseProcessorLock
- *
- * Allows threads to execute on other processors and restores the IRQL.
- *
- * ProcessorLock: A processor lock structure that is present in
- * non-paged memory.
- *
- * Comments:
- * Here is how the processor lock is released:
- * 1. Sets the signal to release the processors. The DPCs that are
- * currently waiting for the signal will return and decrement
- * the acquired processors counter.
- * 2. Waits for the acquired processors counter to become zero.
- * 3. Restores the old IRQL. This will always be APC_LEVEL due to
- * the mutex.
- * 4. Frees the storage allocated for the DPCs.
- * 5. Releases the processor lock mutex. This will restore the IRQL
- * back to normal.
- * Thread safety: Full
- * IRQL: DISPATCH_LEVEL
- */
-VOID KphReleaseProcessorLock(
- __inout PKPH_PROCESSOR_LOCK ProcessorLock
- )
-{
- if (!ProcessorLock->Acquired)
- return;
-
- /* Signal for the acquired processors to be released. */
- InterlockedExchange(&ProcessorLock->ReleaseSignal, 1);
-
- /* Spinwait for all acquired processors to be released. */
- KphSpinUntilEqual(&ProcessorLock->AcquiredProcessors, 0);
-
- dprintf("KphReleaseProcessorLock: All processors released.\n");
-
- /* Restore the old IRQL (should always be APC_LEVEL due to the
- * fast mutex). */
- KeLowerIrql(ProcessorLock->OldIrql);
-
- /* Free the DPCs if necessary. */
- if (ProcessorLock->Dpcs != NULL)
- {
- ExFreePoolWithTag(ProcessorLock->Dpcs, TAG_SYNC_DPC);
- ProcessorLock->Dpcs = NULL;
- }
-
- ProcessorLock->Acquired = FALSE;
-
- /* Release the processor lock guarded lock. This will restore the
- * IRQL back to what it was before the processor lock was
- * acquired.
- */
- KphReleaseGuardedLock(&ProcessorLock->Lock);
-}
-
-/* KphpCountBits
- *
- * Counts the number of bits set in an integer.
- */
-ULONG KphpCountBits(
- __in ULONG_PTR Number
- )
-{
- ULONG count = 0;
-
- while (Number)
- {
- count++;
- Number &= Number - 1;
- }
-
- return count;
-}
-
-/* KphpProcessorLockDpc
- *
- * The DPC routine which "locks" processors.
- *
- * Thread safety: Full
- * IRQL: DISPATCH_LEVEL
- */
-VOID KphpProcessorLockDpc(
- __in PKDPC Dpc,
- __in PVOID DeferredContext,
- __in PVOID SystemArgument1,
- __in PVOID SystemArgument2
- )
-{
- PKPH_PROCESSOR_LOCK processorLock = (PKPH_PROCESSOR_LOCK)SystemArgument1;
-
- ASSERT(processorLock != NULL);
-
- dprintf("KphpProcessorLockDpc: Acquiring processor %d.\n", KeGetCurrentProcessorNumber());
-
- /* Increase the number of acquired processors. */
- InterlockedIncrement(&processorLock->AcquiredProcessors);
-
- /* Spin until we get the signal to release the processor. */
- KphSpinUntilNotEqual(&processorLock->ReleaseSignal, 0);
-
- /* Decrease the number of acquired processors. */
- InterlockedDecrement(&processorLock->AcquiredProcessors);
-
- dprintf("KphpProcessorLockDpc: Releasing processor %d.\n", KeGetCurrentProcessorNumber());
-}
diff --git a/2.x/trunk/KProcessHacker/sysservice.c b/2.x/trunk/KProcessHacker/sysservice.c
deleted file mode 100644
index 784706b4b..000000000
--- a/2.x/trunk/KProcessHacker/sysservice.c
+++ /dev/null
@@ -1,2140 +0,0 @@
-/*
- * Process Hacker Driver -
- * system service logging
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-/* ================ IMPORTANT ================
- * Please read the comments in KphpSsNewKiFastCallEntry to find out how
- * KiFastCallEntry can be hooked.
- *
- * Note that the ONLY SUPPORTED METHOD of hooking is KiFastCallEntry,
- * which means you MUST be using a CPU which supports sysenter.
- * ===========================================
- */
-
-#include "include/sysservicep.h"
-#include "include/hook.h"
-#include "include/sync.h"
-#include "include/trace.h"
-
-extern PDRIVER_OBJECT KphDriverObject;
-
-/* A fast mutex guarding starting/stopping system service logging. */
-FAST_MUTEX KphSsMutex;
-/* Whether system service logging has been initialized. */
-BOOLEAN KphSsInitialized = FALSE;
-/* The KiFastCallEntry hook. */
-KPH_HOOK KphSsKiFastCallEntryHook;
-/* The number of active loggers. */
-ULONG KphSsNumberOfActiveLoggers = 0;
-
-/* The object type for client entries. */
-PKPH_OBJECT_TYPE KphSsClientEntryType;
-/* The object type for ruleset entries. */
-PKPH_OBJECT_TYPE KphSsRuleSetEntryType;
-/* The object type for rule entries. */
-PKPH_OBJECT_TYPE KphSsRuleEntryType;
-
-/* The list of ruleset entries. */
-LIST_ENTRY KphSsRuleSetListHead;
-/* A push lock guarding accesses to the ruleset list. */
-EX_PUSH_LOCK KphSsRuleSetListPushLock;
-
-/* KphSsLogInit
- *
- * Initializes system service logging.
- */
-NTSTATUS KphSsLogInit()
-{
- NTSTATUS status = STATUS_SUCCESS;
-
- /* Initialize the system service call data. */
- KphSsDataInit();
-
- /* Initialize the ruleset list. */
- InitializeListHead(&KphSsRuleSetListHead);
- ExInitializeFastMutex(&KphSsMutex);
- ExInitializePushLock(&KphSsRuleSetListPushLock);
-
- /* Initialize the object types. */
- status = KphCreateObjectType(
- &KphSsClientEntryType,
- NonPagedPool,
- 0,
- KphpSsClientEntryDeleteProcedure
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- status = KphCreateObjectType(
- &KphSsRuleSetEntryType,
- NonPagedPool,
- 0,
- KphpSsRuleSetEntryDeleteProcedure
- );
-
- if (!NT_SUCCESS(status))
- {
- KphDereferenceObject(KphSsClientEntryType);
- return status;
- }
-
- status = KphCreateObjectType(
- &KphSsRuleEntryType,
- NonPagedPool,
- 0,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- {
- KphDereferenceObject(KphSsClientEntryType);
- KphDereferenceObject(KphSsRuleSetEntryType);
- return status;
- }
-
- return status;
-}
-
-/* KphSsLogDeinit
- *
- * Frees system service logging data.
- */
-NTSTATUS KphSsLogDeinit()
-{
- KphSsDataDeinit();
-
- return STATUS_SUCCESS;
-}
-
-/* KphSsLogStart
- *
- * Starts system service logging.
- */
-NTSTATUS KphSsLogStart()
-{
-#ifdef _X86_
- NTSTATUS status = STATUS_SUCCESS;
-
- /* Make sure we have the KiFastCallEntry+x address. */
- if (!__KiFastCallEntry)
- return STATUS_NOT_SUPPORTED;
-
- ExAcquireFastMutex(&KphSsMutex);
-
- if (KphSsInitialized)
- {
- ExReleaseFastMutex(&KphSsMutex);
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Hook KiFastCallEntry. Logging will start from now. */
- KphInitializeHook(
- &KphSsKiFastCallEntryHook,
- __KiFastCallEntry,
- KphpSsNewKiFastCallEntry
- );
- status = KphHook(&KphSsKiFastCallEntryHook);
-
- if (!NT_SUCCESS(status))
- {
- ExReleaseFastMutex(&KphSsMutex);
- return status;
- }
-
- KphSsInitialized = TRUE;
-
- ExReleaseFastMutex(&KphSsMutex);
-
- return status;
-#else
- return STATUS_NOT_SUPPORTED;
-#endif
-}
-
-/* KphSsLogStop
- *
- * Stops system service logging.
- */
-NTSTATUS KphSsLogStop()
-{
-#ifdef _X86_
- NTSTATUS status = STATUS_SUCCESS;
-
- ExAcquireFastMutex(&KphSsMutex);
-
- if (!KphSsInitialized)
- {
- ExReleaseFastMutex(&KphSsMutex);
- return STATUS_UNSUCCESSFUL;
- }
-
- status = KphUnhook(&KphSsKiFastCallEntryHook);
-
- if (!NT_SUCCESS(status))
- {
- ExReleaseFastMutex(&KphSsMutex);
- return status;
- }
-
- /* Spin until the logger count reaches 0. */
- KphSpinUntilEqual(&KphSsNumberOfActiveLoggers, 0);
-
- KphSsInitialized = FALSE;
-
- ExReleaseFastMutex(&KphSsMutex);
-
- return status;
-#else
- return STATUS_NOT_SUPPORTED;
-#endif
-}
-
-/* KphSsCreateClientEntry
- *
- * Creates a client entry which describes a client of the
- * system service logger. Clients receive system service log events.
- * Note that a client may have several ruleset entries associated
- * with it.
- *
- * ClientEntry: A variable which receives a pointer to the client entry.
- * ProcessHandle: A handle to the client process, with PROCESS_VM_WRITE
- * access.
- * ReadSemaphoreHandle: A handle to a semaphore which is released when an
- * event is written to the client buffer. The client must wait for the
- * semaphore when it is about to read a block.
- * WriteSemaphoreHandle: A handle to a semaphore which is acquired when an
- * event is about to be written to the client buffer. If the semaphore
- * cannot be acquired immediately, the event is dropped. The client must
- * continually read the buffer and release the semaphore.
- * BufferBase: A pointer to a buffer in the client process.
- * BufferSize: The size of the buffer, in bytes.
- * AccessMode: The mode to use when probing arguments.
- */
-NTSTATUS KphSsCreateClientEntry(
- __out PKPHSS_CLIENT_ENTRY *ClientEntry,
- __in HANDLE ProcessHandle,
- __in HANDLE ReadSemaphoreHandle,
- __in HANDLE WriteSemaphoreHandle,
- __in PVOID BufferBase,
- __in ULONG BufferSize,
- __in KPROCESSOR_MODE AccessMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_CLIENT_ENTRY clientEntry;
- PEPROCESS processObject;
- PKSEMAPHORE readSemaphore;
- PKSEMAPHORE writeSemaphore;
-
- /* Probe. */
- if (AccessMode != KernelMode)
- {
- __try
- {
- ProbeForWrite(BufferBase, BufferSize, 1);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
- }
-
- /* Reference the client process. */
- status = ObReferenceObjectByHandle(
- ProcessHandle,
- PROCESS_VM_WRITE,
- *PsProcessType,
- AccessMode,
- &processObject,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Reference the read semaphore. */
- status = ObReferenceObjectByHandle(
- ReadSemaphoreHandle,
- SEMAPHORE_MODIFY_STATE,
- *ExSemaphoreObjectType,
- AccessMode,
- &readSemaphore,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- {
- ObDereferenceObject(processObject);
- return status;
- }
-
- /* Reference the write semaphore. */
- status = ObReferenceObjectByHandle(
- WriteSemaphoreHandle,
- SEMAPHORE_MODIFY_STATE,
- *ExSemaphoreObjectType,
- AccessMode,
- &writeSemaphore,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- {
- ObDereferenceObject(processObject);
- ObDereferenceObject(readSemaphore);
- return status;
- }
-
- /* Create the client entry object. */
- status = KphCreateObject(
- &clientEntry,
- sizeof(KPHSS_CLIENT_ENTRY),
- 0,
- KphSsClientEntryType,
- 0
- );
-
- if (!NT_SUCCESS(status))
- {
- ObDereferenceObject(processObject);
- ObDereferenceObject(readSemaphore);
- ObDereferenceObject(writeSemaphore);
-
- return status;
- }
-
- clientEntry->Process = processObject;
- clientEntry->Enabled = TRUE;
- clientEntry->ReadSemaphore = readSemaphore;
- clientEntry->WriteSemaphore = writeSemaphore;
- ExInitializeFastMutex(&clientEntry->BufferMutex);
- clientEntry->BufferBase = BufferBase;
- clientEntry->BufferSize = BufferSize;
- clientEntry->BufferCursor = 0;
- clientEntry->NumberOfBlocksWritten = 0;
- clientEntry->NumberOfBlocksDropped = 0;
-
- *ClientEntry = clientEntry;
-
- return status;
-}
-
-/* KphSsEnableClientEntry
- *
- * Enables or disables a client entry.
- */
-NTSTATUS KphSsEnableClientEntry(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in BOOLEAN Enable
- )
-{
- if (Enable)
- ClientEntry->Enabled = TRUE;
- else
- ClientEntry->Enabled = FALSE;
-
- return STATUS_SUCCESS;
-}
-
-/* KphSsQueryClientEntry
- *
- * Queries information about a client entry.
- */
-NTSTATUS KphSsQueryClientEntry(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __out_bcount_opt(ClientInformationLength) PKPHSS_CLIENT_INFORMATION ClientInformation,
- __in ULONG ClientInformationLength,
- __out_opt PULONG ReturnLength,
- __in KPROCESSOR_MODE AccessMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
-
- /* Probe the return length if necessary. */
- if (AccessMode != KernelMode)
- {
- __try
- {
- ProbeForWrite(ReturnLength, sizeof(ULONG), 1);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
- }
-
- /* Check the length. */
- if (ClientInformationLength >= sizeof(KPHSS_CLIENT_INFORMATION))
- {
- if (ClientInformation)
- {
- __try
- {
- /* Probe the buffer if we're not from kernel-mode. */
- if (AccessMode != KernelMode)
- ProbeForWrite(ClientInformation, sizeof(KPHSS_CLIENT_INFORMATION), 1);
-
- ClientInformation->ProcessId = PsGetProcessId(ClientEntry->Process);
- ClientInformation->BufferBase = ClientEntry->BufferBase;
- ClientInformation->BufferSize = ClientEntry->BufferSize;
- ClientInformation->NumberOfBlocksWritten = ClientEntry->NumberOfBlocksWritten;
- ClientInformation->NumberOfBlocksDropped = ClientEntry->NumberOfBlocksDropped;
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- status = GetExceptionCode();
- }
- }
- }
- else
- {
- status = STATUS_BUFFER_TOO_SMALL;
- }
-
- /* Pass the return length back if requested. */
- if (ReturnLength)
- {
- __try
- {
- *ReturnLength = sizeof(KPHSS_CLIENT_INFORMATION);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- status = GetExceptionCode();
- }
- }
-
- return status;
-}
-
-/* KphpSsClientEntryDeleteProcedure
- *
- * Performs cleanup for a client entry.
- */
-VOID NTAPI KphpSsClientEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- )
-{
- PKPHSS_CLIENT_ENTRY clientEntry = (PKPHSS_CLIENT_ENTRY)Object;
-
- ObDereferenceObject(clientEntry->Process);
- ObDereferenceObject(clientEntry->ReadSemaphore);
- ObDereferenceObject(clientEntry->WriteSemaphore);
-}
-
-/* KphSsCreateRuleSetEntry
- *
- * Creates a ruleset entry which contains a list of rules
- * and an action to perform.
- */
-NTSTATUS KphSsCreateRuleSetEntry(
- __out PKPHSS_RULESET_ENTRY *RuleSetEntry,
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in KPHSS_FILTER_TYPE DefaultFilterType,
- __in KPHSS_RULESET_ACTION Action
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULESET_ENTRY ruleSetEntry;
-
- /* Make sure the action is valid. */
- if (Action < LogRuleSetAction || Action >= MaxRuleSetAction)
- return STATUS_INVALID_PARAMETER_3;
-
- /* Create the ruleset object. */
- status = KphCreateObject(
- &ruleSetEntry,
- sizeof(KPHSS_RULESET_ENTRY),
- 0,
- KphSsRuleSetEntryType,
- 0
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Initialize the ruleset object. */
- KphReferenceObject(ClientEntry);
- ruleSetEntry->Client = ClientEntry;
- ruleSetEntry->DefaultFilterType = DefaultFilterType;
- ruleSetEntry->Action = Action;
- ruleSetEntry->NextRuleHandle = 4;
- ExInitializePushLock(&ruleSetEntry->RuleListPushLock);
- InitializeListHead(&ruleSetEntry->RuleListHead);
-
- /* Add the ruleset to the list. */
- KeEnterCriticalRegion();
- ExAcquirePushLockExclusive(&KphSsRuleSetListPushLock);
- InsertHeadList(&KphSsRuleSetListHead, &ruleSetEntry->RuleSetListEntry);
- ExReleasePushLock(&KphSsRuleSetListPushLock);
- KeLeaveCriticalRegion();
-
- *RuleSetEntry = ruleSetEntry;
-
- return status;
-}
-
-/* KphpSsRuleSetEntryDeleteProcedure
- *
- * Performs cleanup for a ruleset entry.
- */
-VOID NTAPI KphpSsRuleSetEntryDeleteProcedure(
- __in PVOID Object,
- __in ULONG Flags
- )
-{
- PKPHSS_RULESET_ENTRY ruleSetEntry = (PKPHSS_RULESET_ENTRY)Object;
- PLIST_ENTRY currentRuleListEntry;
-
- /* Dereference the client entry. */
- KphDereferenceObject(ruleSetEntry->Client);
-
- KeEnterCriticalRegion();
-
- /* Dereference all rules in the ruleset. */
- ExAcquirePushLockExclusive(&ruleSetEntry->RuleListPushLock);
-
- currentRuleListEntry = ruleSetEntry->RuleListHead.Flink;
-
- while (currentRuleListEntry != &ruleSetEntry->RuleListHead)
- {
- PLIST_ENTRY nextEntry;
-
- /* Save the next entry pointer since currentRuleListEntry may
- * be deallocated due to the dereference.
- */
- nextEntry = currentRuleListEntry->Flink;
- KphDereferenceObject(KPHSS_RULE_ENTRY(currentRuleListEntry));
- currentRuleListEntry = nextEntry;
- }
-
- ExReleasePushLock(&ruleSetEntry->RuleListPushLock);
-
- /* Remove the ruleset from the list. */
- ExAcquirePushLockExclusive(&KphSsRuleSetListPushLock);
- RemoveEntryList(&ruleSetEntry->RuleSetListEntry);
- ExReleasePushLock(&KphSsRuleSetListPushLock);
-
- KeLeaveCriticalRegion();
-}
-
-/* KphSsAddProcessIdRule
- *
- * Adds a process ID rule entry to a ruleset entry.
- */
-NTSTATUS KphSsAddProcessIdRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in HANDLE ProcessId
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- /* Add the rule. */
- status = KphpSsAddRule(&ruleEntry, RuleSetEntry, FilterType, ProcessIdRuleType);
-
- if (!NT_SUCCESS(status))
- return status;
-
- ruleEntry->ProcessIdRule.ProcessId = ProcessId;
- ruleEntry->Initialized = TRUE;
-
- *RuleEntry = ruleEntry;
-
- return status;
-}
-
-/* KphSsAddThreadIdRule
- *
- * Adds a thread ID rule entry to a ruleset entry.
- */
-NTSTATUS KphSsAddThreadIdRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in HANDLE ThreadId
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- /* Add the rule. */
- status = KphpSsAddRule(&ruleEntry, RuleSetEntry, FilterType, ThreadIdRuleType);
-
- if (!NT_SUCCESS(status))
- return status;
-
- ruleEntry->ThreadIdRule.ThreadId = ThreadId;
- ruleEntry->Initialized = TRUE;
-
- *RuleEntry = ruleEntry;
-
- return status;
-}
-
-/* KphSsAddPreviousModeRule
- *
- * Adds a previous mode rule entry to a ruleset entry.
- */
-NTSTATUS KphSsAddPreviousModeRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- /* Add the rule. */
- status = KphpSsAddRule(&ruleEntry, RuleSetEntry, FilterType, PreviousModeRuleType);
-
- if (!NT_SUCCESS(status))
- return status;
-
- ruleEntry->PreviousModeRule.PreviousMode = PreviousMode;
- ruleEntry->Initialized = TRUE;
-
- *RuleEntry = ruleEntry;
-
- return status;
-}
-
-/* KphSsAddNumberRule
- *
- * Adds a system service number rule entry to a ruleset entry.
- */
-NTSTATUS KphSsAddNumberRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in ULONG Number
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- /* Add the rule. */
- status = KphpSsAddRule(&ruleEntry, RuleSetEntry, FilterType, NumberRuleType);
-
- if (!NT_SUCCESS(status))
- return status;
-
- ruleEntry->NumberRule.Number = Number;
- ruleEntry->Initialized = TRUE;
-
- *RuleEntry = ruleEntry;
-
- return status;
-}
-
-/* KphSsGetHandleRule
- *
- * Gets the handle of a rule.
- */
-HANDLE KphSsGetHandleRule(
- __in PKPHSS_RULE_ENTRY RuleEntry
- )
-{
- return RuleEntry->Handle;
-}
-
-/* KphSsRemoveRule
- *
- * Removes a rule entry from a ruleset entry.
- */
-NTSTATUS KphSsRemoveRule(
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in HANDLE RuleEntryHandle
- )
-{
- PLIST_ENTRY currentListEntry;
-
- KeEnterCriticalRegion();
- ExAcquirePushLockExclusive(&RuleSetEntry->RuleListPushLock);
-
- /* Find the rule in the ruleset. */
-
- currentListEntry = RuleSetEntry->RuleListHead.Flink;
-
- while (currentListEntry != &RuleSetEntry->RuleListHead)
- {
- PKPHSS_RULE_ENTRY ruleEntry = KPHSS_RULE_ENTRY(currentListEntry);
-
- if (ruleEntry->Handle == RuleEntryHandle)
- {
- /* Remove the rule from the list. */
- RemoveEntryList(&ruleEntry->RuleListEntry);
- /* Dereference the rule (it was referenced when it
- * got added to the list).
- */
- KphDereferenceObject(ruleEntry);
-
- ExReleasePushLock(&RuleSetEntry->RuleListPushLock);
- KeLeaveCriticalRegion();
-
- return STATUS_SUCCESS;
- }
-
- currentListEntry = currentListEntry->Flink;
- }
-
- ExReleasePushLock(&RuleSetEntry->RuleListPushLock);
- KeLeaveCriticalRegion();
-
- return STATUS_INVALID_PARAMETER_2;
-}
-
-/* KphpSsAddRule
- *
- * Adds a rule entry to a ruleset entry.
- */
-NTSTATUS KphpSsAddRule(
- __out PKPHSS_RULE_ENTRY *RuleEntry,
- __in PKPHSS_RULESET_ENTRY RuleSetEntry,
- __in KPHSS_FILTER_TYPE FilterType,
- __in KPHSS_RULE_TYPE RuleType
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_RULE_ENTRY ruleEntry;
-
- /* Make sure the filter/rule type is valid. */
- if (FilterType < IncludeFilterType || FilterType >= MaxFilterType)
- return STATUS_INVALID_PARAMETER_3;
- if (RuleType < ProcessIdRuleType || RuleType >= MaxRuleType)
- return STATUS_INVALID_PARAMETER_4;
-
- /* Create the rule entry object. */
- status = KphCreateObject(
- &ruleEntry,
- sizeof(KPHSS_RULE_ENTRY),
- 0,
- KphSsRuleEntryType,
- 0
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Initialize the object. */
- ruleEntry->Initialized = FALSE;
- ruleEntry->FilterType = FilterType;
- ruleEntry->RuleType = RuleType;
-
- /* Get a handle for the rule. */
- ruleEntry->Handle = (HANDLE)(ULONG_PTR)InterlockedExchangeAdd(
- &RuleSetEntry->NextRuleHandle,
- KPHSS_RULE_HANDLE_INCREMENT
- );
-
- /* Add the rule to the ruleset. */
- KeEnterCriticalRegion();
- ExAcquirePushLockExclusive(&RuleSetEntry->RuleListPushLock);
- InsertTailList(&RuleSetEntry->RuleListHead, &ruleEntry->RuleListEntry);
- ExReleasePushLock(&RuleSetEntry->RuleListPushLock);
- KeLeaveCriticalRegion();
- /* Add a reference for the rule being on the list. */
- KphReferenceObject(ruleEntry);
-
- *RuleEntry = ruleEntry;
-
- return status;
-}
-
-/* KphpSsCreateEventBlock
- *
- * Allocates and initializes an event block.
- *
- * EventBlock: A variable which receives a pointer to the event block.
- * Thread: The thread for which the event is being generated.
- * Number: The system service number.
- * Arguments: A pointer to the caller-supplied arguments.
- * NumberOfArguments: The number of arguments, in ULONGs.
- */
-NTSTATUS KphpSsCreateEventBlock(
- __out PKPHSS_EVENT_BLOCK *EventBlock,
- __in PKTHREAD Thread,
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments
- )
-{
- PKPHSS_EVENT_BLOCK eventBlock;
- KPROCESSOR_MODE previousMode;
- ULONG eventBlockSize;
- ULONG argumentsSize;
- ULONG traceSize;
- PVOID stackTrace[MAX_STACK_DEPTH * 2];
- ULONG capturedFrames;
-
- /* Make sure the argument count isn't too large. */
- if (NumberOfArguments > MAX_USHORT)
- return STATUS_INVALID_PARAMETER;
-
- previousMode = ExGetPreviousMode();
-
- /* Capture kernel-mode and user-mode stack traces.
- * We do this before we allocate the event block so
- * we can calculate how large the block should be.
- */
-
- /* Get a kernel-mode stack trace. */
- capturedFrames = KphCaptureStackBackTrace(
- 0,
- MAX_STACK_DEPTH - 1,
- 0,
- stackTrace,
- NULL
- );
-
- if (PsGetCurrentProcess() != PsInitialSystemProcess)
- {
- /* Get a user-mode stack trace. */
- capturedFrames += KphCaptureStackBackTrace(
- 0,
- MAX_STACK_DEPTH - 1,
- RTL_WALK_USER_MODE_STACK,
- &stackTrace[capturedFrames],
- NULL
- );
- }
-
- /* Calculate the size of the event block. */
- argumentsSize = NumberOfArguments * sizeof(ULONG);
- traceSize = capturedFrames * sizeof(PVOID);
- eventBlockSize = sizeof(KPHSS_EVENT_BLOCK) + argumentsSize + traceSize;
-
- /* Make sure the block size isn't too large. */
- if (eventBlockSize > MAX_USHORT)
- return STATUS_INVALID_PARAMETER;
-
- /* Allocate the event block. */
- eventBlock = ExAllocatePoolWithTag(PagedPool, eventBlockSize, TAG_EVENT_BLOCK);
-
- if (!eventBlock)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Initialize the event block. */
- eventBlock->Header.Size = (USHORT)eventBlockSize;
- eventBlock->Header.Type = EventBlockType;
- eventBlock->Flags = 0;
- KeQuerySystemTime(&eventBlock->Time);
- eventBlock->ClientId.UniqueThread = PsGetThreadId(Thread);
- eventBlock->ClientId.UniqueProcess = PsGetProcessId(IoThreadToProcess(Thread));
- eventBlock->Number = Number;
- eventBlock->NumberOfArguments = (USHORT)NumberOfArguments;
- eventBlock->ArgumentsOffset = sizeof(KPHSS_EVENT_BLOCK);
- eventBlock->TraceCount = (USHORT)capturedFrames;
- eventBlock->TraceOffset = (USHORT)(sizeof(KPHSS_EVENT_BLOCK) + argumentsSize);
-
- /* Set the flags according to the previous mode. */
- if (previousMode == UserMode)
- eventBlock->Flags |= KPHSS_EVENT_USER_MODE;
- else if (previousMode == KernelMode)
- eventBlock->Flags |= KPHSS_EVENT_KERNEL_MODE;
-
- /* Probe and copy the arguments. */
- if (previousMode != KernelMode)
- {
- __try
- {
- ProbeForRead(Arguments, argumentsSize, 4);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- eventBlock->Flags |= KPHSS_EVENT_PROBE_ARGUMENTS_FAILED;
- }
- }
-
- __try
- {
- /* Copy the arguments to the space immediately after the event block. */
- memcpy((PCHAR)eventBlock + eventBlock->ArgumentsOffset, Arguments, argumentsSize);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- eventBlock->Flags |= KPHSS_EVENT_COPY_ARGUMENTS_FAILED;
- }
-
- /* Copy the stack trace. */
- memcpy((PCHAR)eventBlock + eventBlock->TraceOffset, stackTrace, traceSize);
-
- /* Pass the pointer to the event block back. */
- *EventBlock = eventBlock;
-
- return STATUS_SUCCESS;
-}
-
-/* KphpSsFreeEventBlock
- *
- * Frees an event block created by KphpSsCreateEventBlock.
- */
-VOID KphpSsFreeEventBlock(
- __in PKPHSS_EVENT_BLOCK EventBlock
- )
-{
- ExFreePoolWithTag(EventBlock, TAG_EVENT_BLOCK);
-}
-
-/* KphpSsCaptureSimpleArgument
- *
- * Captures a simple (1-, 2-, 4- or 8-byte) argument.
- */
-NTSTATUS KphpSsCaptureSimpleArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PVOID Argument,
- __in KPHSS_ARGUMENT_TYPE Type,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- ULONG size;
- LARGE_INTEGER value;
-
- /* Return if we have a NULL pointer. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Get the proper argument size based on the argument type. */
- switch (Type)
- {
- case Int8Argument:
- size = sizeof(BOOLEAN);
- break;
- case Int16Argument:
- size = sizeof(SHORT);
- break;
- case Int32Argument:
- size = sizeof(LONG);
- break;
- case Int64Argument:
- size = sizeof(LARGE_INTEGER);
- break;
- default:
- return STATUS_INVALID_PARAMETER_3;
- }
-
- /* Probe and read the value. */
- __try
- {
- if (PreviousMode != KernelMode)
- ProbeForRead(Argument, size, 1);
-
- memcpy(&value, Argument, size);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(size, Type);
-
- if (!argumentBlock)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Copy the value into the argument block. */
- memcpy(&argumentBlock->Simple, &value, size);
- *ArgumentBlock = argumentBlock;
-
- return STATUS_SUCCESS;
-}
-
-/* KphpSsCaptureHandleArgument
- *
- * Captures a handle argument.
- */
-NTSTATUS KphpSsCaptureHandleArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in HANDLE Argument,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- ULONG bufferLength;
- PVOID object;
- POBJECT_TYPE objectType;
- PUNICODE_STRING objectTypeName;
- PUNICODE_STRING objectNameInfo;
- ULONG returnLength;
- PKPHSS_HANDLE handleInfo;
- PKPHSS_WSTRING wString;
-
- /* Return if we have a NULL handle. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Make sure the handle isn't a kernel handle if we're
- * from user-mode. We need exceptions for the process
- * and thread pseudo-handles.
- */
- if (PreviousMode != KernelMode)
- {
- if (
- IsKernelHandle(Argument) &&
- Argument != NtCurrentProcess() &&
- Argument != NtCurrentThread()
- )
- return STATUS_INVALID_HANDLE;
- }
-
- /* Reference the object. */
- status = ObReferenceObjectByHandle(
- Argument,
- 0,
- NULL,
- KernelMode,
- &object,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Get a pointer to the UNICODE_STRING containing the
- * object type name.
- */
- objectType = KphGetObjectTypeNt(object);
- objectTypeName = (PUNICODE_STRING)KVOFF(objectType, OffOtName);
-
- /* Allocate a buffer for name information. */
- objectNameInfo = (PUNICODE_STRING)ExAllocatePoolWithTag(
- PagedPool,
- CAPTURE_HANDLE_BUFFER_SIZE,
- TAG_CAPTURE_TEMP_BUFFER
- );
-
- if (!objectNameInfo)
- goto CleanupObject;
-
- /* Query the name of the object. */
- status = KphQueryNameObject(
- object,
- objectNameInfo,
- CAPTURE_HANDLE_BUFFER_SIZE,
- &returnLength
- );
-
- if (!NT_SUCCESS(status))
- goto CleanupName;
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(
- sizeof(KPHSS_HANDLE) + sizeof(KPHSS_WSTRING) + sizeof(KPHSS_WSTRING) +
- objectTypeName->Length + objectNameInfo->Length,
- HandleArgument
- );
-
- if (!argumentBlock)
- goto CleanupName;
-
- handleInfo = &argumentBlock->Handle;
- /* Calculate the offsets. */
- handleInfo->TypeNameOffset = sizeof(KPHSS_HANDLE);
- handleInfo->NameOffset =
- handleInfo->TypeNameOffset + sizeof(KPHSS_WSTRING) +
- objectTypeName->Length;
-
- /* Copy the object type name into the block. */
- wString = (PKPHSS_WSTRING)PTR_ADD_OFFSET(handleInfo, handleInfo->TypeNameOffset);
- wString->Length = objectTypeName->Length;
- memcpy(&wString->Buffer, objectTypeName->Buffer, wString->Length);
-
- /* Copy the object name into the block. */
- wString = (PKPHSS_WSTRING)PTR_ADD_OFFSET(handleInfo, handleInfo->NameOffset);
- wString->Length = objectNameInfo->Length;
- memcpy(&wString->Buffer, objectNameInfo->Buffer, wString->Length);
-
- /* We may be able to get additional information for the
- * object.
- */
-
- handleInfo->ClientId.UniqueProcess = NULL;
- handleInfo->ClientId.UniqueThread = NULL;
-
- if (objectType == *PsProcessType)
- {
- handleInfo->ClientId.UniqueProcess = PsGetProcessId((PEPROCESS)object);
- }
- else if (objectType == *PsThreadType)
- {
- handleInfo->ClientId.UniqueThread = PsGetThreadId((PETHREAD)object);
- handleInfo->ClientId.UniqueProcess = PsGetProcessId(IoThreadToProcess((PETHREAD)object));
- }
-
- *ArgumentBlock = argumentBlock;
-
-CleanupName:
- ExFreePoolWithTag(objectNameInfo, TAG_CAPTURE_TEMP_BUFFER);
-CleanupObject:
- ObDereferenceObject(object);
-
- return status;
-}
-
-/* KphpSsCaptureUnicodeStringArgument
- *
- * Captures a UNICODE_STRING argument.
- */
-NTSTATUS KphpSsCaptureUnicodeStringArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PUNICODE_STRING Argument,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- UNICODE_STRING unicodeString;
-
- /* Return if we have a NULL pointer. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Probe and copy the UNICODE_STRING structure. */
- __try
- {
- if (PreviousMode != KernelMode)
- ProbeForRead(Argument, sizeof(UNICODE_STRING), 1);
-
- memcpy(&unicodeString, Argument, sizeof(UNICODE_STRING));
-
- /* Probe the buffer, if present. */
- if (unicodeString.Buffer && PreviousMode != KernelMode)
- {
- ProbeForRead(unicodeString.Buffer, unicodeString.Length, 1);
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
-
- /* Check if the string is too large. */
- if (unicodeString.Length > CAPTURE_UNICODE_STRING_MAX_SIZE)
- return STATUS_UNSUCCESSFUL;
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(
- sizeof(KPHSS_UNICODE_STRING) + unicodeString.Length,
- UnicodeStringArgument
- );
-
- if (!argumentBlock)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Copy the string into the argument block. */
- argumentBlock->UnicodeString.Length = unicodeString.Length;
- argumentBlock->UnicodeString.MaximumLength = unicodeString.MaximumLength;
- argumentBlock->UnicodeString.Pointer = unicodeString.Buffer;
-
- if (unicodeString.Buffer)
- {
- __try
- {
- memcpy(argumentBlock->UnicodeString.Buffer, unicodeString.Buffer, unicodeString.Length);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- KphpSsFreeArgumentBlock(argumentBlock);
- return GetExceptionCode();
- }
- }
-
- *ArgumentBlock = argumentBlock;
-
- return status;
-}
-
-/* KphpSsCaptureObjectAttributesArgument
- *
- * Captures an OBJECT_ATTRIBUTES argument.
- */
-NTSTATUS KphpSsCaptureObjectAttributesArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in POBJECT_ATTRIBUTES Argument,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- OBJECT_ATTRIBUTES objectAttributes;
- PKPHSS_ARGUMENT_BLOCK rootDirectoryArgumentBlock = NULL;
- ULONG rootDirectoryArgumentBlockSize = 0;
- PKPHSS_ARGUMENT_BLOCK objectNameArgumentBlock = NULL;
- ULONG objectNameArgumentBlockSize = 0;
-
- /* Return if we have a NULL pointer. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Probe and copy the OBJECT_ATTRIBUTES structure. */
- __try
- {
- if (PreviousMode != KernelMode)
- ProbeForRead(Argument, sizeof(OBJECT_ATTRIBUTES), 1);
-
- memcpy(&objectAttributes, Argument, sizeof(OBJECT_ATTRIBUTES));
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
-
- /* If we have a root directory, create an argument block from it
- * and copy it to our argument block.
- */
- if (objectAttributes.RootDirectory)
- {
- status = KphpSsCaptureHandleArgument(
- &rootDirectoryArgumentBlock,
- objectAttributes.RootDirectory,
- PreviousMode
- );
-
- /* If we created the argument block, we need to calculate
- * the size of the KPHSS_HANDLE structure.
- */
- if (NT_SUCCESS(status))
- {
- rootDirectoryArgumentBlockSize =
- rootDirectoryArgumentBlock->Header.Size - KPHSS_ARGUMENT_BLOCK_OVERHEAD;
- }
- else
- {
- rootDirectoryArgumentBlock = NULL;
- }
- }
-
- /* If we have a object name, create an argument block from it and
- * copy it to our argument block.
- */
- if (objectAttributes.ObjectName)
- {
- status = KphpSsCaptureUnicodeStringArgument(
- &objectNameArgumentBlock,
- objectAttributes.ObjectName,
- PreviousMode
- );
-
- /* If we created the argument block, we need to calculate
- * the size of the KPHSS_UNICODE_STRING structure.
- */
- if (NT_SUCCESS(status))
- {
- objectNameArgumentBlockSize =
- objectNameArgumentBlock->Header.Size - KPHSS_ARGUMENT_BLOCK_OVERHEAD;
- }
- else
- {
- objectNameArgumentBlock = NULL;
- }
- }
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(
- sizeof(KPHSS_OBJECT_ATTRIBUTES) + rootDirectoryArgumentBlockSize + objectNameArgumentBlockSize,
- ObjectAttributesArgument
- );
-
- argumentBlock->ObjectAttributes.RootDirectoryOffset = 0;
- argumentBlock->ObjectAttributes.ObjectNameOffset = 0;
-
- /* Copy the object attributes fields. */
- memcpy(
- &argumentBlock->ObjectAttributes.ObjectAttributes,
- &objectAttributes,
- sizeof(OBJECT_ATTRIBUTES)
- );
-
- /* Copy the root directory structure, if we have one. */
- if (rootDirectoryArgumentBlock)
- {
- ULONG rootDirectoryOffset;
-
- /* It will go directly after the KPHSS_OBJECT_ATTRIBUTES structure. */
- rootDirectoryOffset = sizeof(KPHSS_OBJECT_ATTRIBUTES);
- argumentBlock->ObjectAttributes.RootDirectoryOffset = (USHORT)rootDirectoryOffset;
- /* Copy it. */
- memcpy(
- PTR_ADD_OFFSET(&argumentBlock->ObjectAttributes, rootDirectoryOffset),
- &rootDirectoryArgumentBlock->Handle,
- rootDirectoryArgumentBlockSize
- );
- /* Free the block. */
- KphpSsFreeArgumentBlock(rootDirectoryArgumentBlock);
- }
-
- /* Copy the object name structure, if we have one. */
- if (objectNameArgumentBlock)
- {
- ULONG objectNameOffset;
-
- /* We'll place the structure after the root directory structure,
- * if present.
- */
- objectNameOffset = sizeof(KPHSS_OBJECT_ATTRIBUTES) + rootDirectoryArgumentBlockSize;
-
- /* Make sure the offset isn't too large. */
- if (objectNameOffset <= MAX_USHORT)
- {
- argumentBlock->ObjectAttributes.ObjectNameOffset = (USHORT)objectNameOffset;
- /* Copy it. */
- memcpy(
- PTR_ADD_OFFSET(&argumentBlock->ObjectAttributes, objectNameOffset),
- &objectNameArgumentBlock->UnicodeString,
- objectNameArgumentBlockSize
- );
- }
-
- /* Free the block. */
- KphpSsFreeArgumentBlock(objectNameArgumentBlock);
- }
-
- *ArgumentBlock = argumentBlock;
-
- return status;
-}
-
-/* KphpSsCaptureClientIdArgument
- *
- * Captures a CLIENT_ID argument.
- */
-NTSTATUS KphpSsCaptureClientIdArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PCLIENT_ID Argument,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- CLIENT_ID clientId;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
-
- /* Check if we have a NULL pointer. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Probe and copy the CLIENT_ID structure. */
- __try
- {
- if (PreviousMode != KernelMode)
- ProbeForRead(Argument, sizeof(CLIENT_ID), 1);
-
- memcpy(&clientId, Argument, sizeof(CLIENT_ID));
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(
- sizeof(CLIENT_ID),
- ClientIdArgument
- );
-
- if (!argumentBlock)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Fill in the argument block. */
- memcpy(&argumentBlock->ClientId, &clientId, sizeof(CLIENT_ID));
-
- *ArgumentBlock = argumentBlock;
-
- return status;
-}
-
-/* KphpSsCaptureBytesArgument
- *
- * Captures a binary blob as an argument.
- */
-NTSTATUS KphpSsCaptureBytesArgument(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in PVOID Argument,
- __in ULONG Length,
- __in KPROCESSOR_MODE PreviousMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
-
- /* Check if we have a NULL pointer. */
- if (!Argument)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Make sure the length isn't too big. */
- if (Length > CAPTURE_BYTES_MAX_SIZE)
- return STATUS_INVALID_PARAMETER_3;
-
- /* Probe the bytes. */
- __try
- {
- if (PreviousMode != KernelMode)
- ProbeForRead(Argument, Length, 1);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
-
- /* Allocate an argument block. */
- argumentBlock = KphpSsAllocateArgumentBlock(
- sizeof(KPHSS_BYTES) + Length,
- BytesArgument
- );
-
- if (!argumentBlock)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Copy the bytes. */
- __try
- {
- memcpy(argumentBlock->Bytes.Buffer, Argument, Length);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- KphpSsFreeArgumentBlock(argumentBlock);
- return GetExceptionCode();
- }
-
- argumentBlock->Bytes.Length = (USHORT)Length;
-
- *ArgumentBlock = argumentBlock;
-
- return status;
-}
-
-/* KphpSsCreateArgumentBlock
- *
- * Allocates and initializes an argument block.
- */
-NTSTATUS KphpSsCreateArgumentBlock(
- __out PKPHSS_ARGUMENT_BLOCK *ArgumentBlock,
- __in ULONG Number,
- __in ULONG Argument,
- __in ULONG Index,
- __in_opt KPHSS_ARGUMENT_TYPE Type,
- __in_opt PVOID Context
- )
-{
-#ifdef _X86_
- NTSTATUS status = STATUS_SUCCESS;
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- KPROCESSOR_MODE previousMode;
- PKPHSS_CALL_ENTRY callEntry;
- KPHSS_ARGUMENT_TYPE argumentType;
-
- previousMode = ExGetPreviousMode();
-
- /* Get a pointer to the call entry for the system service.
- * If we don't have one, we can't proceed.
- */
- callEntry = KphSsLookupCallEntry(Number);
-
- if (!callEntry)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Validate the argument index. */
- if (Index >= callEntry->NumberOfArguments)
- return STATUS_INVALID_PARAMETER_3;
-
- if (Type != 0)
- argumentType = Type;
- else
- argumentType = callEntry->Arguments[Index];
-
- /* Is this a normal argument? If so, there's no point
- * creating an argument block since the data is already
- * in the event block.
- */
- if (argumentType == NormalArgument)
- return STATUS_UNSUCCESSFUL;
-
- /* Capture the argument. */
-
- switch (argumentType)
- {
- case Int8Argument:
- case Int16Argument:
- case Int32Argument:
- case Int64Argument:
- status = KphpSsCaptureSimpleArgument(
- &argumentBlock,
- (PVOID)Argument,
- argumentType,
- previousMode
- );
- break;
- case HandleArgument:
- status = KphpSsCaptureHandleArgument(
- &argumentBlock,
- (HANDLE)Argument,
- previousMode
- );
- break;
- case UnicodeStringArgument:
- status = KphpSsCaptureUnicodeStringArgument(
- &argumentBlock,
- (PUNICODE_STRING)Argument,
- previousMode
- );
- break;
- case ObjectAttributesArgument:
- status = KphpSsCaptureObjectAttributesArgument(
- &argumentBlock,
- (POBJECT_ATTRIBUTES)Argument,
- previousMode
- );
- break;
- case ClientIdArgument:
- status = KphpSsCaptureClientIdArgument(
- &argumentBlock,
- (PCLIENT_ID)Argument,
- previousMode
- );
- break;
- case BytesArgument:
- status = KphpSsCaptureBytesArgument(
- &argumentBlock,
- (PVOID)Argument,
- (ULONG)Context,
- previousMode
- );
- break;
- default:
- status = STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- if (!NT_SUCCESS(status))
- return status;
-
- /* Put the index in. */
- argumentBlock->Index = (UCHAR)Index;
-
- *ArgumentBlock = argumentBlock;
-
- return status;
-#else
- return STATUS_NOT_SUPPORTED;
-#endif
-}
-
-/* KphpSsAllocateArgumentBlock
- *
- * Allocates an argument block and initializes some fields.
- */
-PKPHSS_ARGUMENT_BLOCK KphpSsAllocateArgumentBlock(
- __in ULONG InnerSize,
- __in KPHSS_ARGUMENT_TYPE Type
- )
-{
- PKPHSS_ARGUMENT_BLOCK argumentBlock;
- ULONG size;
-
- size = KPHSS_ARGUMENT_BLOCK_SIZE(InnerSize);
-
- /* Make sure the size isn't too large. */
- if (size > MAX_USHORT)
- return NULL;
-
- argumentBlock = ExAllocatePoolWithTag(
- PagedPool,
- size,
- TAG_ARGUMENT_BLOCK
- );
-
- if (!argumentBlock)
- return NULL;
-
- argumentBlock->Header.Type = ArgumentBlockType;
- argumentBlock->Header.Size = (USHORT)size;
- argumentBlock->Type = Type;
-
- return argumentBlock;
-}
-
-/* KphpSsFreeArgumentBlock
- *
- * Frees an argument block created by KphpSsCreateArgumentBlock.
- */
-VOID KphpSsFreeArgumentBlock(
- __in PKPHSS_ARGUMENT_BLOCK ArgumentBlock
- )
-{
- ExFreePoolWithTag(ArgumentBlock, TAG_ARGUMENT_BLOCK);
-}
-
-/* KphpSsWriteBlock
- *
- * Writes a block into client memory.
- */
-NTSTATUS KphpSsWriteBlock(
- __in PKPHSS_CLIENT_ENTRY ClientEntry,
- __in_opt PKPHSS_BLOCK_HEADER Block,
- __in KPHSS_SEQUENCE_MODE SequenceMode
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- LARGE_INTEGER zeroTimeout;
- KPH_ATTACH_STATE attachState;
- ULONG availableSpace;
- HANDLE dupHandleInClient = NULL;
-
- zeroTimeout.QuadPart = 0;
-
- /* Take care of the sequence mode. If it isn't
- * NoSequence, it is effectively a way for the caller
- * to control the buffer mutex.
- */
- if (SequenceMode == StartSequence)
- {
- ExAcquireFastMutex(&ClientEntry->BufferMutex);
- return STATUS_SUCCESS;
- }
- else if (SequenceMode == EndSequence)
- {
- ExReleaseFastMutex(&ClientEntry->BufferMutex);
- return STATUS_SUCCESS;
- }
- else
- {
- /* If we aren't manipulating the mutex, we need
- * a block to write.
- */
- if (!Block)
- return STATUS_INVALID_PARAMETER_2;
-
- /* If we're in a sequence, don't acquire the mutex
- * because the caller would have acquired it using
- * StartSequence already.
- */
- if (SequenceMode != InSequence)
- ExAcquireFastMutex(&ClientEntry->BufferMutex);
- }
-
- /* Try to acquire the write semaphore. If we can't acquire
- * it immediately, drop the block.
- */
- status = KeWaitForSingleObject(
- ClientEntry->WriteSemaphore,
- Executive,
- KernelMode,
- FALSE,
- &zeroTimeout
- );
-
- if (!KPHSS_BLOCK_SUCCESS(status))
- {
- if (status == STATUS_TIMEOUT)
- {
- dprintf("Ss: WARNING: Dropped block (server %#x).\n", ClientEntry->BufferCursor);
- ClientEntry->NumberOfBlocksDropped++;
- }
-
- goto CleanupBufferMutex;
- }
-
- availableSpace = ClientEntry->BufferSize - ClientEntry->BufferCursor;
-
- /* Blocks are recorded in a circular buffer.
- * In the case that there is not enough space for an entire block,
- * we will record a reset block that tells the client to reset
- * its read cursor to 0. In the case that there is not enough
- * space for a block header, it is implied that the client will
- * reset its read cursor.
- */
-
- /* Check if we have enough space for a block header. */
- if (availableSpace < sizeof(KPHSS_BLOCK_HEADER))
- {
- /* Not enough space. Reset the cursor. */
- dprintf("Ss: Implicit cursor reset (server %#x).\n", ClientEntry->BufferCursor);
- ClientEntry->BufferCursor = 0;
- availableSpace = ClientEntry->BufferSize;
- }
- /* Check if we have enough space for the block. */
- else if (availableSpace < Block->Size)
- {
- KPHSS_RESET_BLOCK resetBlock;
-
- /* Not enough space for the block, but enough space
- * for a reset block. Write the reset block and reset
- * the cursor.
- */
- resetBlock.Header.Size = sizeof(KPHSS_RESET_BLOCK);
- resetBlock.Header.Type = ResetBlockType;
-
- /* Attach to the client process and copy the block. */
- KphAttachProcess(ClientEntry->Process, &attachState);
-
- __try
- {
- memcpy(
- PTR_ADD_OFFSET(ClientEntry->BufferBase, ClientEntry->BufferCursor),
- &resetBlock,
- resetBlock.Header.Size
- );
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- KphDetachProcess(&attachState);
- status = GetExceptionCode();
- goto CleanupBufferMutex;
- }
-
- dprintf("Ss: Wrote reset block (server %#x).\n", ClientEntry->BufferCursor);
- KphDetachProcess(&attachState);
- ClientEntry->BufferCursor = 0;
- availableSpace = ClientEntry->BufferSize;
- }
-
- /* Now that we have dealt with any end-of-buffer issues,
- * we still have to check if we have enough space for the
- * event. We may have a huge event or the client may have a
- * tiny buffer.
- */
- if (availableSpace < Block->Size)
- {
- dfprintf("Ss: WARNING: Insufficient buffer size (server %#x).\n", ClientEntry->BufferCursor);
- status = STATUS_BUFFER_TOO_SMALL;
- goto CleanupBufferMutex;
- }
-
- /* Time to copy the block into the buffer.
- */
- KphAttachProcess(ClientEntry->Process, &attachState);
-
- __try
- {
- memcpy(
- PTR_ADD_OFFSET(ClientEntry->BufferBase, ClientEntry->BufferCursor),
- Block,
- Block->Size
- );
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- dfprintf("Ss: ERROR: Could not write to the client buffer (server %#x)!\n", ClientEntry->BufferCursor);
- KphDetachProcess(&attachState);
- status = GetExceptionCode();
- goto CleanupBufferMutex;
- }
-
- KphDetachProcess(&attachState);
-
- /* Now that we have succesfully copied the block, we need to
- * release the read semaphore to notify to the client that they have
- * a block to read. We also need to advance our cursor.
- */
-
- /* May cause an exception (STATUS_SEMAPHORE_LIMIT_EXCEEDED). */
- __try
- {
- KeReleaseSemaphore(ClientEntry->ReadSemaphore, 2, 1, FALSE);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- dfprintf("Ss: ERROR: Could not release read semaphore (server %#x)!\n", ClientEntry->BufferCursor);
- status = GetExceptionCode();
- goto CleanupBufferMutex;
- }
-
- ClientEntry->BufferCursor += Block->Size;
- ClientEntry->NumberOfBlocksWritten++;
-
- dprintf("Ss: Wrote block (server %#x).\n", ClientEntry->BufferCursor);
-
-CleanupBufferMutex:
- if (SequenceMode != InSequence)
- ExReleaseFastMutex(&ClientEntry->BufferMutex);
-
- return status;
-}
-
-/* KphpSsLogSystemServiceCall
- *
- * Logs a system service.
- *
- * WARNING: This function CANNOT make any system calls.
- *
- * IRQL: <= APC_LEVEL
- */
-VOID NTAPI KphpSsLogSystemServiceCall(
- __in ULONG Number,
- __in ULONG *Arguments,
- __in ULONG NumberOfArguments,
- __in PKSERVICE_TABLE_DESCRIPTOR ServiceTable,
- __in PKTHREAD Thread
- )
-{
-#ifdef _X86_
- NTSTATUS status = STATUS_SUCCESS;
- KPROCESSOR_MODE previousMode;
- PLIST_ENTRY currentListEntry;
- PKPHSS_RULESET_ENTRY ruleSetEntryArray[KPHSS_RULESET_ENTRY_LIMIT];
- ULONG ruleSetEntryCount;
- PKPHSS_EVENT_BLOCK eventBlock;
- PKPHSS_ARGUMENT_BLOCK argumentBlockArray[KPHSS_MAXIMUM_ARGUMENT_BLOCKS];
- ULONG i, j;
-
- previousMode = ExGetPreviousMode();
- /* Ignore the Thread argument. Replace it with our own. */
- Thread = KeGetCurrentThread();
-
- /* First, some checks.
- * * We can't operate at IRQL > APC_LEVEL because
- * of restrictions on logging.
- * * We can't operate on unknown service tables like the
- * shadow service table (yet).
- * * We have to make sure we aren't attempting to log
- * a call to ZwContinue because we caused an exception
- * last time we were logging something. This will cause
- * a deadlock!
- */
-
- if (KeGetCurrentIrql() > APC_LEVEL)
- return;
- if (
- ServiceTable->Base != __KeServiceDescriptorTable->Base ||
- ServiceTable->Number != __KeServiceDescriptorTable->Number ||
- ServiceTable->Limit != __KeServiceDescriptorTable->Limit
- )
- return;
-
- /* Make sure we aren't logging ZwContinue if it's because
- * we caused an exception somewhere. */
- if (
- ServiceTable->Base == __KeServiceDescriptorTable->Base &&
- Number == SsNtContinue &&
- NumberOfArguments == 2 &&
- previousMode == KernelMode
- )
- {
- /* "Reverse probe" the arguments. */
- if (
- (ULONG_PTR)Arguments > (ULONG_PTR)MmHighestUserAddress &&
- Arguments[0] > (ULONG_PTR)MmHighestUserAddress
- )
- {
- CONTEXT context;
-
- /* The first argument contains the context. */
- memcpy(&context, (PCONTEXT)Arguments[0], sizeof(CONTEXT));
- /* Check if the context Eip points into the KPH module.
- * If so, abort the logging.
- */
- if (
- context.Eip >= (ULONG_PTR)KphDriverObject->DriverStart &&
- context.Eip < (ULONG_PTR)KphDriverObject->DriverStart + KphDriverObject->DriverSize
- )
- return;
- }
- }
-
- /* Build the ruleset entry array by going through the ruleset
- * list, referencing each relevant one and copying them into
- * the local array. This we way don't hold the lock for too
- * long.
- */
-
- KeEnterCriticalRegion();
- ExAcquirePushLockShared(&KphSsRuleSetListPushLock);
-
- currentListEntry = KphSsRuleSetListHead.Flink;
- ruleSetEntryCount = 0;
-
- while (
- currentListEntry != &KphSsRuleSetListHead &&
- ruleSetEntryCount < KPHSS_RULESET_ENTRY_LIMIT
- )
- {
- PKPHSS_RULESET_ENTRY ruleSetEntry = KPHSS_RULESET_ENTRY(currentListEntry);
-
- if (KphpSsMatchRuleSetEntry(
- ruleSetEntry,
- Number,
- Arguments,
- NumberOfArguments,
- ServiceTable,
- Thread,
- previousMode
- ))
- {
- /* Reference and store the ruleset entry in the local array. */
- if (KphReferenceObjectSafe(ruleSetEntry))
- {
- /* Make sure the client is enabled. */
- if (ruleSetEntry->Client->Enabled)
- {
- ruleSetEntryArray[ruleSetEntryCount] = ruleSetEntry;
- ruleSetEntryCount++;
- }
- else
- {
- /* We need to use defer delete here because we hold the
- * ruleset list lock.
- */
- KphDereferenceObjectDeferDelete(ruleSetEntry);
- }
- }
- }
-
- currentListEntry = currentListEntry->Flink;
- }
-
- ExReleasePushLock(&KphSsRuleSetListPushLock);
- KeLeaveCriticalRegion();
-
- /* If we didn't find any ruleset entries, don't bother creating the
- * event block.
- */
- if (ruleSetEntryCount == 0)
- return;
-
- /* We have work to do. Create an event block first. */
- if (!NT_SUCCESS(KphpSsCreateEventBlock(
- &eventBlock,
- Thread,
- Number,
- Arguments,
- NumberOfArguments
- )))
- {
- dfprintf("Ss: ERROR: Unable to create an event block!\n");
- return;
- }
-
- memset(argumentBlockArray, 0, sizeof(argumentBlockArray));
-
- /* Process specific argument blocks. */
- KphpSsProcessSpecificArguments(
- argumentBlockArray,
- Number,
- Arguments,
- NumberOfArguments,
- previousMode
- );
-
- /* Create the (generic) argument blocks. If we fail to create one,
- * set the array entry to NULL and we'll skip it later.
- */
-
- for (i = 0; i < NumberOfArguments && i < KPHSS_MAXIMUM_ARGUMENT_BLOCKS; i++)
- {
- ULONG argument;
-
- /* If we already have a specific argument block already, skip this one. */
- if (argumentBlockArray[i])
- continue;
-
- __try
- {
- /* We'll assume the arguments have already been probed
- * since we created the event block successfully.
- */
- argument = Arguments[i];
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- /* Silently skip this argument. Even though it is 99% likely
- * that we will fail to read the next argument, continue
- * anyway.
- */
- argumentBlockArray[i] = NULL;
- continue;
- }
-
- status = KphpSsCreateArgumentBlock(
- &argumentBlockArray[i],
- Number,
- argument,
- i,
- 0,
- NULL
- );
-
- if (!NT_SUCCESS(status))
- argumentBlockArray[i] = NULL;
- }
-
- /* Go through the ruleset entry array and write the blocks to each
- * client. While we're doing that we can also dereference each
- * ruleset entry.
- */
- for (i = 0; i < ruleSetEntryCount; i++)
- {
- /* Begin a sequence. */
- status = KphpSsWriteBlock(ruleSetEntryArray[i]->Client, NULL, StartSequence);
-
- if (NT_SUCCESS(status))
- {
- /* Write the event block. */
- KphpSsWriteBlock(ruleSetEntryArray[i]->Client, &eventBlock->Header, InSequence);
-
- /* Write the argument blocks. */
- for (j = 0; j < NumberOfArguments && j < KPHSS_MAXIMUM_ARGUMENT_BLOCKS; j++)
- {
- if (argumentBlockArray[j])
- {
- KphpSsWriteBlock(ruleSetEntryArray[i]->Client, &argumentBlockArray[j]->Header, InSequence);
- }
- }
-
- /* End the sequence. */
- KphpSsWriteBlock(ruleSetEntryArray[i]->Client, NULL, EndSequence);
- }
-
- KphDereferenceObject(ruleSetEntryArray[i]);
- }
-
- /* Free the event block. */
- KphpSsFreeEventBlock(eventBlock);
-
- /* Free the argument blocks. */
- for (i = 0; i < NumberOfArguments && i < KPHSS_MAXIMUM_ARGUMENT_BLOCKS; i++)
- {
- if (argumentBlockArray[i])
- KphpSsFreeArgumentBlock(argumentBlockArray[i]);
- }
-#else
- KeBugCheck(STATUS_NOT_SUPPORTED);
-#endif
-}
-
-#ifdef _X86_
-
-/* KphpSsNewKiFastCallEntry
- *
- * The hook function called from within the hooked KiFastCallEntry.
- */
-__declspec(naked) VOID NTAPI KphpSsNewKiFastCallEntry()
-{
- /* KiFastCallEntry handles system service calls. User-mode applications
- * will perform system calls like this:
- *
- * Nt*:
- * mov eax, SystemServiceNumber
- * mov edx, 0x7ffe0300 <-- at 0x7ffe0300 we have a pointer to KiFastSystemCall
- * call [edx]
- * ret
- *
- * At KiFastSystemCall:
- * mov edx, esp
- * sysenter
- */
- /* This means that in KiFastCallEntry, eax will contain the system service
- * number while edx will contain a pointer to the arguments for the system
- * service. KiFastCallEntry will fill in edi with the service table, and
- * esi will contain the caller KTHREAD.
- *
- * We cannot hook KiFastCallEntry from the beginning because it starts on the DPC
- * stack. KiFastCallEntry switches to the proper thread stack, and we want to
- * hook it just after it switches to the stack. That way we can avoid having to
- * manually switch the thread stack ourselves.
- *
- * At this point:
- * * eax contains the system service number.
- * * edx contains a pointer to the user-supplied arguments for
- * the system service.
- * * edi contains a pointer to the service table associated with
- * the system service number.
- * * esi contains a pointer to the KTHREAD of the caller.
- */
- /* Some context:
- *
- * push edx
- * push eax
- * call [_KeGdiFlushUserBatch]
- * pop eax
- * pop edx
- * inc dword ptr fs:[PbSystemCalls] <-- this gets overwritten with a jmp to here
- * mov edi, edx
- * mov ebx, [edi+...]
- * ...
- */
- __asm
- {
- /* Save all registers first. */
- push ebp
- push edi
- push esi
- push edx
- push ecx
- push ebx
- push eax
-
- /* Since we overwrite the inc instruction when we did the hook,
- * perform the job now - we have to increment the system calls
- * counter.
- */
- lea ebx, KphSsKiFastCallEntryHook /* get a pointer to the hook structure */
- mov ebx, dword ptr [ebx+KPH_HOOK.Bytes+3] /* get the PbSystemCalls offset from the original inc instruction */
- inc dword ptr fs:[ebx] /* increment PbSystemCalls in the PRCB */
-
- /* Get the number of arguments for this system service. */
- mov ebx, dword ptr [edi+KSERVICE_TABLE_DESCRIPTOR.Number] /* ebx = a pointer to the argument table */
- xor ecx, ecx
- mov cl, [ebx+eax] /* ecx = size of the arguments, in bytes. */
- shr ecx, 2 /* divide by 2 to get the number of arguments (all ULONGs) */
-
- /* Call the KiFastCallEntry proc while maintaining the logger count
- * so that the driver doesn't get unloaded while we're executing.
- */
- push esi /* Thread */
- push edi /* ServiceTable */
- push ecx /* NumberOfArguments */
- push edx /* Arguments */
- push eax /* Number */
- lock inc dword ptr KphSsNumberOfActiveLoggers
- call KphpSsLogSystemServiceCall
- lock dec dword ptr KphSsNumberOfActiveLoggers
-
- /* Restore the registers and resume execution in KiFastCallEntry. */
- pop eax
- pop ebx
- pop ecx
- pop edx
- pop esi
- pop edi
- pop ebp
-
- /* Luckily, KiFastCallEntry will overwrite ebx when we jump back, so it's safe to use it. */
- lea ebx, __KiFastCallEntry
- mov ebx, [ebx] /* ebx = KiFastCallEntry at the inc instruction */
- add ebx, 7 /* skip the inc instruction */
- jmp ebx /* jump back */
- }
-}
-
-#else
-
-VOID NTAPI KphpSsNewKiFastCallEntry()
-{
- KeBugCheck(STATUS_NOT_SUPPORTED);
-}
-
-#endif
diff --git a/2.x/trunk/KProcessHacker/sysservicedata.c b/2.x/trunk/KProcessHacker/sysservicedata.c
deleted file mode 100644
index c30c36917..000000000
--- a/2.x/trunk/KProcessHacker/sysservicedata.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Process Hacker Driver -
- * system service logging (data)
- *
- * Copyright (C) 2009 wj32
- *
- * This file is part of Process Hacker.
- *
- * Process Hacker is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Process Hacker is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Process Hacker. If not, see .
- */
-
-#define _SYSSERVICEDATA_PRIVATE
-#include "include/sysservicedata.h"
-
-PVOID KphpSsCallEntryAllocateRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in CLONG ByteSize
- );
-
-RTL_GENERIC_COMPARE_RESULTS KphpSsCallEntryCompareRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in PVOID FirstStruct,
- __in PVOID SecondStruct
- );
-
-VOID KphpSsCallEntryFreeRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in PVOID Buffer
- );
-
-KPHSS_CALL_ENTRY SsEntries[] =
-{
- /* NTSTATUS NtAddAtom(PWSTR String, ULONG StringLength, PUSHORT Atom) */
- { &SsNtAddAtom, "NtAddAtom", 3, { WStringArgument, 0, Int16Argument } },
- /* NTSTATUS NtAlertResumeThread(HANDLE ThreadHandle, PULONG PreviousSuspendCount) */
- { &SsNtAlertResumeThread, "NtAlertResumeThread", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtAlertThread(HANDLE ThreadHandle) */
- { &SsNtAlertThread, "NtAlertThread", 1, { HandleArgument } },
- /* NTSTATUS NtAllocateLocallyUniqueId(PLUID Luid) */
- { &SsNtAllocateLocallyUniqueId, "NtAllocateLocallyUniqueId", 1, { 0 } },
- /* NTSTATUS NtAllocateUserPhysicalPages(HANDLE ProcessHandle, PULONG NumberOfPages, PULONG PageFrameNumbers) */
- { &SsNtAllocateUserPhysicalPages, "NtAllocateUserPhysicalPages", 3, { HandleArgument, Int32Argument, 0 } },
- /* NTSTATUS NtAllocateUuids(PLARGE_INTEGER UuidLastTimeAllocated, PULONG UuidDeltaTime, PULONG UuidSequenceNumber,
- * PUCHAR UuidSeed) */
- { &SsNtAllocateUuids, "NtAllocateUuids", 4, { Int64Argument, 0, 0, 0 } },
- /* NTSTATUS NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits,
- * PULONG AllocationSize, ULONG AllocationType, ULONG Protect) */
- { &SsNtAllocateVirtualMemory, "NtAllocateVirtualMemory", 6, { HandleArgument, Int32Argument, 0, Int32Argument, 0, 0 } },
- /* NTSTATUS NtApphelpCacheControl(APPHELPCACHECONTROL ApphelpCacheControl, PUNICODE_STRING ApphelpCacheObject) */
- { &SsNtApphelpCacheControl, "NtApphelpCacheControl", 2, { 0, UnicodeStringArgument } },
- /* NTSTATUS NtAreMappedFilesTheSame(PVOID Address1, PVOID Address2) */
- { &SsNtAreMappedFilesTheSame, "NtAreMappedFilesTheSame", 2, { 0, 0 } },
- /* NTSTATUS NtAssignProcessToJobObject(HANDLE JobHandle, HANDLE ProcessHandle) */
- { &SsNtAssignProcessToJobObject, "NtAssignProcessToJobObject", 2, { HandleArgument, HandleArgument } },
- /* NTSTATUS NtCallbackReturn(PVOID Result, ULONG ResultLength, NTSTATUS Status) */
- { &SsNtCallbackReturn, "NtCallbackReturn", 3, { 0, 0, 0 } },
- /* NTSTATUS NtCancelDeviceWakeupRequest(HANDLE DeviceHandle) */
- { &SsNtCancelDeviceWakeupRequest, "NtCancelDeviceWakeupRequest", 1, { HandleArgument } },
- /* NTSTATUS NtCancelIoFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock) */
- { &SsNtCancelIoFile, "NtCancelIoFile", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtCancelTimer(HANDLE TimerHandle, PBOOLEAN CurrentState) */
- { &SsNtCancelTimer, "NtCancelTimer", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtClearEvent(HANDLE EventHandle) */
- { &SsNtClearEvent, "NtClearEvent", 1, { HandleArgument } },
- /* NTSTATUS NtClose(HANDLE Handle) */
- { &SsNtClose, "NtClose", 1, { HandleArgument } },
- /* NTSTATUS NtContinue(PCONTEXT Context, BOOLEAN TestAlert) */
- { &SsNtContinue, "NtContinue", 2, { ContextArgument, 0 } },
- /* NTSTATUS NtCreateDebugObject(PHANDLE DebugObjectHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * ULONG Flags) */
- { &SsNtCreateDebugObject, "NtCreateDebugObject", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtCreateDirectoryObject, "NtCreateDirectoryObject", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtCreateEvent(PHANDLE EventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * EVENT_TYPE EventType, BOOLEAN InitialState) */
- { &SsNtCreateEvent, "NtCreateEvent", 5, { 0, 0, ObjectAttributesArgument, 0, 0 } },
- /* NTSTATUS NtCreateEventPair(PHANDLE EventPairHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtCreateEventPair, "NtCreateEventPair", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes,
- * ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions,
- * PVOID EaBuffer, ULONG EaLength) */
- { &SsNtCreateFile, "NtCreateFile", 11, { 0, 0, ObjectAttributesArgument, 0, Int64Argument, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtCreateIoCompletion(PHANDLE IoCompletionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * ULONG NumberOfConcurrentThreads) */
- { &SsNtCreateIoCompletion, "NtCreateIoCompletion", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateJobObject(PHANDLE JobHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtCreateJobObject, "NtCreateJobObject", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtCreateJobSet(ULONG NumJob, IN PJOB_SET_ARRAY UserJobSet, IN ULONG Flags) */
- { &SsNtCreateJobSet, "NtCreateJobSet", 3, { 0, 0, 0 } },
- /* NTSTATUS NtCreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * ULONG TitleIndex, PUNICODE_STRING Class, ULONG CreateOptions,
- * PULONG Disposition) */
- { &SsNtCreateKey, "NtCreateKey", 7, { 0, 0, ObjectAttributesArgument, 0, UnicodeStringArgument, 0, 0 } },
- /* NTSTATUS NtCreateKeyedEvent(PHANDLE KeyedEventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * ULONG Flags) */
- { &SsNtCreateKeyedEvent, "NtCreateKeyedEvent", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateMailslotFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PIO_STATUS_BLOCK IoStatusBlock, ULONG CreateOptions, ULONG MailslotQuota,
- * ULONG MaximumMessageSize, PLARGE_INTEGER ReadTimeout) */
- { &SsNtCreateMailslotFile, "NtCreateMailslotFile", 8, { 0, 0, ObjectAttributesArgument, 0, 0, 0, 0, Int64Argument } },
- /* NTSTATUS NtCreateMutant(PHANDLE MutantHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * BOOLEAN InitialOwner) */
- { &SsNtCreateMutant, "NtCreateMutant", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateNamedPipeFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG CreateDisposition,
- * ULONG CreateOptions, BOOLEAN TypeMessage, BOOLEAN ReadmodeMessage,
- * BOOLEAN Nonblocking, ULONG MaxInstances, ULONG InBufferSize,
- * ULONG OutBufferSize, PLARGE_INTEGER DefaultTimeout) */
- { &SsNtCreateNamedPipeFile, "NtCreateNamedPipeFile", 14, { 0, 0, ObjectAttributesArgument, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Int64Argument } },
- /* NTSTATUS NtCreatePagingFile(PUNICODE_STRING FileName, PULARGE_INTEGER MinimumSize, PULARGE_INTEGER MaximumSize,
- * ULONG Priority) */
- { &SsNtCreatePagingFile, "NtCreatePagingFile", 4, { UnicodeStringArgument, Int64Argument, Int64Argument, 0 } },
- /* NTSTATUS NtCreatePort(PHANDLE PortHandle, POBJECT_ATTRIBUTES ObjectAttributes, ULONG MaxConnectionInfoLength,
- * ULONG MaxMessageLength, ULONG MaxPoolUsage) */
- { &SsNtCreatePort, "NtCreatePort", 5, { 0, ObjectAttributesArgument, 0, 0, 0 } },
- /* NTSTATUS NtCreatePrivateNamespace(PHANDLE PrivateNamespaceHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PBOUNDARY_DESCRIPTOR BoundaryDescriptor) */
- { &SsNtCreatePrivateNamespace, "NtCreatePrivateNamespace", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * HANDLE InheritFromProcessHandle, BOOLEAN InheritHandles, HANDLE SectionHandle,
- * HANDLE DebugPort, HANDLE ExceptionPort) */
- { &SsNtCreateProcess, "NtCreateProcess", 8, { 0, 0, ObjectAttributesArgument, HandleArgument, 0, HandleArgument, HandleArgument, HandleArgument } },
- /* NTSTATUS NtCreateProcessEx(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * HANDLE ParentProcess, ULONG Flags, HANDLE SectionHandle,
- * HANDLE DebugPort, HANDLE ExceptionPort, ULONG JobMemberLevel */
- { &SsNtCreateProcessEx, "NtCreateProcessEx", 9, { 0, 0, ObjectAttributesArgument, HandleArgument, 0, HandleArgument, HandleArgument, HandleArgument, 0 } },
- /* NTSTATUS NtCreateProfile(PHANDLE ProfileHandle, HANDLE ProcessHandle, PVOID Base,
- * ULONG Size, ULONG BucketShift, PULONG Buffer,
- * ULONG BufferLength, KPROFILE_SOURCE Source, ULONG ProcessorMask) */
- { &SsNtCreateProfile, "NtCreateProfile", 9, { 0, HandleArgument, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PLARGE_INTEGER SectionSize, ULONG Protect, ULONG Attributes,
- * HANDLE FileHandle) */
- { &SsNtCreateSection, "NtCreateSection", 7, { 0, 0, ObjectAttributesArgument, Int64Argument, 0, 0, HandleArgument } },
- /* NTSTATUS NtCreateSemaphore(PHANDLE SemaphoreHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * LONG InitialCount, LONG MaximumCount) */
- { &SsNtCreateSemaphore, "NtCreateSemaphore", 5, { 0, 0, ObjectAttributesArgument, 0, 0 } },
- /* NTSTATUS NtCreateSymbolicLinkObject(PHANDLE SymbolicLinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PUNICODE_STRING TargetName) */
- { &SsNtCreateSymbolicLinkObject, "NtCreateSymbolicLinkObject", 4, { 0, 0, ObjectAttributesArgument, UnicodeStringArgument } },
- /* NTSTATUS NtCreateThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * HANDLE ProcessHandle, PCLIENT_ID ClientId, PCONTEXT ThreadContext,
- * PINITIAL_TEB UserStack, BOOLEAN CreateSuspended) */
- { &SsNtCreateThread, "NtCreateThread", 8, { 0, 0, ObjectAttributesArgument, HandleArgument, 0, ContextArgument, InitialTebArgument, 0 } },
- /* NTSTATUS NtCreateTimer(PHANDLE TimerHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * TIMER_TYPE TimerType) */
- { &SsNtCreateTimer, "NtCreateTimer", 4, { 0, 0, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtCreateToken(PHANDLE TokenHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * TOKEN_TYPE Type, PLUID AuthenticationId, PLARGE_INTEGER ExpirationTime,
- * PTOKEN_USER User, PTOKEN_GROUPS Groups, PTOKEN_PRIVILEGES Privileges,
- * PTOKEN_OWNER Owner, PTOKEN_PRIMARY_GROUP PrimaryGroup, PTOKEN_DEFAULT_DACL DefaultDacl,
- * PTOKEN_SOURCE Source) */
- { &SsNtCreateToken, "NtCreateToken", 13, { 0, 0, ObjectAttributesArgument, 0, Int64Argument, Int64Argument, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtCreateWaitablePort(PHANDLE PortHandle, POBJECT_ATTRIBUTES ObjectAttributes, ULONG MaxConnectionInfoLength,
- * ULONG MaxMessageLength, ULONG MaxPoolUsage) */
- { &SsNtCreateWaitablePort, "NtCreateWaitablePort", 5, { 0, ObjectAttributesArgument, 0, 0, 0 } },
- /* NTSTATUS NtDebugActiveProcess(HANDLE ProcessHandle, HANDLE DebugObjectHandle) */
- { &SsNtDebugActiveProcess, "NtDebugActiveProcess", 2, { HandleArgument, HandleArgument } },
- /* NTSTATUS NtDebugContinue(HANDLE DebugObjectHandle, PCLIENT_ID ClientId, NTSTATUS ContinueStatus) */
- { &SsNtDebugContinue, "NtDebugContinue", 3, { HandleArgument, ClientIdArgument, 0 } },
- /* NTSTATUS NtDelayExecution(BOOLEAN Alertable, PLARGE_INTEGER Interval) */
- { &SsNtDelayExecution, "NtDelayExecution", 2, { 0, Int64Argument } },
- /* NTSTATUS NtDeleteAtom(USHORT Atom) */
- { &SsNtDeleteAtom, "NtDeleteAtom", 1, { 0 } },
- /* NTSTATUS NtDeleteBootEntry(ULONG Id) */
- { &SsNtDeleteBootEntry, "NtDeleteBootEntry", 1, { 0 } },
- /* NTSTATUS NtDeleteDriverEntry(ULONG Id) */
- { &SsNtDeleteDriverEntry, "NtDeleteDriverEntry", 1, { 0 } },
- /* NTSTATUS NtDeleteFile(POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtDeleteFile, "NtDeleteFile", 1, { ObjectAttributesArgument } },
- /* NTSTATUS NtDeleteKey(HANDLE KeyHandle) */
- { &SsNtDeleteKey, "NtDeleteKey", 1, { HandleArgument } },
- /* NTSTATUS NtDeleteObjectAuditAlarm(PUNICODE_STRING SubsystemName, PVOID HandleId, BOOLEAN GenerateOnClose) */
- { &SsNtDeleteObjectAuditAlarm, "NtDeleteObjectAuditAlarm", 3, { UnicodeStringArgument, 0, 0 } },
- /* NTSTATUS NtDeletePrivateNamespace(HANDLE PrivateNamespaceHandle) */
- { &SsNtDeletePrivateNamespace, "NtDeletePrivateNamespace", 1, { HandleArgument } },
- /* NTSTATUS NtDeleteValueKey(HANDLE KeyHandle, PUNICODE_STRING ValueName) */
- { &SsNtDeleteValueKey, "NtDeleteValueKey", 2, { HandleArgument, UnicodeStringArgument } },
- /* NTSTATUS NtDeviceIoControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode,
- * PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer,
- * ULONG OutputBufferLength) */
- { &SsNtDeviceIoControlFile, "NtDeviceIoControlFile", 10, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtDisplayString(PUNICODE_STRING String) */
- { &SsNtDisplayString, "NtDisplayString", 1, { UnicodeStringArgument } },
- /* NTSTATUS NtDuplicateObject(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle,
- * PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, ULONG Attributes,
- * ULONG Options) */
- { &SsNtDuplicateObject, "NtDuplicateObject", 7, { HandleArgument, HandleArgument, HandleArgument, 0, 0, 0, 0 } },
- /* NTSTATUS NtDuplicateToken(HANDLE ExistingTokenHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * BOOLEAN EffectiveOnly, TOKEN_TYPE TokenType, PHANDLE NewTokenHandle) */
- { &SsNtDuplicateToken, "NtDuplicateToken", 6, { HandleArgument, 0, ObjectAttributesArgument, 0, 0, 0 } },
- /* NTSTATUS NtEnumerateBootEntries(PVOID Buffer, PULONG BufferLength) */
- { &SsNtEnumerateBootEntries, "NtEnumerateBootEntries", 2, { 0, Int32Argument } },
- /* NTSTATUS NtEnumerateDriverEntries(PVOID Buffer, PULONG BufferLength) */
- { &SsNtEnumerateDriverEntries, "NtEnumerateDriverEntries", 2, { 0, Int32Argument } },
- /* NTSTATUS NtEnumerateKey(HANDLE KeyHandle, ULONG Index, KEY_INFORMATION_CLASS KeyInformationClass,
- * PVOID KeyInformation, ULONG KeyInformationLength, PULONG ResultLength) */
- { &SsNtEnumerateKey, "NtEnumerateKey", 6, { HandleArgument, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtEnumerateSystemEnvironmentValuesEx(ULONG InformationClass, PVOID Buffer, PULONG BufferLength) */
- { &SsNtEnumerateSystemEnvironmentValuesEx, "NtEnumerateSystemEnvironmentValuesEx", 3, { 0, 0, Int32Argument } },
- /* NTSTATUS NtEnumerateValueKey(HANDLE KeyHandle, ULONG Index, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
- * PVOID KeyValueInformation, ULONG KeyValueInformationLength, PULONG ResultLength) */
- { &SsNtEnumerateValueKey, "NtEnumerateValueKey", 6, { HandleArgument, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtExtendSection(HANDLE SectionHandle, PLARGE_INTEGER SectionSize) */
- { &SsNtExtendSection, "NtExtendSection", 2, { HandleArgument, Int64Argument } },
- /* NTSTATUS NtFilterToken(HANDLE ExistingTokenHandle, ULONG Flags, PTOKEN_GROUPS SidsToDisable,
- * PTOKEN_PRIVILEGES PrivilegesToDelete, PTOKEN_GROUPS SidsToRestricted, PHANDLE NewTokenHandle) */
- { &SsNtFilterToken, "NtFilterToken", 6, { HandleArgument, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtFindAtom(PWSTR String, ULONG StringLength, PUSHORT Atom) */
- { &SsNtFindAtom, "NtFindAtom", 3, { WStringArgument, 0, 0 } },
- /* NTSTATUS NtFlushBuffersFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock) */
- { &SsNtFlushBuffersFile, "NtFlushBuffersFile", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtFlushInstructionCache(HANDLE ProcessHandle, PVOID BaseAddress, ULONG FlushSize) */
- { &SsNtFlushInstructionCache, "NtFlushInstructionCache", 3, { HandleArgument, 0, 0 } },
- /* NTSTATUS NtFlushKey(HANDLE KeyHandle) */
- { &SsNtFlushKey, "NtFlushKey", 1, { HandleArgument } },
- /* NTSTATUS NtFlushProcessWriteBuffers() */
- { &SsNtFlushProcessWriteBuffers, "NtFlushProcessWriteBuffers", 0 },
- /* NTSTATUS NtFlushVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, PULONG FlushSize,
- * PIO_STATUS_BLOCK IoStatusBlock) */
- { &SsNtFlushVirtualMemory, "NtFlushVirtualMemory", 4, { HandleArgument, Int32Argument, Int32Argument, 0 } },
- /* NTSTATUS NtFlushWriteBuffer() */
- { &SsNtFlushWriteBuffer, "NtFlushWriteBuffer", 0 },
- /* NTSTATUS NtFreeUserPhysicalPages(HANDLE ProcessHandle, PULONG NumberOfPages, PULONG PageFrameNumbers) */
- { &SsNtFreeUserPhysicalPages, "NtFreeUserPhysicalPages", 3, { HandleArgument, Int32Argument, 0 } },
- /* NTSTATUS NtFreeVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, PULONG FreeSize,
- * ULONG FreeType) */
- { &SsNtFreeVirtualMemory, "NtFreeVirtualMemory", 4, { HandleArgument, Int32Argument, Int32Argument, 0 } },
- /* NTSTATUS NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode,
- * PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer,
- * ULONG OutputBufferLength) */
- { &SsNtFsControlFile, "NtFsControlFile", 10, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtGetContextThread(HANDLE ThreadHandle, PCONTEXT Context) */
- { &SsNtGetContextThread, "NtGetContextThread", 2, { HandleArgument, ContextArgument } },
- /* NTSTATUS NtGetCurrentProcessorNumber() */
- { &SsNtGetCurrentProcessorNumber, "NtGetCurrentProcessorNumber", 0 },
- /* NTSTATUS NtGetDevicePowerState(HANDLE DeviceHandle, PDEVICE_POWER_STATE DevicePowerState) */
- { &SsNtGetDevicePowerState, "NtGetDevicePowerState", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtGetNextProcess(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes,
- * ULONG Flags, PHANDLE NewProcessHandle) */
- { &SsNtGetNextProcess, "NtGetNextProcess", 5, { HandleArgument, 0, 0, 0, 0 } },
- /* NTSTATUS NtGetNextThread(HANDLE ProcessHandle, HANDLE ThreadHandle, ACCESS_MASK DesiredAccess,
- * ULONG HandleAttributes, ULONG Flags, PHANDLE NewThreadHandle) */
- { &SsNtGetNextThread, "NtGetNextThread", 6, { HandleArgument, HandleArgument, 0, 0, 0, 0 } },
- /* NTSTATUS NtGetPlugPlayEvent(HANDLE EventHandle, PVOID Context, PVOID Buffer,
- * ULONG BufferLength) */
- { &SsNtGetPlugPlayEvent, "NtGetPlugPlayEvent", 4, { HandleArgument, 0, 0, 0 } },
- /* NTSTATUS NtGetWriteWatch(HANDLE ProcessHandle, ULONG Flags, PVOID BaseAddress,
- * ULONG RegionSize, PULONG Buffer, PULONG BufferEntries,
- * PULONG Granularity) */
- { &SsNtGetWriteWatch, "NtGetWriteWatch", 7, { HandleArgument, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtImpersonateAnonymousToken(HANDLE ThreadHandle) */
- { &SsNtImpersonateAnonymousToken, "NtImpersonateAnonymousToken", 1, { HandleArgument } },
- /* NTSTATUS NtImpersonateClientOfPort(HANDLE PortHandle, PPORT_MESSAGE Message) */
- { &SsNtImpersonateClientOfPort, "SsNtImpersonateClientOfPort", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtImpersonateThread(HANDLE ThreadHandle, HANDLE TargetThreadHandle, PSECURITY_QUALITY_OF_SERVICE SecurityQos) */
- { &SsNtImpersonateThread, "NtImpersonateThread", 3, { HandleArgument, HandleArgument, 0 } },
- /* NTSTATUS NtInitiatePowerAction(POWER_ACTION SystemAction, SYSTEM_POWER_STATE MinSystemState, ULONG Flags,
- * BOOLEAN Asynchronous) */
- { &SsNtInitiatePowerAction, "NtInitiatePowerAction", 4, { 0, 0, 0, 0 } },
- /* NTSTATUS NtIsProcessInJob(HANDLE ProcessHandle, HANDLE JobHandle) */
- { &SsNtIsProcessInJob, "NtIsProcessInJob", 2, { HandleArgument, HandleArgument } },
- /* NTSTATUS NtIsSystemResumeAutomatic() */
- { &SsNtIsSystemResumeAutomatic, "NtIsSystemResumeAutomatic", 0 },
- /* NTSTATUS NtListenPort(HANDLE PortHandle, PPORT_MESSAGE Message) */
- { &SsNtListenPort, "NtListenPort", 2, { HandleArgument, 0 } },
- /* NTSTATUS NtLoadDriver(PUNICODE_STRING DriverServiceName) */
- { &SsNtLoadDriver, "NtLoadDriver", 1, { UnicodeStringArgument } },
- /* NTSTATUS NtLoadKey(POBJECT_ATTRIBUTES KeyObjectAttributes, POBJECT_ATTRIBUTES FileObjectAttributes) */
- { &SsNtLoadKey, "NtLoadKey", 2, { ObjectAttributesArgument, ObjectAttributesArgument } },
- /* NTSTATUS NtLoadKey2(POBJECT_ATTRIBUTES KeyObjectAttributes, POBJECT_ATTRIBUTES FileObjectAttributes, ULONG Flags) */
- { &SsNtLoadKey2, "NtLoadKey2", 3, { ObjectAttributesArgument, ObjectAttributesArgument, 0 } },
- /* NTSTATUS NtLockFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PULARGE_INTEGER LockOffset,
- * PULARGE_INTEGER LockLength, ULONG Key, BOOLEAN FailImmediately,
- * BOOLEAN ExclusiveLock) */
- { &SsNtLockFile, "NtLockFile", 10, { HandleArgument, HandleArgument, 0, 0, 0, Int64Argument, Int64Argument, 0, 0, 0 } },
- /* NTSTATUS NtLockVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, PULONG LockSize,
- * ULONG LockType) */
- { &SsNtLockVirtualMemory, "NtLockVirtualMemory", 4, { HandleArgument, Int32Argument, Int32Argument, 0 } },
- /* NTSTATUS NtMakePermanentObject(HANDLE Handle) */
- { &SsNtMakePermanentObject, "NtMakePermanentObject", 1, { HandleArgument } },
- /* NTSTATUS NtMakeTemporaryObject(HANDLE Handle) */
- { &SsNtMakeTemporaryObject, "NtMakeTemporaryObject", 1, { HandleArgument } },
- /* NTSTATUS NtMapUserPhysicalPages(PVOID BaseAddress, PULONG NumberOfPages, PULONG PageFrameNumbers) */
- { &SsNtMapUserPhysicalPages, "NtMapUserPhysicalPages", 3, { 0, Int32Argument, 0 } },
- /* NTSTATUS NtMapUserPhysicalPagesScatter(PVOID BaseAddress, PULONG NumberOfPages, PULONG PageFrameNumbers) */
- { &SsNtMapUserPhysicalPagesScatter, "NtMapUserPhysicalPagesScatter", 3, { 0, Int32Argument, 0 } },
- /* NTSTATUS NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress,
- * ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset,
- * PULONG ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType,
- * ULONG Protect) */
- { &SsNtMapViewOfSection, "NtMapViewOfSection", 10, { HandleArgument, HandleArgument, Int32Argument, 0, 0, Int64Argument, Int32Argument, 0, 0, 0 } },
- /* NTSTATUS NtModifyBootEntry(PBOOT_ENTRY BootEntry) */
- { &SsNtModifyBootEntry, "NtModifyBootEntry", 1, { 0 } },
- /* NTSTATUS NtModifyDriverEntry(PEFI_DRIVER_ENTRY DriverEntry) */
- { &SsNtModifyDriverEntry, "NtModifyDriverEntry", 1, { 0 } },
- /* NTSTATUS NtNotifyChangeDirectoryFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PFILE_NOTIFY_INFORMATION Buffer,
- * ULONG BufferLength, ULONG NotifyFilter, BOOLEAN WatchSubtree) */
- { &SsNtNotifyChangeDirectoryFile, "NtNotifyChangeDirectoryFile", 9, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtNotifyChangeKey(HANDLE KeyHandle, HANDLE EventHandle, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG NotifyFilter,
- * BOOLEAN WatchSubtree, PVOID Buffer, ULONG BufferLength,
- * BOOLEAN Asynchronous) */
- { &SsNtNotifyChangeKey, "NtNotifyChangeKey", 10, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtNotifyChangeMultipleKeys(HANDLE KeyHandle, ULONG Flags, POBJECT_ATTRIBUTES KeyObjectAttributes,
- * HANDLE EventHandle, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
- * PIO_STATUS_BLOCK IoStatusBlock, ULONG NotifyFilter, BOOLEAN WatchSubtree,
- * PVOID Buffer, ULONG BufferLength, BOOLEAN Asynchronous) */
- { &SsNtNotifyChangeMultipleKeys, "NtNotifyChangeMultipleKeys", 12, { HandleArgument, 0, ObjectAttributesArgument, HandleArgument, 0, 0, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenDirectoryObject, "NtOpenDirectoryObject", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenEvent(PHANDLE EventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenEvent, "NtOpenEvent", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenEventPair(PHANDLE EventPairHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenEventPair, "NtOpenEventPair", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions) */
- { &SsNtOpenFile, "NtOpenFile", 6, { 0, 0, ObjectAttributesArgument, 0, 0, 0 } },
- /* NTSTATUS NtOpenIoCompletion(PHANDLE IoCompletionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenIoCompletion, "NtOpenIoCompletion", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenJobObject(PHANDLE JobHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenJobObject, "NtOpenJobObject", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenKey, "NtOpenKey", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenKeyedEvent(PHANDLE KeyedEventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenKeyedEvent, "NtOpenKeyedEvent", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenMutant(PHANDLE MutantHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenMutant, "NtOpenMutant", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenObjectAuditAlarm(PUNICODE_STRING SubsystemName, PVOID *HandleId, PUNICODE_STRING ObjectTypeName,
- * PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, HANDLE TokenHandle,
- * ACCESS_MASK DesiredAccess, ACCESS_MASK GrantedAccess, PPRIVILEGE_SET Privileges,
- * BOOLEAN ObjectCreation, BOOLEAN AccessGranted, PBOOLEAN GenerateOnClose) */
- { &SsNtOpenObjectAuditAlarm, "NtOpenObjectAuditAlarm", 12, { UnicodeStringArgument, Int32Argument, UnicodeStringArgument, UnicodeStringArgument, 0, HandleArgument, 0, 0, 0, 0, 0, 0 } },
- /* NTSTATUS NtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PCLIENT_ID ClientId) */
- { &SsNtOpenProcess, "NtOpenProcess", 4, { 0, 0, ObjectAttributesArgument, ClientIdArgument } },
- /* NTSTATUS NtOpenProcessToken(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, PHANDLE TokenHandle) */
- { &SsNtOpenProcessToken, "NtOpenProcessToken", 3, { HandleArgument, 0, 0 } },
- /* NTSTATUS NtOpenProcessTokenEx(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes,
- * PHANDLE TokenHandle) */
- { &SsNtOpenProcessTokenEx, "NtOpenProcessTokenEx", 4, { HandleArgument, 0, 0, 0 } },
- /* NTSTATUS NtOpenSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenSection, "NtOpenSection", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenSemaphore(PHANDLE SemaphoreHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenSemaphore, "NtOpenSemaphore", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenSymbolicLinkObject(PHANDLE SymbolicLinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenSymbolicLinkObject, "NtOpenSymbolicLinkObject", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtOpenThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
- * PCLIENT_ID ClientId) */
- { &SsNtOpenThread, "NtOpenThread", 4, { 0, 0, ObjectAttributesArgument, ClientIdArgument } },
- /* NTSTATUS NtOpenThreadToken(HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, BOOLEAN OpenAsSelf,
- * PHANDLE TokenHandle) */
- { &SsNtOpenThreadToken, "NtOpenThreadToken", 4, { HandleArgument, 0, 0, 0 } },
- /* NTSTATUS NtOpenThreadTokenEx(HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, BOOLEAN OpenAsSelf,
- * ULONG HandleAttributes, PHANDLE TokenHandle) */
- { &SsNtOpenThreadTokenEx, "NtOpenThreadTokenEx", 5, { HandleArgument, 0, 0, 0, 0 } },
- /* NTSTATUS NtOpenTimer(PHANDLE TimerHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) */
- { &SsNtOpenTimer, "NtOpenTimer", 3, { 0, 0, ObjectAttributesArgument } },
- /* NTSTATUS NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
- * ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) */
- { &SsNtReadFile, "NtReadFile", 9, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, Int64Argument, Int32Argument } },
- /* NTSTATUS NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine,
- * PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer,
- * ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key) */
- { &SsNtWriteFile, "NtWriteFile", 9, { HandleArgument, HandleArgument, 0, 0, 0, 0, 0, Int64Argument, Int32Argument } },
-
- { NULL, "Dummy", 0 }
-};
-
-RTL_GENERIC_TABLE KphSsCallTable;
-FAST_MUTEX KphSsCallTableMutex;
-
-/* KphSsDataInit
- *
- * Initializes all data structures so that system service entries
- * can be looked up.
- */
-VOID KphSsDataInit()
-{
- ULONG i;
-
- RtlInitializeGenericTable(
- &KphSsCallTable,
- KphpSsCallEntryCompareRoutine,
- KphpSsCallEntryAllocateRoutine,
- KphpSsCallEntryFreeRoutine,
- NULL
- );
-
- for (i = 0; i < sizeof(SsEntries) / sizeof(KPHSS_CALL_ENTRY); i++)
- {
- /* Ignore the dummy entry. */
- if (SsEntries[i].Number)
- {
- RtlInsertElementGenericTable(
- &KphSsCallTable,
- &SsEntries[i],
- /* Save some space... */
- FIELD_OFFSET(KPHSS_CALL_ENTRY, Arguments) +
- SsEntries[i].NumberOfArguments * sizeof(KPHSS_ARGUMENT_TYPE),
- NULL
- );
- }
- }
-
- ExInitializeFastMutex(&KphSsCallTableMutex);
-}
-
-/* KphSsDataDeinit
- *
- * Frees all memory associated with system service data.
- */
-VOID KphSsDataDeinit()
-{
- PKPHSS_CALL_ENTRY callEntry;
-
- while (callEntry = (PKPHSS_CALL_ENTRY)RtlGetElementGenericTable(&KphSsCallTable, 0))
- RtlDeleteElementGenericTable(&KphSsCallTable, callEntry);
-}
-
-/* KphSsLookupCallEntry
- *
- * Lookups up a system service entry by system service number.
- */
-PKPHSS_CALL_ENTRY KphSsLookupCallEntry(
- __in ULONG Number
- )
-{
- KPHSS_CALL_ENTRY callEntry;
- PKPHSS_CALL_ENTRY foundEntry;
-
- callEntry.Number = &Number;
-
- ExAcquireFastMutex(&KphSsCallTableMutex);
- foundEntry = (PKPHSS_CALL_ENTRY)RtlLookupElementGenericTable(
- &KphSsCallTable,
- &callEntry
- );
- ExReleaseFastMutex(&KphSsCallTableMutex);
-
- return foundEntry;
-}
-
-/* KphpSsCallEntryAllocateRoutine
- *
- * Allocates storage for a system service entry.
- */
-PVOID KphpSsCallEntryAllocateRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in CLONG ByteSize
- )
-{
- return ExAllocatePoolWithTag(
- PagedPool,
- ByteSize,
- TAG_CALL_ENTRY
- );
-}
-
-/* KphpSsCallEntryCompareRoutine
- *
- * Compares two system service entries.
- */
-RTL_GENERIC_COMPARE_RESULTS KphpSsCallEntryCompareRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in PVOID FirstStruct,
- __in PVOID SecondStruct
- )
-{
- PKPHSS_CALL_ENTRY callEntry1, callEntry2;
-
- callEntry1 = (PKPHSS_CALL_ENTRY)FirstStruct;
- callEntry2 = (PKPHSS_CALL_ENTRY)SecondStruct;
-
- if (*(callEntry1->Number) < *(callEntry2->Number))
- return GenericLessThan;
- else if (*(callEntry1->Number) > *(callEntry2->Number))
- return GenericGreaterThan;
- else
- return GenericEqual;
-}
-
-/* KphpSsCallEntryFreeRoutine
- *
- * Frees storage for a system service entry.
- */
-VOID KphpSsCallEntryFreeRoutine(
- __in PRTL_GENERIC_TABLE Table,
- __in PVOID Buffer
- )
-{
- ExFreePoolWithTag(
- Buffer,
- TAG_CALL_ENTRY
- );
-}
diff --git a/2.x/trunk/KProcessHacker/util.c b/2.x/trunk/KProcessHacker/util.c
index 61e3b3ecf..545127095 100644
--- a/2.x/trunk/KProcessHacker/util.c
+++ b/2.x/trunk/KProcessHacker/util.c
@@ -20,7 +20,7 @@
* along with Process Hacker. If not, see .
*/
-#include "include/util.h"
+#include "include/kph.h"
/* KphInitializeStream
*
diff --git a/2.x/trunk/KProcessHacker/version.c b/2.x/trunk/KProcessHacker/version.c
index ef2e9bb2b..d98f681b6 100644
--- a/2.x/trunk/KProcessHacker/version.c
+++ b/2.x/trunk/KProcessHacker/version.c
@@ -21,75 +21,13 @@
*/
#define _VERSION_PRIVATE
-#include "include/version.h"
-#include "include/debug.h"
+#include "include/kph.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KvInit)
#pragma alloc_text(PAGE, KvScanProc)
-#pragma alloc_text(PAGE, KvVerifyPrologue)
#endif
-/*
- * mov edi, edi
- * push ebp
- * mov ebp, esp
- */
-static char StandardPrologue[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec };
-
-/* KiFastCallEntry */
-/*
- * Note that this scan will get the address of
- * mov esi, edx
- * within KiFastCallEntry, not the start of KiFastCallEntry.
- * We will then subtract 7 to get the address of
- * inc dword ptr fs:PbSystemCalls
- * See sysservice.c for more details.
- */
-static char KiFastCallEntry51[] =
-{
- 0x8b, 0xf2, 0x8b, 0x5f, 0x0c, 0x33, 0xc9, 0x8a,
- 0x0c, 0x18, 0x8b, 0x3f, 0x8b, 0x1c, 0x87, 0x2b
-};
-static char KiFastCallEntry52[] =
-{
- 0x8b, 0xf2, 0x8b, 0x5f, 0x0c, 0x33, 0xc9, 0x8a,
- 0x0c, 0x18, 0x8b, 0x3f, 0x8b, 0x1c, 0x87, 0x2b
-}; /* same as 5.1 */
-static char KiFastCallEntry60[] =
-{
- 0x8b, 0xf2, 0x33, 0xc9, 0x8b, 0x57, 0x0c, 0x8b,
- 0x3f, 0x8a, 0x0c, 0x10, 0x8b, 0x14, 0x87, 0x2b
-};
-static char KiFastCallEntry61[] =
-{
- 0x8b, 0xf2, 0x33, 0xc9, 0x8b, 0x57, 0x0c, 0x8b,
- 0x3f, 0x8a, 0x0c, 0x10, 0x8b, 0x14, 0x87, 0x2b
-}; /* same as 6.0 */
-/* Below is the scan to find the start of KiFastCallEntry. */
-/* static char KiFastCallEntry[] =
-{
- 0xb9, 0x23, 0x00, 0x00, 0x00, 0x6a, 0x30, 0x0f,
- 0xa1, 0x8e, 0xd9, 0x8e, 0xc1, 0x64, 0x8b, 0x0d
-}; */
-
-/* PsExitSpecialApc */
-static char PsExitSpecialApc51[] =
-{
- 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x64, 0xa1, 0x24,
- 0x01, 0x00, 0x00, 0x8b, 0x45, 0x08, 0xf6, 0x40
-};
-static char PsExitSpecialApc60[] =
-{
- 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xe4, 0xf8,
- 0x51, 0x8b, 0x45, 0x08, 0xf6, 0x40, 0x28, 0x01
-};
-static char PsExitSpecialApc61[] =
-{
- 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xe4, 0xf8,
- 0x51, 0x8b, 0x45, 0x08, 0xf6, 0x40, 0x28, 0x01
-}; /* same as 6.0 */
-
/* PsTerminateProcess/PspTerminateProcess */
static char PspTerminateProcess51[] =
{
@@ -193,9 +131,6 @@ NTSTATUS KvInit()
ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff;
OffEtClientId = 0x1ec;
- OffEtSpareByteForSs = 0x256; /* Padding, last */
- OffEtStartAddress = 0x224;
- OffEtWin32StartAddress = 0x228;
OffEpJob = 0x134;
OffEpObjectTable = 0xc4;
OffEpProtectedProcessOff = 0;
@@ -204,17 +139,7 @@ NTSTATUS KvInit()
OffOhBody = 0x18;
OffOtName = 0x40;
OffOtiGenericMapping = 0x60 + 0x8;
- OffOtiOpenProcedure = 0x60 + 0x30;
- SsNtContinue = 0x20;
-
- /* KiFastCallEntry isn't hooked properly yet. Disabled for now. */
- /* INIT_SCAN(
- KiFastCallEntryScan,
- KiFastCallEntry51,
- sizeof(KiFastCallEntry51),
- (ULONG_PTR)__ZwClose, SCAN_LENGTH, -6
- ); */
/* We are scanning for PspTerminateProcess which has
the same signature as PsTerminateProcess because
PsTerminateProcess is simply a wrapper on XP.
@@ -264,9 +189,6 @@ NTSTATUS KvInit()
ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff;
OffEtClientId = 0x1e4;
- OffEtSpareByteForSs = 0x24f; /* Padding, last */
- OffEtStartAddress = 0x21c;
- OffEtWin32StartAddress = 0x220;
OffEpJob = 0x120;
OffEpObjectTable = 0xd4;
OffEpProtectedProcessOff = 0;
@@ -275,17 +197,7 @@ NTSTATUS KvInit()
OffOhBody = 0x18;
OffOtName = 0x40;
OffOtiGenericMapping = 0x60 + 0x8;
- OffOtiOpenProcedure = 0x60 + 0x30;
- SsNtContinue = 0x22;
-
- /* Can't find on ntoskrnl *and* ntkrnlpa. Disabled for now. */
- /* INIT_SCAN(
- KiFastCallEntryScan,
- KiFastCallEntry52,
- sizeof(KiFastCallEntry52),
- (ULONG_PTR)__ZwClose, SCAN_LENGTH, -7
- ); */
/* We are scanning for PspTerminateProcess which has
the same signature as PsTerminateProcess because
PsTerminateProcess is simply a wrapper on Server 2003.
@@ -329,9 +241,6 @@ NTSTATUS KvInit()
ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff;
OffEtClientId = 0x20c;
- OffEtSpareByteForSs = 0x26f; /* Padding, second-last */
- OffEtStartAddress = 0x1f8;
- OffEtWin32StartAddress = 0x240;
OffEpJob = 0x10c;
OffEpObjectTable = 0xdc;
OffEpProtectedProcessOff = 0x224;
@@ -339,12 +248,6 @@ NTSTATUS KvInit()
OffEpRundownProtect = 0x98;
OffOhBody = 0x18;
- INIT_SCAN(
- KiFastCallEntryScan,
- KiFastCallEntry60,
- sizeof(KiFastCallEntry60),
- (ULONG_PTR)__ZwClose, SCAN_LENGTH, -7
- );
INIT_SCAN(
PsTerminateProcessScan,
PsTerminateProcess60,
@@ -363,150 +266,18 @@ NTSTATUS KvInit()
{
OffOtName = 0x40;
OffOtiGenericMapping = 0x60 + 0xc;
- OffOtiOpenProcedure = 0x60 + 0x30;
-
- SsNtContinue = 0x36;
}
/* SP1 */
else if (servicePack == 1)
{
OffOtName = 0x8;
OffOtiGenericMapping = 0x28 + 0xc; /* They got rid of the Mutex (an ERESOURCE) */
- OffOtiOpenProcedure = 0x28 + 0x34;
-
- SsNtContinue = 0x37;
}
/* SP2 */
else if (servicePack == 2)
{
OffOtName = 0x8;
OffOtiGenericMapping = 0x28 + 0xc;
- OffOtiOpenProcedure = 0x28 + 0x34;
-
- SsNtAddAtom = 0x8;
- SsNtAlertResumeThread = 0xd;
- SsNtAlertThread = 0xe;
- SsNtAllocateLocallyUniqueId = 0xf;
- SsNtAllocateUserPhysicalPages = 0x10;
- SsNtAllocateUuids = 0x11;
- SsNtAllocateVirtualMemory = 0x12;
- SsNtApphelpCacheControl = 0x28;
- SsNtAreMappedFilesTheSame = 0x29;
- SsNtAssignProcessToJobObject = 0x2a;
- SsNtCallbackReturn = 0x2b;
- SsNtCancelDeviceWakeupRequest = 0x2c;
- SsNtCancelIoFile = 0x2d;
- SsNtCancelTimer = 0x2e;
- SsNtClearEvent = 0x2f;
- SsNtClose = 0x30;
- SsNtContinue = 0x37;
- SsNtCreateDebugObject = 0x38;
- SsNtCreateDirectoryObject = 0x39;
- SsNtCreateEvent = 0x3a;
- SsNtCreateEventPair = 0x3b;
- SsNtCreateFile = 0x3c;
- SsNtCreateIoCompletion = 0x3d;
- SsNtCreateJobObject = 0x3e;
- SsNtCreateJobSet = 0x3f;
- SsNtCreateKey = 0x40;
- SsNtCreateKeyedEvent = 0x168;
- SsNtCreateMailslotFile = 0x42;
- SsNtCreateMutant = 0x43;
- SsNtCreateNamedPipeFile = 0x44;
- SsNtCreatePagingFile = 0x46;
- SsNtCreatePort = 0x47;
- SsNtCreatePrivateNamespace = 0x45;
- SsNtCreateProcess = 0x48;
- SsNtCreateProcessEx = 0x49;
- SsNtCreateProfile = 0x4a;
- SsNtCreateSection = 0x4b;
- SsNtCreateSemaphore = 0x4c;
- SsNtCreateSymbolicLinkObject = 0x4d;
- SsNtCreateThread = 0x4e;
- SsNtCreateTimer = 0x4f;
- SsNtCreateToken = 0x50;
- SsNtCreateUserProcess = 0x17f;
- SsNtCreateWaitablePort = 0x73;
- SsNtDebugActiveProcess = 0x74;
- SsNtDebugContinue = 0x75;
- SsNtDelayExecution = 0x76;
- SsNtDeleteAtom = 0x77;
- SsNtDeleteBootEntry = 0x78;
- SsNtDeleteDriverEntry = 0x79;
- SsNtDeleteFile = 0x7a;
- SsNtDeleteKey = 0x7b;
- SsNtDeletePrivateNamespace = 0x7c;
- SsNtDeleteObjectAuditAlarm = 0x7d;
- SsNtDeleteValueKey = 0x7e;
- SsNtDeviceIoControlFile = 0x7f;
- SsNtDisplayString = 0x80;
- SsNtDuplicateObject = 0x81;
- SsNtDuplicateToken = 0x82;
- SsNtEnumerateBootEntries = 0x83;
- SsNtEnumerateDriverEntries = 0x84;
- SsNtEnumerateKey = 0x85;
- SsNtEnumerateSystemEnvironmentValuesEx = 0x86;
- SsNtEnumerateValueKey = 0x88;
- SsNtExtendSection = 0x89;
- SsNtFilterToken = 0x8a;
- SsNtFindAtom = 0x8b;
- SsNtFlushBuffersFile = 0x8c;
- SsNtFlushInstructionCache = 0x8d;
- SsNtFlushKey = 0x8e;
- SsNtFlushProcessWriteBuffers = 0x8f;
- SsNtFlushVirtualMemory = 0x90;
- SsNtFlushWriteBuffer = 0x91;
- SsNtFreeUserPhysicalPages = 0x92;
- SsNtFreeVirtualMemory = 0x93;
- SsNtFsControlFile = 0x96;
- SsNtGetContextThread = 0x97;
- SsNtGetDevicePowerState = 0x98;
- SsNtGetPlugPlayEvent = 0x9a;
- SsNtGetWriteWatch = 0x9b;
- SsNtImpersonateAnonymousToken = 0x9c;
- SsNtImpersonateClientOfPort = 0x9d;
- SsNtImpersonateThread = 0x9e;
- SsNtInitiatePowerAction = 0xa1;
- SsNtIsProcessInJob = 0xa2;
- SsNtIsSystemResumeAutomatic = 0xa3;
- SsNtListenPort = 0xa4;
- SsNtLoadDriver = 0xa5;
- SsNtLoadKey = 0xa6;
- SsNtLoadKey2 = 0xa7;
- SsNtLockFile = 0xa9;
- SsNtLockVirtualMemory = 0xac;
- SsNtMakePermanentObject = 0xad;
- SsNtMakeTemporaryObject = 0xae;
- SsNtMapUserPhysicalPages = 0xaf;
- SsNtMapUserPhysicalPagesScatter = 0xb0;
- SsNtMapViewOfSection = 0xb1;
- SsNtModifyBootEntry = 0xb2;
- SsNtModifyDriverEntry = 0xb3;
- SsNtNotifyChangeDirectoryFile = 0xb4;
- SsNtNotifyChangeKey = 0xb5;
- SsNtNotifyChangeMultipleKeys = 0xb6;
- SsNtOpenDirectoryObject = 0xb7;
- SsNtOpenEvent = 0xb8;
- SsNtOpenEventPair = 0xb9;
- SsNtOpenFile = 0xba;
- SsNtOpenIoCompletion = 0xbb;
- SsNtOpenJobObject = 0xbc;
- SsNtOpenKey = 0xbd;
- SsNtOpenKeyedEvent = 0x169;
- SsNtOpenMutant = 0xbf;
- SsNtOpenObjectAuditAlarm = 0xc1;
- SsNtOpenProcess = 0xc2;
- SsNtOpenProcessToken = 0xc3;
- SsNtOpenProcessTokenEx = 0xc4;
- SsNtOpenSection = 0xc5;
- SsNtOpenSemaphore = 0xc6;
- SsNtOpenSymbolicLinkObject = 0xc8;
- SsNtOpenThread = 0xc9;
- SsNtOpenThreadToken = 0xca;
- SsNtOpenThreadTokenEx = 0xcb;
- SsNtOpenTimer = 0xcc;
- SsNtReadFile = 0x102;
- SsNtWriteFile = 0x163;
}
else
{
@@ -529,9 +300,6 @@ NTSTATUS KvInit()
ThreadAllAccess = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff;
OffEtClientId = 0x22c;
- OffEtSpareByteForSs = 0x2b4; /* Padding, last */
- OffEtStartAddress = 0x218;
- OffEtWin32StartAddress = 0x260;
OffEpJob = 0x124;
OffEpObjectTable = 0xf4;
OffEpProtectedProcessOff = 0x26c;
@@ -540,16 +308,7 @@ NTSTATUS KvInit()
OffOhBody = 0x18;
OffOtName = 0x8;
OffOtiGenericMapping = 0x28 + 0xc;
- OffOtiOpenProcedure = 0x28 + 0x34;
- SsNtContinue = 0x3c;
-
- INIT_SCAN(
- KiFastCallEntryScan,
- KiFastCallEntry61,
- sizeof(KiFastCallEntry61),
- (ULONG_PTR)__ZwClose, SCAN_LENGTH, -7
- );
INIT_SCAN(
PsTerminateProcessScan,
PsTerminateProcess61,
@@ -599,13 +358,3 @@ PVOID KvScanProc(
return NULL;
}
-
-PVOID KvVerifyPrologue(
- PVOID Address
- )
-{
- if (memcmp(Address, StandardPrologue, 5) == 0)
- return Address;
- else
- return NULL;
-}
diff --git a/2.x/trunk/ProcessHacker/main.c b/2.x/trunk/ProcessHacker/main.c
index ff88960bd..6b93f8845 100644
--- a/2.x/trunk/ProcessHacker/main.c
+++ b/2.x/trunk/ProcessHacker/main.c
@@ -363,7 +363,7 @@ VOID PhInitializeKph()
// Append kprocesshacker.sys to the application directory.
kprocesshackerFileName = PhConcatStrings2(PhApplicationDirectory->Buffer, kprocesshacker);
- KphConnect2(&PhKphHandle, L"KProcessHacker", kprocesshackerFileName->Buffer);
+ KphConnect2(&PhKphHandle, L"KProcessHacker2", kprocesshackerFileName->Buffer);
PhDereferenceObject(kprocesshackerFileName);
#endif
diff --git a/2.x/trunk/ProcessHacker/thrdprv.c b/2.x/trunk/ProcessHacker/thrdprv.c
index cfc2e2716..d9c1420fb 100644
--- a/2.x/trunk/ProcessHacker/thrdprv.c
+++ b/2.x/trunk/ProcessHacker/thrdprv.c
@@ -802,25 +802,13 @@ VOID PhThreadProviderUpdate(
if (threadItem->ThreadHandle)
{
- if (PhKphHandle)
- {
- KphGetThreadStartAddress(
- PhKphHandle,
- threadItem->ThreadHandle,
- &startAddress
- );
- }
-
- if (!startAddress)
- {
- NtQueryInformationThread(
- threadItem->ThreadHandle,
- ThreadQuerySetWin32StartAddress,
- &startAddress,
- sizeof(PVOID),
- NULL
- );
- }
+ NtQueryInformationThread(
+ threadItem->ThreadHandle,
+ ThreadQuerySetWin32StartAddress,
+ &startAddress,
+ sizeof(PVOID),
+ NULL
+ );
}
if (!startAddress)
diff --git a/2.x/trunk/phlib/include/kph.h b/2.x/trunk/phlib/include/kph.h
index 74e869706..5a50fe30a 100644
--- a/2.x/trunk/phlib/include/kph.h
+++ b/2.x/trunk/phlib/include/kph.h
@@ -4,70 +4,62 @@
#include
#define KPH_DEVICE_TYPE (0x9999)
-#define KPH_DEVICE_NAME (L"\\Device\\KProcessHacker")
+#define KPH_DEVICE_NAME (L"\\Device\\KProcessHacker2")
#define KPHF_PSTERMINATEPROCESS 0x1
#define KPHF_PSPTERMINATETHREADBPYPOINTER 0x2
#define KPH_CTL_CODE(x) CTL_CODE(KPH_DEVICE_TYPE, 0x800 + x, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define KPH_CLOSEHANDLE KPH_CTL_CODE(0)
-#define KPH_SSQUERYCLIENTENTRY KPH_CTL_CODE(1)
-#define KPH_RESERVED1 KPH_CTL_CODE(2)
-#define KPH_OPENPROCESS KPH_CTL_CODE(3)
-#define KPH_OPENTHREAD KPH_CTL_CODE(4)
-#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(5)
-#define KPH_GETPROCESSPROTECTED KPH_CTL_CODE(6)
-#define KPH_SETPROCESSPROTECTED KPH_CTL_CODE(7)
-#define KPH_TERMINATEPROCESS KPH_CTL_CODE(8)
-#define KPH_SUSPENDPROCESS KPH_CTL_CODE(9)
-#define KPH_RESUMEPROCESS KPH_CTL_CODE(10)
-#define KPH_READVIRTUALMEMORY KPH_CTL_CODE(11)
-#define KPH_WRITEVIRTUALMEMORY KPH_CTL_CODE(12)
-#define KPH_SETPROCESSTOKEN KPH_CTL_CODE(13)
-#define KPH_GETTHREADSTARTADDRESS KPH_CTL_CODE(14)
-#define KPH_SETHANDLEATTRIBUTES KPH_CTL_CODE(15)
-#define KPH_GETHANDLEOBJECTNAME KPH_CTL_CODE(16)
-#define KPH_OPENPROCESSJOB KPH_CTL_CODE(17)
-#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(18)
-#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(19)
-#define KPH_GETTHREADWIN32THREAD KPH_CTL_CODE(20)
-#define KPH_DUPLICATEOBJECT KPH_CTL_CODE(21)
-#define KPH_ZWQUERYOBJECT KPH_CTL_CODE(22)
-#define KPH_GETPROCESSID KPH_CTL_CODE(23)
-#define KPH_GETTHREADID KPH_CTL_CODE(24)
-#define KPH_TERMINATETHREAD KPH_CTL_CODE(25)
-#define KPH_GETFEATURES KPH_CTL_CODE(26)
-#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(27)
-#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(28)
-#define KPH_PROTECTADD KPH_CTL_CODE(29)
-#define KPH_PROTECTREMOVE KPH_CTL_CODE(30)
-#define KPH_PROTECTQUERY KPH_CTL_CODE(31)
-#define KPH_UNSAFEREADVIRTUALMEMORY KPH_CTL_CODE(32)
-#define KPH_SETEXECUTEOPTIONS KPH_CTL_CODE(33)
-#define KPH_QUERYPROCESSHANDLES KPH_CTL_CODE(34)
-#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(35)
-#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(36)
-#define KPH_DANGEROUSTERMINATETHREAD KPH_CTL_CODE(37)
-#define KPH_OPENTYPE KPH_CTL_CODE(38)
-#define KPH_OPENDRIVER KPH_CTL_CODE(39)
-#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(40)
-#define KPH_OPENDIRECTORYOBJECT KPH_CTL_CODE(41)
-#define KPH_SSREF KPH_CTL_CODE(42)
-#define KPH_SSUNREF KPH_CTL_CODE(43)
-#define KPH_SSCREATECLIENTENTRY KPH_CTL_CODE(44)
-#define KPH_SSCREATERULESETENTRY KPH_CTL_CODE(45)
-#define KPH_SSREMOVERULE KPH_CTL_CODE(46)
-#define KPH_SSADDPROCESSIDRULE KPH_CTL_CODE(47)
-#define KPH_SSADDTHREADIDRULE KPH_CTL_CODE(48)
-#define KPH_SSADDPREVIOUSMODERULE KPH_CTL_CODE(49)
-#define KPH_SSADDNUMBERRULE KPH_CTL_CODE(50)
-#define KPH_SSENABLECLIENTENTRY KPH_CTL_CODE(51)
-#define KPH_OPENNAMEDOBJECT KPH_CTL_CODE(52)
-#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(53)
-#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(54)
-#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(55)
-#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(56)
+/* General */
+#define KPH_GETFEATURES KPH_CTL_CODE(0)
+
+/* Processes */
+#define KPH_OPENPROCESS KPH_CTL_CODE(50)
+#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(51)
+#define KPH_OPENPROCESSJOB KPH_CTL_CODE(52)
+#define KPH_SUSPENDPROCESS KPH_CTL_CODE(53)
+#define KPH_RESUMEPROCESS KPH_CTL_CODE(54)
+#define KPH_TERMINATEPROCESS KPH_CTL_CODE(55)
+#define KPH_READVIRTUALMEMORY KPH_CTL_CODE(56)
+#define KPH_WRITEVIRTUALMEMORY KPH_CTL_CODE(57)
+#define KPH_UNSAFEREADVIRTUALMEMORY KPH_CTL_CODE(58)
+#define KPH_GETPROCESSPROTECTED KPH_CTL_CODE(59)
+#define KPH_SETPROCESSPROTECTED KPH_CTL_CODE(60)
+#define KPH_SETEXECUTEOPTIONS KPH_CTL_CODE(61)
+#define KPH_SETPROCESSTOKEN KPH_CTL_CODE(62)
+#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(63)
+#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(64)
+#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(65)
+#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(66)
+
+/* Threads */
+#define KPH_OPENTHREAD KPH_CTL_CODE(100)
+#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(101)
+#define KPH_TERMINATETHREAD KPH_CTL_CODE(102)
+#define KPH_DANGEROUSTERMINATETHREAD KPH_CTL_CODE(103)
+#define KPH_GETCONTEXTTHREAD KPH_CTL_CODE(104)
+#define KPH_SETCONTEXTTHREAD KPH_CTL_CODE(105)
+#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(106)
+#define KPH_GETTHREADWIN32THREAD KPH_CTL_CODE(107)
+#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(108)
+
+/* Handles */
+#define KPH_QUERYPROCESSHANDLES KPH_CTL_CODE(150)
+#define KPH_GETHANDLEOBJECTNAME KPH_CTL_CODE(151)
+#define KPH_ZWQUERYOBJECT KPH_CTL_CODE(152)
+#define KPH_DUPLICATEOBJECT KPH_CTL_CODE(153)
+#define KPH_SETHANDLEATTRIBUTES KPH_CTL_CODE(154)
+#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(155)
+#define KPH_GETPROCESSID KPH_CTL_CODE(156)
+#define KPH_GETTHREADID KPH_CTL_CODE(157)
+
+/* Objects */
+#define KPH_OPENNAMEDOBJECT KPH_CTL_CODE(200)
+#define KPH_OPENDIRECTORYOBJECT KPH_CTL_CODE(201)
+#define KPH_OPENDRIVER KPH_CTL_CODE(202)
+#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(203)
+#define KPH_OPENTYPE KPH_CTL_CODE(204)
// Process handle information
@@ -85,18 +77,6 @@ typedef struct _PROCESS_HANDLE_INFORMATION
PROCESS_HANDLE Handles[1];
} PROCESS_HANDLE_INFORMATION, *PPROCESS_HANDLE_INFORMATION;
-// System service logging
-
-typedef struct _KPHSS_CLIENT_INFORMATION
-{
- HANDLE ProcessId;
- PVOID BufferBase;
- ULONG BufferSize;
-
- ULONG NumberOfBlocksWritten;
- ULONG NumberOfBlocksDropped;
-} KPHSS_CLIENT_INFORMATION, *PKPHSS_CLIENT_INFORMATION;
-
// Driver information
typedef enum _DRIVER_INFORMATION_CLASS
@@ -146,19 +126,6 @@ NTSTATUS KphGetFeatures(
__out PULONG Features
);
-NTSTATUS KphCloseHandle(
- __in HANDLE KphHandle,
- __in HANDLE Handle
- );
-
-NTSTATUS KphSsQueryClientEntry(
- __in HANDLE KphHandle,
- __in HANDLE ClientEntryHandle,
- __out PKPHSS_CLIENT_INFORMATION ClientInformation,
- __in ULONG ClientInformationLength,
- __out PULONG ReturnLength
- );
-
NTSTATUS KphOpenProcess(
__in HANDLE KphHandle,
__out PHANDLE ProcessHandle,
@@ -166,13 +133,6 @@ NTSTATUS KphOpenProcess(
__in ACCESS_MASK DesiredAccess
);
-NTSTATUS KphOpenThread(
- __in HANDLE KphHandle,
- __out PHANDLE ThreadHandle,
- __in HANDLE ThreadId,
- __in ACCESS_MASK DesiredAccess
- );
-
NTSTATUS KphOpenProcessToken(
__in HANDLE KphHandle,
__out PHANDLE TokenHandle,
@@ -180,22 +140,11 @@ NTSTATUS KphOpenProcessToken(
__in ACCESS_MASK DesiredAccess
);
-NTSTATUS KphGetProcessProtected(
- __in HANDLE KphHandle,
- __in HANDLE ProcessId,
- __out PBOOLEAN IsProtected
- );
-
-NTSTATUS KphSetProcessProtected(
- __in HANDLE KphHandle,
- __in HANDLE ProcessId,
- __in BOOLEAN IsProtected
- );
-
-NTSTATUS KphTerminateProcess(
+NTSTATUS KphOpenProcessJob(
__in HANDLE KphHandle,
+ __out PHANDLE JobHandle,
__in HANDLE ProcessHandle,
- __in NTSTATUS ExitStatus
+ __in ACCESS_MASK DesiredAccess
);
NTSTATUS KphSuspendProcess(
@@ -208,6 +157,12 @@ NTSTATUS KphResumeProcess(
__in HANDLE ProcessHandle
);
+NTSTATUS KphTerminateProcess(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in NTSTATUS ExitStatus
+ );
+
NTSTATUS KphReadVirtualMemory(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
@@ -226,134 +181,6 @@ NTSTATUS KphWriteVirtualMemory(
__out_opt PULONG ReturnLength
);
-NTSTATUS KphSetProcessToken(
- __in HANDLE KphHandle,
- __in HANDLE SourceProcessId,
- __in HANDLE TargetProcessId
- );
-
-NTSTATUS KphGetThreadStartAddress(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __out PPVOID StartAddress
- );
-
-NTSTATUS KphSetHandleAttributes(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __in ULONG Flags
- );
-
-NTSTATUS KphGetHandleObjectName(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out_bcount_opt(BufferLength) PUNICODE_STRING Buffer,
- __in ULONG BufferLength,
- __out_opt PULONG ReturnLength
- );
-
-NTSTATUS KphOpenProcessJob(
- __in HANDLE KphHandle,
- __out PHANDLE JobHandle,
- __in HANDLE ProcessHandle,
- __in ACCESS_MASK DesiredAccess
- );
-
-NTSTATUS KphGetContextThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __inout PCONTEXT ThreadContext
- );
-
-NTSTATUS KphSetContextThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in PCONTEXT ThreadContext
- );
-
-NTSTATUS KphGetThreadWin32Thread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __out PPVOID Win32Thread
- );
-
-NTSTATUS KphDuplicateObject(
- __in HANDLE KphHandle,
- __in HANDLE SourceProcessHandle,
- __in HANDLE SourceHandle,
- __in_opt HANDLE TargetProcessHandle,
- __out_opt PHANDLE TargetHandle,
- __in ACCESS_MASK DesiredAccess,
- __in ULONG HandleAttributes,
- __in ULONG Options
- );
-
-NTSTATUS KphZwQueryObject(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __in OBJECT_INFORMATION_CLASS ObjectInformationClass,
- __in_bcount_opt(BufferLength) PVOID Buffer,
- __in ULONG BufferLength,
- __out_opt PULONG ReturnLength
- );
-
-NTSTATUS KphGetProcessId(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out PHANDLE ProcessId
- );
-
-NTSTATUS KphGetThreadId(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out PHANDLE ThreadId,
- __out_opt PHANDLE ProcessId
- );
-
-NTSTATUS KphTerminateThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in NTSTATUS ExitStatus
- );
-
-NTSTATUS KphSetHandleGrantedAccess(
- __in HANDLE KphHandle,
- __in HANDLE Handle,
- __in ACCESS_MASK GrantedAccess
- );
-
-NTSTATUS KphAssignImpersonationToken(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in HANDLE TokenHandle
- );
-
-NTSTATUS KphProtectAdd(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in BOOLEAN AllowKernelMode,
- __in ACCESS_MASK ProcessAllowMask,
- __in ACCESS_MASK ThreadAllowMask
- );
-
-NTSTATUS KphProtectRemove(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle
- );
-
-NTSTATUS KphProtectQuery(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __out PBOOLEAN AllowKernelMode,
- __out PACCESS_MASK ProcessAllowMask,
- __out PACCESS_MASK ThreadAllowMask
- );
-
NTSTATUS KphUnsafeReadVirtualMemory(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
@@ -363,76 +190,28 @@ NTSTATUS KphUnsafeReadVirtualMemory(
__out_opt PULONG ReturnLength
);
+NTSTATUS KphGetProcessProtected(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessId,
+ __out PBOOLEAN IsProtected
+ );
+
+NTSTATUS KphSetProcessProtected(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessId,
+ __in BOOLEAN IsProtected
+ );
+
NTSTATUS KphSetExecuteOptions(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
__in ULONG ExecuteOptions
);
-NTSTATUS KphQueryProcessHandles(
+NTSTATUS KphSetProcessToken(
__in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __out_bcount_opt(BufferLength) PVOID Buffer,
- __in_opt ULONG BufferLength,
- __out_opt PULONG ReturnLength
- );
-
-NTSTATUS KphOpenThreadProcess(
- __in HANDLE KphHandle,
- __out PHANDLE ProcessHandle,
- __in HANDLE ThreadHandle,
- __in ACCESS_MASK DesiredAccess
- );
-
-NTSTATUS KphCaptureStackBackTraceThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in ULONG FramesToSkip,
- __in ULONG FramesToCapture,
- __out_ecount(FramesToCapture) PPVOID BackTrace,
- __out_opt PULONG CapturedFrames,
- __out_opt PULONG BackTraceHash
- );
-
-NTSTATUS KphDangerousTerminateThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in NTSTATUS ExitStatus
- );
-
-NTSTATUS KphOpenType(
- __in HANDLE KphHandle,
- __out PHANDLE TypeHandle,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- );
-
-NTSTATUS KphOpenDriver(
- __in HANDLE KphHandle,
- __out PHANDLE DriverHandle,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- );
-
-NTSTATUS KphQueryInformationDriver(
- __in HANDLE KphHandle,
- __in HANDLE DriverHandle,
- __in DRIVER_INFORMATION_CLASS DriverInformationClass,
- __out_bcount_opt(DriverInformationLength) PVOID DriverInformation,
- __in ULONG DriverInformationLength,
- __out_opt PULONG ReturnLength
- );
-
-NTSTATUS KphOpenDirectoryObject(
- __in HANDLE KphHandle,
- __out PHANDLE DirectoryHandle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- );
-
-NTSTATUS KphOpenNamedObject(
- __in HANDLE KphHandle,
- __out PHANDLE Handle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes
+ __in HANDLE SourceProcessId,
+ __in HANDLE TargetProcessId
);
NTSTATUS KphQueryInformationProcess(
@@ -469,4 +248,165 @@ NTSTATUS KphSetInformationThread(
__in ULONG ThreadInformationLength
);
+NTSTATUS KphOpenThread(
+ __in HANDLE KphHandle,
+ __out PHANDLE ThreadHandle,
+ __in HANDLE ThreadId,
+ __in ACCESS_MASK DesiredAccess
+ );
+
+NTSTATUS KphOpenThreadProcess(
+ __in HANDLE KphHandle,
+ __out PHANDLE ProcessHandle,
+ __in HANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess
+ );
+
+NTSTATUS KphTerminateThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+ );
+
+NTSTATUS KphDangerousTerminateThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+ );
+
+NTSTATUS KphGetContextThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __inout PCONTEXT ThreadContext
+ );
+
+NTSTATUS KphSetContextThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in PCONTEXT ThreadContext
+ );
+
+NTSTATUS KphCaptureStackBackTraceThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in ULONG FramesToSkip,
+ __in ULONG FramesToCapture,
+ __out_ecount(FramesToCapture) PPVOID BackTrace,
+ __out_opt PULONG CapturedFrames,
+ __out_opt PULONG BackTraceHash
+ );
+
+NTSTATUS KphGetThreadWin32Thread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __out PPVOID Win32Thread
+ );
+
+NTSTATUS KphAssignImpersonationToken(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in HANDLE TokenHandle
+ );
+
+NTSTATUS KphQueryProcessHandles(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __out_bcount_opt(BufferLength) PVOID Buffer,
+ __in_opt ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ );
+
+NTSTATUS KphGetHandleObjectName(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out_bcount_opt(BufferLength) PUNICODE_STRING Buffer,
+ __in ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ );
+
+NTSTATUS KphZwQueryObject(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __in OBJECT_INFORMATION_CLASS ObjectInformationClass,
+ __in_bcount_opt(BufferLength) PVOID Buffer,
+ __in ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ );
+
+NTSTATUS KphDuplicateObject(
+ __in HANDLE KphHandle,
+ __in HANDLE SourceProcessHandle,
+ __in HANDLE SourceHandle,
+ __in_opt HANDLE TargetProcessHandle,
+ __out_opt PHANDLE TargetHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in ULONG HandleAttributes,
+ __in ULONG Options
+ );
+
+NTSTATUS KphSetHandleAttributes(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __in ULONG Flags
+ );
+
+NTSTATUS KphSetHandleGrantedAccess(
+ __in HANDLE KphHandle,
+ __in HANDLE Handle,
+ __in ACCESS_MASK GrantedAccess
+ );
+
+NTSTATUS KphGetProcessId(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out PHANDLE ProcessId
+ );
+
+NTSTATUS KphGetThreadId(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out PHANDLE ThreadId,
+ __out_opt PHANDLE ProcessId
+ );
+
+NTSTATUS KphOpenNamedObject(
+ __in HANDLE KphHandle,
+ __out PHANDLE Handle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
+NTSTATUS KphOpenDirectoryObject(
+ __in HANDLE KphHandle,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
+NTSTATUS KphOpenDriver(
+ __in HANDLE KphHandle,
+ __out PHANDLE DriverHandle,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
+NTSTATUS KphQueryInformationDriver(
+ __in HANDLE KphHandle,
+ __in HANDLE DriverHandle,
+ __in DRIVER_INFORMATION_CLASS DriverInformationClass,
+ __out_bcount_opt(DriverInformationLength) PVOID DriverInformation,
+ __in ULONG DriverInformationLength,
+ __out_opt PULONG ReturnLength
+ );
+
+NTSTATUS KphOpenType(
+ __in HANDLE KphHandle,
+ __out PHANDLE TypeHandle,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
#endif
diff --git a/2.x/trunk/phlib/kph.c b/2.x/trunk/phlib/kph.c
index 995280610..2997f5121 100644
--- a/2.x/trunk/phlib/kph.c
+++ b/2.x/trunk/phlib/kph.c
@@ -109,7 +109,7 @@ NTSTATUS KphConnect2(
BOOLEAN created = FALSE;
if (!DeviceName)
- DeviceName = L"KProcessHacker";
+ DeviceName = L"KProcessHacker2";
_snwprintf(fullDeviceName, MAX_PATH, L"\\Device\\%s", DeviceName);
@@ -271,61 +271,6 @@ NTSTATUS KphGetFeatures(
return status;
}
-NTSTATUS KphCloseHandle(
- __in HANDLE KphHandle,
- __in HANDLE Handle
- )
-{
- struct
- {
- HANDLE Handle;
- } args;
-
- args.Handle = Handle;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_CLOSEHANDLE,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphSsQueryClientEntry(
- __in HANDLE KphHandle,
- __in HANDLE ClientEntryHandle,
- __out PKPHSS_CLIENT_INFORMATION ClientInformation,
- __in ULONG ClientInformationLength,
- __out PULONG ReturnLength
- )
-{
- struct
- {
- HANDLE ClientEntryHandle;
- PKPHSS_CLIENT_INFORMATION ClientInformation;
- ULONG ClientInformationLength;
- PULONG ReturnLength;
- } args;
-
- args.ClientEntryHandle = ClientEntryHandle;
- args.ClientInformation = ClientInformation;
- args.ClientInformationLength = ClientInformationLength;
- args.ReturnLength = ReturnLength;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SSQUERYCLIENTENTRY,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
NTSTATUS KphOpenProcess(
__in HANDLE KphHandle,
__out PHANDLE ProcessHandle,
@@ -365,45 +310,6 @@ NTSTATUS KphOpenProcess(
return status;
}
-NTSTATUS KphOpenThread(
- __in HANDLE KphHandle,
- __out PHANDLE ThreadHandle,
- __in HANDLE ThreadId,
- __in ACCESS_MASK DesiredAccess
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ThreadId;
- ACCESS_MASK DesiredAccess;
- } args;
- struct
- {
- HANDLE ThreadHandle;
- } ret;
-
- args.ThreadId = ThreadId;
- args.DesiredAccess = DesiredAccess;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_OPENTHREAD,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *ThreadHandle = ret.ThreadHandle;
- }
-
- return status;
-}
-
NTSTATUS KphOpenProcessToken(
__in HANDLE KphHandle,
__out PHANDLE TokenHandle,
@@ -443,27 +349,30 @@ NTSTATUS KphOpenProcessToken(
return status;
}
-NTSTATUS KphGetProcessProtected(
+NTSTATUS KphOpenProcessJob(
__in HANDLE KphHandle,
- __in HANDLE ProcessId,
- __out PBOOLEAN IsProtected
+ __out PHANDLE JobHandle,
+ __in HANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess
)
{
NTSTATUS status;
struct
{
- HANDLE ProcessId;
+ HANDLE ProcessHandle;
+ ACCESS_MASK DesiredAccess;
} args;
struct
{
- BOOLEAN IsProtected;
+ HANDLE JobHandle;
} ret;
- args.ProcessId = ProcessId;
+ args.ProcessHandle = ProcessHandle;
+ args.DesiredAccess = DesiredAccess;
status = KphpDeviceIoControl(
KphHandle,
- KPH_GETPROCESSPROTECTED,
+ KPH_OPENPROCESSJOB,
&args,
sizeof(args),
&ret,
@@ -473,69 +382,7 @@ NTSTATUS KphGetProcessProtected(
if (NT_SUCCESS(status))
{
- *IsProtected = ret.IsProtected;
- }
-
- return status;
-}
-
-NTSTATUS KphSetProcessProtected(
- __in HANDLE KphHandle,
- __in HANDLE ProcessId,
- __in BOOLEAN IsProtected
- )
-{
- struct
- {
- HANDLE ProcessId;
- BOOLEAN IsProtected;
- } args;
-
- args.ProcessId = ProcessId;
- args.IsProtected = IsProtected;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SETPROCESSPROTECTED,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphTerminateProcess(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in NTSTATUS ExitStatus
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- struct
- {
- HANDLE ProcessHandle;
- NTSTATUS ExitStatus;
- } args;
-
- args.ProcessHandle = ProcessHandle;
- args.ExitStatus = ExitStatus;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_TERMINATEPROCESS,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-
- /* Check if we were trying to terminate the current
- * process and do it now. */
- if (status == STATUS_CANT_TERMINATE_SELF)
- {
- RtlExitUserProcess(ExitStatus);
+ *JobHandle = ret.JobHandle;
}
return status;
@@ -587,6 +434,42 @@ NTSTATUS KphResumeProcess(
);
}
+NTSTATUS KphTerminateProcess(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in NTSTATUS ExitStatus
+ )
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ struct
+ {
+ HANDLE ProcessHandle;
+ NTSTATUS ExitStatus;
+ } args;
+
+ args.ProcessHandle = ProcessHandle;
+ args.ExitStatus = ExitStatus;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_TERMINATEPROCESS,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+
+ /* Check if we were trying to terminate the current
+ * process and do it now. */
+ if (status == STATUS_CANT_TERMINATE_SELF)
+ {
+ RtlExitUserProcess(ExitStatus);
+ }
+
+ return status;
+}
+
NTSTATUS KphReadVirtualMemory(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
@@ -657,690 +540,6 @@ NTSTATUS KphWriteVirtualMemory(
);
}
-NTSTATUS KphSetProcessToken(
- __in HANDLE KphHandle,
- __in HANDLE SourceProcessId,
- __in HANDLE TargetProcessId
- )
-{
- struct
- {
- HANDLE SourceProcessId;
- HANDLE TargetProcessId;
- } args;
-
- args.SourceProcessId = SourceProcessId;
- args.TargetProcessId = TargetProcessId;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SETPROCESSTOKEN,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphGetThreadStartAddress(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __out PPVOID StartAddress
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ThreadHandle;
- } args;
- struct
- {
- PVOID StartAddress;
- } ret;
-
- args.ThreadHandle = ThreadHandle;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETTHREADSTARTADDRESS,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *StartAddress = ret.StartAddress;
- }
-
- return status;
-}
-
-NTSTATUS KphSetHandleAttributes(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __in ULONG Flags
- )
-{
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- ULONG Flags;
- } args;
-
- args.ProcessHandle = ProcessHandle;
- args.Handle = Handle;
- args.Flags = Flags;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SETHANDLEATTRIBUTES,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphGetHandleObjectName(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out_bcount_opt(BufferLength) PUNICODE_STRING Buffer,
- __in ULONG BufferLength,
- __out_opt PULONG ReturnLength
- )
-{
- NTSTATUS status;
- UNICODE_STRING buffer;
- ULONG returnLength;
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } args;
-
- args.ProcessHandle = ProcessHandle;
- args.Handle = Handle;
-
- if (Buffer && BufferLength >= sizeof(UNICODE_STRING))
- {
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETHANDLEOBJECTNAME,
- &args,
- sizeof(args),
- Buffer,
- BufferLength,
- &returnLength
- );
-
- Buffer->Buffer = (PWSTR)PTR_ADD_OFFSET(Buffer, sizeof(UNICODE_STRING));
-
- if (ReturnLength)
- {
- if (status == STATUS_BUFFER_TOO_SMALL)
- *ReturnLength = Buffer->Length;
- else
- *ReturnLength = returnLength;
- }
- }
- else
- {
- // User doesn't give us a buffer, or it was too small.
- // Use our internal buffer.
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETHANDLEOBJECTNAME,
- &args,
- sizeof(args),
- &buffer,
- sizeof(UNICODE_STRING),
- &returnLength
- );
-
- if (ReturnLength)
- {
- if (status == STATUS_BUFFER_TOO_SMALL)
- *ReturnLength = buffer.Length;
- else
- *ReturnLength = returnLength;
- }
- }
-
- return status;
-}
-
-NTSTATUS KphOpenProcessJob(
- __in HANDLE KphHandle,
- __out PHANDLE JobHandle,
- __in HANDLE ProcessHandle,
- __in ACCESS_MASK DesiredAccess
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ProcessHandle;
- ACCESS_MASK DesiredAccess;
- } args;
- struct
- {
- HANDLE JobHandle;
- } ret;
-
- args.ProcessHandle = ProcessHandle;
- args.DesiredAccess = DesiredAccess;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_OPENPROCESSJOB,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *JobHandle = ret.JobHandle;
- }
-
- return status;
-}
-
-NTSTATUS KphGetContextThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __inout PCONTEXT ThreadContext
- )
-{
- struct
- {
- HANDLE ThreadHandle;
- PCONTEXT ThreadContext;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.ThreadContext = ThreadContext;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_GETCONTEXTTHREAD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphSetContextThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in PCONTEXT ThreadContext
- )
-{
- struct
- {
- HANDLE ThreadHandle;
- PCONTEXT ThreadContext;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.ThreadContext = ThreadContext;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SETCONTEXTTHREAD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphGetThreadWin32Thread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __out PPVOID Win32Thread
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ThreadHandle;
- } args;
- struct
- {
- PVOID Win32Thread;
- } ret;
-
- args.ThreadHandle = ThreadHandle;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETTHREADWIN32THREAD,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *Win32Thread = ret.Win32Thread;
- }
-
- return status;
-}
-
-NTSTATUS KphDuplicateObject(
- __in HANDLE KphHandle,
- __in HANDLE SourceProcessHandle,
- __in HANDLE SourceHandle,
- __in_opt HANDLE TargetProcessHandle,
- __out_opt PHANDLE TargetHandle,
- __in ACCESS_MASK DesiredAccess,
- __in ULONG HandleAttributes,
- __in ULONG Options
- )
-{
- struct
- {
- HANDLE SourceProcessHandle;
- HANDLE SourceHandle;
- HANDLE TargetProcessHandle;
- PHANDLE TargetHandle;
- ACCESS_MASK DesiredAccess;
- ULONG HandleAttributes;
- ULONG Options;
- } args;
-
- args.SourceProcessHandle = SourceProcessHandle;
- args.SourceHandle = SourceHandle;
- args.TargetProcessHandle = TargetProcessHandle;
- args.TargetHandle = TargetHandle;
- args.DesiredAccess = DesiredAccess;
- args.HandleAttributes = HandleAttributes;
- args.Options = Options;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_DUPLICATEOBJECT,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphZwQueryObject(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __in OBJECT_INFORMATION_CLASS ObjectInformationClass,
- __in_bcount_opt(BufferLength) PVOID Buffer,
- __in ULONG BufferLength,
- __out_opt PULONG ReturnLength
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- OBJECT_INFORMATION_CLASS ObjectInformationClass;
- } args;
- PKPH_ZWQUERYOBJECT_BUFFER ret;
- ULONG retLength;
-
- // Make sure we understand the object information class
- // because we will be fixing the buffer later.
- if (
- ObjectInformationClass != ObjectBasicInformation &&
- ObjectInformationClass != ObjectNameInformation &&
- ObjectInformationClass != ObjectTypeInformation
- )
- return STATUS_INVALID_INFO_CLASS;
-
- args.ProcessHandle = ProcessHandle;
- args.Handle = Handle;
- args.ObjectInformationClass = ObjectInformationClass;
-
- retLength = FIELD_OFFSET(KPH_ZWQUERYOBJECT_BUFFER, Buffer) + BufferLength;
- ret = PhAllocate(retLength);
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_ZWQUERYOBJECT,
- &args,
- sizeof(args),
- ret,
- retLength,
- NULL
- );
-
- // Make sure the actual I/O control request succeeded.
- if (NT_SUCCESS(status))
- {
- // Check if ZwQueryObject succeeded.
- status = ret->Status;
-
- if (NT_SUCCESS(status))
- {
- if (Buffer)
- {
- // Copy the buffer contents to the user buffer.
- memcpy(Buffer, ret->Buffer, ret->ReturnLength);
-
- // Rebase pointers in the buffer.
- if (ObjectInformationClass == ObjectNameInformation)
- {
- POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)Buffer;
-
- nameInfo->Name.Buffer = (PWSTR)REBASE_ADDRESS(
- nameInfo->Name.Buffer,
- ret->BufferBase,
- Buffer
- );
- }
- else if (ObjectInformationClass == ObjectTypeInformation)
- {
- POBJECT_TYPE_INFORMATION typeInfo = (POBJECT_TYPE_INFORMATION)Buffer;
-
- typeInfo->TypeName.Buffer = (PWSTR)REBASE_ADDRESS(
- typeInfo->TypeName.Buffer,
- ret->BufferBase,
- Buffer
- );
- }
- }
- }
-
- if (ReturnLength)
- *ReturnLength = ret->ReturnLength;
- }
-
- PhFree(ret);
-
- return status;
-}
-
-NTSTATUS KphGetProcessId(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out PHANDLE ProcessId
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } args;
- struct
- {
- HANDLE ProcessId;
- } ret;
-
- args.ProcessHandle = ProcessHandle;
- args.Handle = Handle;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETPROCESSID,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *ProcessId = ret.ProcessId;
- }
-
- return status;
-}
-
-NTSTATUS KphGetThreadId(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in HANDLE Handle,
- __out PHANDLE ThreadId,
- __out_opt PHANDLE ProcessId
- )
-{
- NTSTATUS status;
- struct
- {
- HANDLE ProcessHandle;
- HANDLE Handle;
- } args;
- struct
- {
- HANDLE ThreadId;
- HANDLE ProcessId;
- } ret;
-
- args.ProcessHandle = ProcessHandle;
- args.Handle = Handle;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_GETTHREADID,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *ThreadId = ret.ThreadId;
-
- if (ProcessId)
- *ProcessId = ret.ProcessId;
- }
-
- return status;
-}
-
-NTSTATUS KphTerminateThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in NTSTATUS ExitStatus
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- struct
- {
- HANDLE ThreadHandle;
- NTSTATUS ExitStatus;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.ExitStatus = ExitStatus;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_TERMINATETHREAD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-
- if (status == STATUS_CANT_TERMINATE_SELF)
- {
- RtlExitUserThread(ExitStatus);
- }
-
- return status;
-}
-
-NTSTATUS KphSetHandleGrantedAccess(
- __in HANDLE KphHandle,
- __in HANDLE Handle,
- __in ACCESS_MASK GrantedAccess
- )
-{
- struct
- {
- HANDLE Handle;
- ACCESS_MASK GrantedAccess;
- } args;
-
- args.Handle = Handle;
- args.GrantedAccess = GrantedAccess;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_SETHANDLEGRANTEDACCESS,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphAssignImpersonationToken(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in HANDLE TokenHandle
- )
-{
- struct
- {
- HANDLE ThreadHandle;
- HANDLE TokenHandle;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.TokenHandle = TokenHandle;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_ASSIGNIMPERSONATIONTOKEN,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphProtectAdd(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __in BOOLEAN AllowKernelMode,
- __in ACCESS_MASK ProcessAllowMask,
- __in ACCESS_MASK ThreadAllowMask
- )
-{
- struct
- {
- HANDLE ProcessHandle;
- LOGICAL AllowKernelMode;
- ACCESS_MASK ProcessAllowMask;
- ACCESS_MASK ThreadAllowMask;
- } args;
-
- args.ProcessHandle = ProcessHandle;
- args.AllowKernelMode = AllowKernelMode;
- args.ProcessAllowMask = ProcessAllowMask;
- args.ThreadAllowMask = ThreadAllowMask;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_PROTECTADD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphProtectRemove(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle
- )
-{
- struct
- {
- HANDLE ProcessHandle;
- } args;
-
- args.ProcessHandle = ProcessHandle;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_PROTECTREMOVE,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphProtectQuery(
- __in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __out PBOOLEAN AllowKernelMode,
- __out PACCESS_MASK ProcessAllowMask,
- __out PACCESS_MASK ThreadAllowMask
- )
-{
- NTSTATUS status = STATUS_SUCCESS;
- struct
- {
- HANDLE ProcessHandle;
- PLOGICAL AllowKernelMode;
- PACCESS_MASK ProcessAllowMask;
- PACCESS_MASK ThreadAllowMask;
- } args;
- LOGICAL allowKernelMode;
-
- args.ProcessHandle = ProcessHandle;
- args.AllowKernelMode = &allowKernelMode;
- args.ProcessAllowMask = ProcessAllowMask;
- args.ThreadAllowMask = ThreadAllowMask;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_PROTECTQUERY,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *AllowKernelMode = (BOOLEAN)allowKernelMode;
- }
-
- return status;
-}
-
NTSTATUS KphUnsafeReadVirtualMemory(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
@@ -1376,6 +575,68 @@ NTSTATUS KphUnsafeReadVirtualMemory(
);
}
+NTSTATUS KphGetProcessProtected(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessId,
+ __out PBOOLEAN IsProtected
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ProcessId;
+ } args;
+ struct
+ {
+ BOOLEAN IsProtected;
+ } ret;
+
+ args.ProcessId = ProcessId;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETPROCESSPROTECTED,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *IsProtected = ret.IsProtected;
+ }
+
+ return status;
+}
+
+NTSTATUS KphSetProcessProtected(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessId,
+ __in BOOLEAN IsProtected
+ )
+{
+ struct
+ {
+ HANDLE ProcessId;
+ BOOLEAN IsProtected;
+ } args;
+
+ args.ProcessId = ProcessId;
+ args.IsProtected = IsProtected;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_SETPROCESSPROTECTED,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
NTSTATUS KphSetExecuteOptions(
__in HANDLE KphHandle,
__in HANDLE ProcessHandle,
@@ -1402,279 +663,24 @@ NTSTATUS KphSetExecuteOptions(
);
}
-NTSTATUS KphQueryProcessHandles(
+NTSTATUS KphSetProcessToken(
__in HANDLE KphHandle,
- __in HANDLE ProcessHandle,
- __out_bcount_opt(BufferLength) PVOID Buffer,
- __in_opt ULONG BufferLength,
- __out_opt PULONG ReturnLength
+ __in HANDLE SourceProcessId,
+ __in HANDLE TargetProcessId
)
{
struct
{
- HANDLE ProcessHandle;
- PVOID Buffer;
- ULONG BufferLength;
- PULONG ReturnLength;
+ HANDLE SourceProcessId;
+ HANDLE TargetProcessId;
} args;
- args.ProcessHandle = ProcessHandle;
- args.Buffer = Buffer;
- args.BufferLength = BufferLength;
- args.ReturnLength = ReturnLength;
+ args.SourceProcessId = SourceProcessId;
+ args.TargetProcessId = TargetProcessId;
return KphpDeviceIoControl(
KphHandle,
- KPH_QUERYPROCESSHANDLES,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphOpenThreadProcess(
- __in HANDLE KphHandle,
- __out PHANDLE ProcessHandle,
- __in HANDLE ThreadHandle,
- __in ACCESS_MASK DesiredAccess
- )
-{
- NTSTATUS status;
-
- struct
- {
- HANDLE ThreadHandle;
- ACCESS_MASK DesiredAccess;
- } args;
- struct
- {
- HANDLE ProcessHandle;
- } ret;
-
- args.ThreadHandle = ThreadHandle;
- args.DesiredAccess = DesiredAccess;
-
- status = KphpDeviceIoControl(
- KphHandle,
- KPH_OPENTHREADPROCESS,
- &args,
- sizeof(args),
- &ret,
- sizeof(ret),
- NULL
- );
-
- if (NT_SUCCESS(status))
- {
- *ProcessHandle = ret.ProcessHandle;
- }
-
- return status;
-}
-
-NTSTATUS KphCaptureStackBackTraceThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in ULONG FramesToSkip,
- __in ULONG FramesToCapture,
- __out_ecount(FramesToCapture) PPVOID BackTrace,
- __out_opt PULONG CapturedFrames,
- __out_opt PULONG BackTraceHash
- )
-{
- struct
- {
- HANDLE ThreadHandle;
- ULONG FramesToSkip;
- ULONG FramesToCapture;
- PPVOID BackTrace;
- PULONG CapturedFrames;
- PULONG BackTraceHash;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.FramesToSkip = FramesToSkip;
- args.FramesToCapture = FramesToCapture;
- args.BackTrace = BackTrace;
- args.CapturedFrames = CapturedFrames;
- args.BackTraceHash = BackTraceHash;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_CAPTURESTACKBACKTRACETHREAD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphDangerousTerminateThread(
- __in HANDLE KphHandle,
- __in HANDLE ThreadHandle,
- __in NTSTATUS ExitStatus
- )
-{
- struct
- {
- HANDLE ThreadHandle;
- NTSTATUS ExitStatus;
- } args;
-
- args.ThreadHandle = ThreadHandle;
- args.ExitStatus = ExitStatus;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_DANGEROUSTERMINATETHREAD,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphOpenType(
- __in HANDLE KphHandle,
- __out PHANDLE TypeHandle,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- )
-{
- struct
- {
- PHANDLE TypeHandle;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } args;
-
- args.TypeHandle = TypeHandle;
- args.ObjectAttributes = ObjectAttributes;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_OPENTYPE,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphOpenDriver(
- __in HANDLE KphHandle,
- __out PHANDLE DriverHandle,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- )
-{
- struct
- {
- PHANDLE DriverHandle;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } args;
-
- args.DriverHandle = DriverHandle;
- args.ObjectAttributes = ObjectAttributes;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_OPENDRIVER,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphQueryInformationDriver(
- __in HANDLE KphHandle,
- __in HANDLE DriverHandle,
- __in DRIVER_INFORMATION_CLASS DriverInformationClass,
- __out_bcount_opt(DriverInformationLength) PVOID DriverInformation,
- __in ULONG DriverInformationLength,
- __out_opt PULONG ReturnLength
- )
-{
- struct
- {
- HANDLE DriverHandle;
- DRIVER_INFORMATION_CLASS DriverInformationClass;
- PVOID DriverInformation;
- ULONG DriverInformationLength;
- PULONG ReturnLength;
- } args;
-
- args.DriverHandle = DriverHandle;
- args.DriverInformationClass = DriverInformationClass;
- args.DriverInformation = DriverInformation;
- args.DriverInformationLength = DriverInformationLength;
- args.ReturnLength = ReturnLength;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_QUERYINFORMATIONDRIVER,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphOpenDirectoryObject(
- __in HANDLE KphHandle,
- __out PHANDLE DirectoryHandle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- )
-{
- struct
- {
- PHANDLE DirectoryHandle;
- ACCESS_MASK DesiredAccess;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } args;
-
- args.DirectoryHandle = DirectoryHandle;
- args.DesiredAccess = DesiredAccess;
- args.ObjectAttributes = ObjectAttributes;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_OPENDIRECTORYOBJECT,
- &args,
- sizeof(args),
- NULL,
- 0,
- NULL
- );
-}
-
-NTSTATUS KphOpenNamedObject(
- __in HANDLE KphHandle,
- __out PHANDLE Handle,
- __in ACCESS_MASK DesiredAccess,
- __in POBJECT_ATTRIBUTES ObjectAttributes
- )
-{
- struct
- {
- PHANDLE Handle;
- ACCESS_MASK DesiredAccess;
- POBJECT_ATTRIBUTES ObjectAttributes;
- } args;
-
- args.Handle = Handle;
- args.DesiredAccess = DesiredAccess;
- args.ObjectAttributes = ObjectAttributes;
-
- return KphpDeviceIoControl(
- KphHandle,
- KPH_OPENNAMEDOBJECT,
+ KPH_SETPROCESSTOKEN,
&args,
sizeof(args),
NULL,
@@ -1816,3 +822,820 @@ NTSTATUS KphSetInformationThread(
NULL
);
}
+
+NTSTATUS KphOpenThread(
+ __in HANDLE KphHandle,
+ __out PHANDLE ThreadHandle,
+ __in HANDLE ThreadId,
+ __in ACCESS_MASK DesiredAccess
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ThreadId;
+ ACCESS_MASK DesiredAccess;
+ } args;
+ struct
+ {
+ HANDLE ThreadHandle;
+ } ret;
+
+ args.ThreadId = ThreadId;
+ args.DesiredAccess = DesiredAccess;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENTHREAD,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *ThreadHandle = ret.ThreadHandle;
+ }
+
+ return status;
+}
+
+NTSTATUS KphOpenThreadProcess(
+ __in HANDLE KphHandle,
+ __out PHANDLE ProcessHandle,
+ __in HANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess
+ )
+{
+ NTSTATUS status;
+
+ struct
+ {
+ HANDLE ThreadHandle;
+ ACCESS_MASK DesiredAccess;
+ } args;
+ struct
+ {
+ HANDLE ProcessHandle;
+ } ret;
+
+ args.ThreadHandle = ThreadHandle;
+ args.DesiredAccess = DesiredAccess;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENTHREADPROCESS,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *ProcessHandle = ret.ProcessHandle;
+ }
+
+ return status;
+}
+
+NTSTATUS KphTerminateThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+ )
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ struct
+ {
+ HANDLE ThreadHandle;
+ NTSTATUS ExitStatus;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.ExitStatus = ExitStatus;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_TERMINATETHREAD,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+
+ if (status == STATUS_CANT_TERMINATE_SELF)
+ {
+ RtlExitUserThread(ExitStatus);
+ }
+
+ return status;
+}
+
+NTSTATUS KphDangerousTerminateThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+ )
+{
+ struct
+ {
+ HANDLE ThreadHandle;
+ NTSTATUS ExitStatus;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.ExitStatus = ExitStatus;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_DANGEROUSTERMINATETHREAD,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphGetContextThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __inout PCONTEXT ThreadContext
+ )
+{
+ struct
+ {
+ HANDLE ThreadHandle;
+ PCONTEXT ThreadContext;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.ThreadContext = ThreadContext;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETCONTEXTTHREAD,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphSetContextThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in PCONTEXT ThreadContext
+ )
+{
+ struct
+ {
+ HANDLE ThreadHandle;
+ PCONTEXT ThreadContext;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.ThreadContext = ThreadContext;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_SETCONTEXTTHREAD,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphCaptureStackBackTraceThread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in ULONG FramesToSkip,
+ __in ULONG FramesToCapture,
+ __out_ecount(FramesToCapture) PPVOID BackTrace,
+ __out_opt PULONG CapturedFrames,
+ __out_opt PULONG BackTraceHash
+ )
+{
+ struct
+ {
+ HANDLE ThreadHandle;
+ ULONG FramesToSkip;
+ ULONG FramesToCapture;
+ PPVOID BackTrace;
+ PULONG CapturedFrames;
+ PULONG BackTraceHash;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.FramesToSkip = FramesToSkip;
+ args.FramesToCapture = FramesToCapture;
+ args.BackTrace = BackTrace;
+ args.CapturedFrames = CapturedFrames;
+ args.BackTraceHash = BackTraceHash;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_CAPTURESTACKBACKTRACETHREAD,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphGetThreadWin32Thread(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __out PPVOID Win32Thread
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ThreadHandle;
+ } args;
+ struct
+ {
+ PVOID Win32Thread;
+ } ret;
+
+ args.ThreadHandle = ThreadHandle;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETTHREADWIN32THREAD,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *Win32Thread = ret.Win32Thread;
+ }
+
+ return status;
+}
+
+NTSTATUS KphAssignImpersonationToken(
+ __in HANDLE KphHandle,
+ __in HANDLE ThreadHandle,
+ __in HANDLE TokenHandle
+ )
+{
+ struct
+ {
+ HANDLE ThreadHandle;
+ HANDLE TokenHandle;
+ } args;
+
+ args.ThreadHandle = ThreadHandle;
+ args.TokenHandle = TokenHandle;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_ASSIGNIMPERSONATIONTOKEN,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphQueryProcessHandles(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __out_bcount_opt(BufferLength) PVOID Buffer,
+ __in_opt ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ )
+{
+ struct
+ {
+ HANDLE ProcessHandle;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PULONG ReturnLength;
+ } args;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Buffer = Buffer;
+ args.BufferLength = BufferLength;
+ args.ReturnLength = ReturnLength;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_QUERYPROCESSHANDLES,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphGetHandleObjectName(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out_bcount_opt(BufferLength) PUNICODE_STRING Buffer,
+ __in ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ )
+{
+ NTSTATUS status;
+ UNICODE_STRING buffer;
+ ULONG returnLength;
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } args;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Handle = Handle;
+
+ if (Buffer && BufferLength >= sizeof(UNICODE_STRING))
+ {
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETHANDLEOBJECTNAME,
+ &args,
+ sizeof(args),
+ Buffer,
+ BufferLength,
+ &returnLength
+ );
+
+ Buffer->Buffer = (PWSTR)PTR_ADD_OFFSET(Buffer, sizeof(UNICODE_STRING));
+
+ if (ReturnLength)
+ {
+ if (status == STATUS_BUFFER_TOO_SMALL)
+ *ReturnLength = Buffer->Length;
+ else
+ *ReturnLength = returnLength;
+ }
+ }
+ else
+ {
+ // User doesn't give us a buffer, or it was too small.
+ // Use our internal buffer.
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETHANDLEOBJECTNAME,
+ &args,
+ sizeof(args),
+ &buffer,
+ sizeof(UNICODE_STRING),
+ &returnLength
+ );
+
+ if (ReturnLength)
+ {
+ if (status == STATUS_BUFFER_TOO_SMALL)
+ *ReturnLength = buffer.Length;
+ else
+ *ReturnLength = returnLength;
+ }
+ }
+
+ return status;
+}
+
+NTSTATUS KphZwQueryObject(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __in OBJECT_INFORMATION_CLASS ObjectInformationClass,
+ __in_bcount_opt(BufferLength) PVOID Buffer,
+ __in ULONG BufferLength,
+ __out_opt PULONG ReturnLength
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ OBJECT_INFORMATION_CLASS ObjectInformationClass;
+ } args;
+ PKPH_ZWQUERYOBJECT_BUFFER ret;
+ ULONG retLength;
+
+ // Make sure we understand the object information class
+ // because we will be fixing the buffer later.
+ if (
+ ObjectInformationClass != ObjectBasicInformation &&
+ ObjectInformationClass != ObjectNameInformation &&
+ ObjectInformationClass != ObjectTypeInformation
+ )
+ return STATUS_INVALID_INFO_CLASS;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Handle = Handle;
+ args.ObjectInformationClass = ObjectInformationClass;
+
+ retLength = FIELD_OFFSET(KPH_ZWQUERYOBJECT_BUFFER, Buffer) + BufferLength;
+ ret = PhAllocate(retLength);
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_ZWQUERYOBJECT,
+ &args,
+ sizeof(args),
+ ret,
+ retLength,
+ NULL
+ );
+
+ // Make sure the actual I/O control request succeeded.
+ if (NT_SUCCESS(status))
+ {
+ // Check if ZwQueryObject succeeded.
+ status = ret->Status;
+
+ if (NT_SUCCESS(status))
+ {
+ if (Buffer)
+ {
+ // Copy the buffer contents to the user buffer.
+ memcpy(Buffer, ret->Buffer, ret->ReturnLength);
+
+ // Rebase pointers in the buffer.
+ if (ObjectInformationClass == ObjectNameInformation)
+ {
+ POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)Buffer;
+
+ nameInfo->Name.Buffer = (PWSTR)REBASE_ADDRESS(
+ nameInfo->Name.Buffer,
+ ret->BufferBase,
+ Buffer
+ );
+ }
+ else if (ObjectInformationClass == ObjectTypeInformation)
+ {
+ POBJECT_TYPE_INFORMATION typeInfo = (POBJECT_TYPE_INFORMATION)Buffer;
+
+ typeInfo->TypeName.Buffer = (PWSTR)REBASE_ADDRESS(
+ typeInfo->TypeName.Buffer,
+ ret->BufferBase,
+ Buffer
+ );
+ }
+ }
+ }
+
+ if (ReturnLength)
+ *ReturnLength = ret->ReturnLength;
+ }
+
+ PhFree(ret);
+
+ return status;
+}
+
+NTSTATUS KphDuplicateObject(
+ __in HANDLE KphHandle,
+ __in HANDLE SourceProcessHandle,
+ __in HANDLE SourceHandle,
+ __in_opt HANDLE TargetProcessHandle,
+ __out_opt PHANDLE TargetHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in ULONG HandleAttributes,
+ __in ULONG Options
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE SourceProcessHandle;
+ HANDLE SourceHandle;
+ HANDLE TargetProcessHandle;
+ PHANDLE TargetHandle;
+ ACCESS_MASK DesiredAccess;
+ ULONG HandleAttributes;
+ ULONG Options;
+ } args;
+
+ args.SourceProcessHandle = SourceProcessHandle;
+ args.SourceHandle = SourceHandle;
+ args.TargetProcessHandle = TargetProcessHandle;
+ args.TargetHandle = TargetHandle;
+ args.DesiredAccess = DesiredAccess;
+ args.HandleAttributes = HandleAttributes;
+ args.Options = Options;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_DUPLICATEOBJECT,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+
+ if (status == STATUS_CANT_TERMINATE_SELF)
+ {
+ /* Means we tried to close a handle in the current process.
+ * Do it now. */
+ status = NtClose(SourceHandle);
+ }
+
+ return status;
+}
+
+NTSTATUS KphSetHandleAttributes(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __in ULONG Flags
+ )
+{
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ ULONG Flags;
+ } args;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Handle = Handle;
+ args.Flags = Flags;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_SETHANDLEATTRIBUTES,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphSetHandleGrantedAccess(
+ __in HANDLE KphHandle,
+ __in HANDLE Handle,
+ __in ACCESS_MASK GrantedAccess
+ )
+{
+ struct
+ {
+ HANDLE Handle;
+ ACCESS_MASK GrantedAccess;
+ } args;
+
+ args.Handle = Handle;
+ args.GrantedAccess = GrantedAccess;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_SETHANDLEGRANTEDACCESS,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphGetProcessId(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out PHANDLE ProcessId
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } args;
+ struct
+ {
+ HANDLE ProcessId;
+ } ret;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Handle = Handle;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETPROCESSID,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *ProcessId = ret.ProcessId;
+ }
+
+ return status;
+}
+
+NTSTATUS KphGetThreadId(
+ __in HANDLE KphHandle,
+ __in HANDLE ProcessHandle,
+ __in HANDLE Handle,
+ __out PHANDLE ThreadId,
+ __out_opt PHANDLE ProcessId
+ )
+{
+ NTSTATUS status;
+ struct
+ {
+ HANDLE ProcessHandle;
+ HANDLE Handle;
+ } args;
+ struct
+ {
+ HANDLE ThreadId;
+ HANDLE ProcessId;
+ } ret;
+
+ args.ProcessHandle = ProcessHandle;
+ args.Handle = Handle;
+
+ status = KphpDeviceIoControl(
+ KphHandle,
+ KPH_GETTHREADID,
+ &args,
+ sizeof(args),
+ &ret,
+ sizeof(ret),
+ NULL
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ *ThreadId = ret.ThreadId;
+
+ if (ProcessId)
+ *ProcessId = ret.ProcessId;
+ }
+
+ return status;
+}
+
+NTSTATUS KphOpenNamedObject(
+ __in HANDLE KphHandle,
+ __out PHANDLE Handle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ )
+{
+ struct
+ {
+ PHANDLE Handle;
+ ACCESS_MASK DesiredAccess;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } args;
+
+ args.Handle = Handle;
+ args.DesiredAccess = DesiredAccess;
+ args.ObjectAttributes = ObjectAttributes;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENNAMEDOBJECT,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphOpenDirectoryObject(
+ __in HANDLE KphHandle,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ )
+{
+ struct
+ {
+ PHANDLE DirectoryHandle;
+ ACCESS_MASK DesiredAccess;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } args;
+
+ args.DirectoryHandle = DirectoryHandle;
+ args.DesiredAccess = DesiredAccess;
+ args.ObjectAttributes = ObjectAttributes;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENDIRECTORYOBJECT,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphOpenDriver(
+ __in HANDLE KphHandle,
+ __out PHANDLE DriverHandle,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ )
+{
+ struct
+ {
+ PHANDLE DriverHandle;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } args;
+
+ args.DriverHandle = DriverHandle;
+ args.ObjectAttributes = ObjectAttributes;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENDRIVER,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphQueryInformationDriver(
+ __in HANDLE KphHandle,
+ __in HANDLE DriverHandle,
+ __in DRIVER_INFORMATION_CLASS DriverInformationClass,
+ __out_bcount_opt(DriverInformationLength) PVOID DriverInformation,
+ __in ULONG DriverInformationLength,
+ __out_opt PULONG ReturnLength
+ )
+{
+ struct
+ {
+ HANDLE DriverHandle;
+ DRIVER_INFORMATION_CLASS DriverInformationClass;
+ PVOID DriverInformation;
+ ULONG DriverInformationLength;
+ PULONG ReturnLength;
+ } args;
+
+ args.DriverHandle = DriverHandle;
+ args.DriverInformationClass = DriverInformationClass;
+ args.DriverInformation = DriverInformation;
+ args.DriverInformationLength = DriverInformationLength;
+ args.ReturnLength = ReturnLength;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_QUERYINFORMATIONDRIVER,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}
+
+NTSTATUS KphOpenType(
+ __in HANDLE KphHandle,
+ __out PHANDLE TypeHandle,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+ )
+{
+ struct
+ {
+ PHANDLE TypeHandle;
+ POBJECT_ATTRIBUTES ObjectAttributes;
+ } args;
+
+ args.TypeHandle = TypeHandle;
+ args.ObjectAttributes = ObjectAttributes;
+
+ return KphpDeviceIoControl(
+ KphHandle,
+ KPH_OPENTYPE,
+ &args,
+ sizeof(args),
+ NULL,
+ 0,
+ NULL
+ );
+}