completed KProcessHacker2 (slim version of KProcessHacker)

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3042 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2010-04-08 05:54:23 +00:00
parent 2f81135e3b
commit 39a444b6df
47 changed files with 2184 additions and 9789 deletions
-355
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
-408
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
}
Binary file not shown.
-2
View File
@@ -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
-78
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
-144
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
-108
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
-2
View File
@@ -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 */
-2
View File
@@ -23,8 +23,6 @@
#ifndef _KE_H
#define _KE_H
#include "types.h"
/* APCs */
typedef enum _KAPC_ENVIRONMENT
+11 -5
View File
@@ -23,16 +23,23 @@
#ifndef _KPH_H
#define _KPH_H
#include "types.h"
#include <ntifs.h>
#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 */
+52 -117
View File
@@ -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
-3
View File
@@ -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)
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
-6
View File
@@ -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)
-2
View File
@@ -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
-4
View File
@@ -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))
+4 -2
View File
@@ -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;
-320
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
-2
View File
@@ -23,8 +23,6 @@
#ifndef _TEST_H
#define _TEST_H
#include "kph.h"
VOID KphTestPushLock();
#endif
-2
View File
@@ -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. */
-7
View File
@@ -1,7 +0,0 @@
#ifndef _TYPES_H
#define _TYPES_H
#include <ntifs.h>
#include "version.h"
#endif
-2
View File
@@ -23,8 +23,6 @@
#ifndef _UTIL_H
#define _UTIL_H
#include "kph.h"
/* Streams
*
* Streams are small buffer management structures. They
+1 -142
View File
@@ -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
-2
View File
@@ -23,8 +23,6 @@
#ifndef _ZW_H
#define _ZW_H
#include "types.h"
NTSTATUS NTAPI ZwOpenProcessToken(
__in HANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
+1 -1
View File
@@ -20,7 +20,7 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "include/io.h"
#include "include/kph.h"
VOID KphpCopyInfoUnicodeString(
__out PVOID Information,
+22 -15
View File
@@ -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;
File diff suppressed because it is too large Load Diff
-1
View File
@@ -21,7 +21,6 @@
*/
#include "include/kph.h"
#include "include/mm.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KphReadVirtualMemory)
+14 -1
View File
@@ -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())
{
-457
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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);
}
+10 -9
View File
@@ -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;
}
+3
View File
@@ -20,6 +20,9 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#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. */
+2 -2
View File
@@ -1,7 +1,7 @@
#include <windows.h>
#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
-1
View File
@@ -21,7 +21,6 @@
*/
#include "include/kph.h"
#include "include/se.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, KphOpenProcessTokenEx)
-6
View File
@@ -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 \
-312
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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());
}
File diff suppressed because it is too large Load Diff
-513
View File
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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
);
}
+1 -1
View File
@@ -20,7 +20,7 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "include/util.h"
#include "include/kph.h"
/* KphInitializeStream
*
+1 -252
View File
@@ -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;
}
+1 -1
View File
@@ -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
+7 -19
View File
@@ -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)
+235 -295
View File
@@ -4,70 +4,62 @@
#include <phbase.h>
#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
+935 -1112
View File
File diff suppressed because it is too large Load Diff