fixed "don't allow kernel-mode to bypass protection" by allowing rule creators to bypass the rules

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1296 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2009-05-18 09:11:21 +00:00
parent 03db5a1fd2
commit 5a25f7aeeb
5 changed files with 141 additions and 22 deletions
Binary file not shown.
@@ -81,10 +81,16 @@
#define KPH_TIMEOUT_TO_SEC ((LONGLONG) 1 * 10 * 1000 * 1000)
#define KPH_REL_TIMEOUT_IN_SEC(Time) (Time * -1 * KPH_TIMEOUT_TO_SEC)
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
VOID DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphDispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS KphUnsupported(PDEVICE_OBJECT DeviceObject, PIRP Irp);
BOOLEAN AddClientEntry(HANDLE ProcessId);
BOOLEAN IsProcessClient(HANDLE ProcessId);
BOOLEAN RemoveClientEntry(HANDLE ProcessId);
#endif
+1
View File
@@ -38,6 +38,7 @@ typedef struct _KPH_PROCESS_ENTRY
{
LIST_ENTRY ListEntry;
PEPROCESS Process;
PEPROCESS CreatorProcess;
HANDLE Tag;
LOGICAL AllowKernelMode;
ACCESS_MASK ProcessAllowMask;
+128 -19
View File
@@ -28,6 +28,17 @@
#include "include/ps.h"
#include "include/version.h"
typedef struct _KPH_CLIENT_ENTRY
{
LIST_ENTRY ListEntry;
HANDLE ProcessId;
} KPH_CLIENT_ENTRY, *PKPH_CLIENT_ENTRY;
LIST_ENTRY ClientListHead;
KSPIN_LOCK ClientListLock;
NPAGED_LOOKASIDE_LIST ClientLookasideList;
static BOOLEAN ProtectionInitialized = FALSE;
#pragma alloc_text(PAGE, KphDispatchCreate)
#pragma alloc_text(PAGE, KphDispatchClose)
#pragma alloc_text(PAGE, KphDispatchDeviceControl)
@@ -35,25 +46,6 @@
#pragma alloc_text(PAGE, KphUnsupported)
#pragma pack(1)
static BOOLEAN ProtectionInitialized = FALSE;
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING dosDeviceName;
RtlInitUnicodeString(&dosDeviceName, KPH_DEVICE_DOS_NAME);
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
if (ProtectionInitialized)
{
KphProtectDeinit();
ProtectionInitialized = FALSE;
}
dprintf("Driver unloaded\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
@@ -78,6 +70,19 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
if (!NT_SUCCESS(status))
return status;
/* Initialize client list structures */
InitializeListHead(&ClientListHead);
KeInitializeSpinLock(&ClientListLock);
ExInitializeNPagedLookasideList(
&ClientLookasideList,
NULL,
NULL,
0,
sizeof(KPH_CLIENT_ENTRY),
KPH_TAG,
0
);
RtlInitUnicodeString(&deviceName, KPH_DEVICE_NAME);
RtlInitUnicodeString(&dosDeviceName, KPH_DEVICE_DOS_NAME);
@@ -105,6 +110,26 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING dosDeviceName;
RtlInitUnicodeString(&dosDeviceName, KPH_DEVICE_DOS_NAME);
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
/* Destroy client list structures */
ExDeleteNPagedLookasideList(&ClientLookasideList);
if (ProtectionInitialized)
{
KphProtectDeinit();
ProtectionInitialized = FALSE;
}
dprintf("Driver unloaded\n");
}
NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
@@ -119,6 +144,13 @@ NTSTATUS KphDispatchCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
}
#endif
/* Add a client entry. */
if (!AddClientEntry(PsGetCurrentProcessId()))
{
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
return STATUS_INSUFFICIENT_RESOURCES;
}
dprintf("Client (PID %d) connected\n", PsGetCurrentProcessId());
dprintf("Base IOCTL is 0x%08x\n", KPH_CTL_CODE(0));
@@ -135,6 +167,9 @@ NTSTATUS KphDispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
dprintf("Removed %d protection entries\n", count);
}
/* Remove the client entry. */
RemoveClientEntry(PsGetCurrentProcessId());
dprintf("Client (PID %d) disconnected\n", PsGetCurrentProcessId());
return status;
@@ -149,6 +184,80 @@ VOID InitProtection()
}
}
BOOLEAN AddClientEntry(HANDLE ProcessId)
{
KIRQL oldIrql;
PKPH_CLIENT_ENTRY entry = ExAllocateFromNPagedLookasideList(&ClientLookasideList);
if (!entry)
return FALSE;
KeAcquireSpinLock(&ClientListLock, &oldIrql);
InsertHeadList(&ClientListHead, &entry->ListEntry);
KeReleaseSpinLock(&ClientListLock, oldIrql);
return TRUE;
}
BOOLEAN IsProcessClient(HANDLE ProcessId)
{
KIRQL oldIrql;
PLIST_ENTRY entry = ClientListHead.Flink;
KeAcquireSpinLock(&ClientListLock, &oldIrql);
while (entry != &ClientListHead)
{
PKPH_CLIENT_ENTRY clientEntry =
CONTAINING_RECORD(entry, KPH_CLIENT_ENTRY, ListEntry);
if (clientEntry->ProcessId == ProcessId)
{
KeReleaseSpinLock(&ClientListLock, oldIrql);
return TRUE;
}
entry = entry->Flink;
}
KeReleaseSpinLock(&ClientListLock, oldIrql);
return FALSE;
}
BOOLEAN RemoveClientEntry(HANDLE ProcessId)
{
KIRQL oldIrql;
PLIST_ENTRY entry = ClientListHead.Flink;
KeAcquireSpinLock(&ClientListLock, &oldIrql);
while (entry != &ClientListHead)
{
PKPH_CLIENT_ENTRY clientEntry =
CONTAINING_RECORD(entry, KPH_CLIENT_ENTRY, ListEntry);
if (clientEntry->ProcessId == ProcessId)
{
RemoveEntryList(&clientEntry->ListEntry);
ExFreeToNPagedLookasideList(
&ClientLookasideList,
clientEntry
);
KeReleaseSpinLock(&ClientListLock, oldIrql);
return TRUE;
}
entry = entry->Flink;
}
KeReleaseSpinLock(&ClientListLock, oldIrql);
return FALSE;
}
/* from YAPM */
NTSTATUS GetObjectName(PFILE_OBJECT FileObject, PVOID Buffer, ULONG BufferLength, PULONG ReturnLength)
{
+6 -3
View File
@@ -161,7 +161,7 @@ NTSTATUS NTAPI KphNewObOpenObjectByPointer(
access = DesiredAccess;
/* If we have an access state, get the desired access from it. */
if (PassedAccessState != NULL)
if (PassedAccessState)
access = PassedAccessState->OriginalDesiredAccess;
/* Search for and copy the corresponding process protection entry. */
@@ -174,6 +174,8 @@ NTSTATUS NTAPI KphNewObOpenObjectByPointer(
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() &&
(access & mask) != access
)
{
@@ -228,10 +230,11 @@ PKPH_PROCESS_ENTRY KphProtectAddEntry(
/* Lookaside list no longer needed. */
ExReleaseRundownProtection(&ProtectedProcessRundownProtect);
if (entry == NULL)
if (!entry)
return NULL;
entry->Process = Process;
entry->CreatorProcess = PsGetCurrentProcess();
entry->Tag = Tag;
entry->AllowKernelMode = AllowKernelMode;
entry->ProcessAllowMask = ProcessAllowMask;
@@ -326,7 +329,7 @@ BOOLEAN KphProtectRemoveByProcess(
{
PKPH_PROCESS_ENTRY entry = KphProtectFindEntry(Process, NULL);
if (entry == NULL)
if (!entry)
return FALSE;
KphpProtectRemoveEntry(entry);