mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
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:
@@ -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;
|
||||
}
|
||||
@@ -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.
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#ifndef _KE_H
|
||||
#define _KE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* APCs */
|
||||
|
||||
typedef enum _KAPC_ENVIRONMENT
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -23,8 +23,6 @@
|
||||
#ifndef _TEST_H
|
||||
#define _TEST_H
|
||||
|
||||
#include "kph.h"
|
||||
|
||||
VOID KphTestPushLock();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#include <ntifs.h>
|
||||
#include "version.h"
|
||||
|
||||
#endif
|
||||
@@ -23,8 +23,6 @@
|
||||
#ifndef _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
#include "kph.h"
|
||||
|
||||
/* Streams
|
||||
*
|
||||
* Streams are small buffer management structures. They
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#ifndef _ZW_H
|
||||
#define _ZW_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
NTSTATUS NTAPI ZwOpenProcessToken(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "include/kph.h"
|
||||
#include "include/mm.h"
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, KphReadVirtualMemory)
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "include/kph.h"
|
||||
#include "include/se.h"
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, KphOpenProcessTokenEx)
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
@@ -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
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user