mirror of
https://github.com/JKornev/hidden
synced 2024-06-30 19:02:03 +00:00
Major changes
- Fixed BSOD on driver deinitialization step - Fixed resources leak in the reg filter - Fixed path normalization function - Added support for inherit type in predefined process monitor configs - Added support for opening protected processes by subsystem - Added tests for protected processes and other little fixes
This commit is contained in:
parent
8a7929b310
commit
98014e750e
@ -4,7 +4,7 @@
|
|||||||
#include "Device.h"
|
#include "Device.h"
|
||||||
#include "DeviceAPI.h"
|
#include "DeviceAPI.h"
|
||||||
|
|
||||||
|
BOOLEAN g_deviceInited = FALSE;
|
||||||
PDEVICE_OBJECT g_deviceObject = NULL;
|
PDEVICE_OBJECT g_deviceObject = NULL;
|
||||||
|
|
||||||
// =========================================================================================
|
// =========================================================================================
|
||||||
@ -453,6 +453,7 @@ NTSTATUS InitializeDevice(PDRIVER_OBJECT DriverObject)
|
|||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = IrpDeviceCleanup;
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = IrpDeviceCleanup;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlHandler;
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlHandler;
|
||||||
g_deviceObject = deviceObject;
|
g_deviceObject = deviceObject;
|
||||||
|
g_deviceInited = TRUE;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -462,11 +463,16 @@ NTSTATUS DestroyDevice()
|
|||||||
NTSTATUS status = STATUS_SUCCESS;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
UNICODE_STRING dosDeviceName = RTL_CONSTANT_STRING(DOS_DEVICES_LINK_NAME);
|
UNICODE_STRING dosDeviceName = RTL_CONSTANT_STRING(DOS_DEVICES_LINK_NAME);
|
||||||
|
|
||||||
|
if (!g_deviceInited)
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
|
||||||
status = IoDeleteSymbolicLink(&dosDeviceName);
|
status = IoDeleteSymbolicLink(&dosDeviceName);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": symbolic link deletion failed with code:%08x\n", status);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": symbolic link deletion failed with code:%08x\n", status);
|
||||||
|
|
||||||
IoDeleteDevice(g_deviceObject);
|
IoDeleteDevice(g_deviceObject);
|
||||||
|
|
||||||
|
g_deviceInited = FALSE;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ CONST FLT_REGISTRATION FilterRegistration = {
|
|||||||
NULL // NormalizeNameComponent
|
NULL // NormalizeNameComponent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BOOLEAN g_fsMonitorInited = FALSE;
|
||||||
PFLT_FILTER gFilterHandle = NULL;
|
PFLT_FILTER gFilterHandle = NULL;
|
||||||
|
|
||||||
ExcludeContext g_excludeFileContext;
|
ExcludeContext g_excludeFileContext;
|
||||||
@ -68,19 +69,6 @@ CONST PWCHAR g_excludeDirs[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS DestroyFSMiniFilter()
|
|
||||||
{
|
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": Entered %d\n", (UINT32)KeGetCurrentIrql());
|
|
||||||
|
|
||||||
FltUnregisterFilter(gFilterHandle);
|
|
||||||
gFilterHandle = NULL;
|
|
||||||
|
|
||||||
DestroyExcludeListContext(g_excludeFileContext);
|
|
||||||
DestroyExcludeListContext(g_excludeDirectoryContext);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FilterSetup(PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType)
|
NTSTATUS FilterSetup(PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(FltObjects);
|
UNREFERENCED_PARAMETER(FltObjects);
|
||||||
@ -799,15 +787,40 @@ NTSTATUS InitializeFSMiniFilter(PDRIVER_OBJECT DriverObject)
|
|||||||
status = FltStartFiltering(gFilterHandle);
|
status = FltStartFiltering(gFilterHandle);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": can't start filtering, code:%08x\n", status);
|
||||||
FltUnregisterFilter(gFilterHandle);
|
FltUnregisterFilter(gFilterHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": Completed status:%08x\n", status);
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DestroyExcludeListContext(g_excludeFileContext);
|
||||||
|
DestroyExcludeListContext(g_excludeDirectoryContext);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_fsMonitorInited = TRUE;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS DestroyFSMiniFilter()
|
||||||
|
{
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": Entered %d\n", (UINT32)KeGetCurrentIrql());
|
||||||
|
|
||||||
|
if (!g_fsMonitorInited)
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
|
||||||
|
FltUnregisterFilter(gFilterHandle);
|
||||||
|
gFilterHandle = NULL;
|
||||||
|
|
||||||
|
DestroyExcludeListContext(g_excludeFileContext);
|
||||||
|
DestroyExcludeListContext(g_excludeDirectoryContext);
|
||||||
|
g_fsMonitorInited = FALSE;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS AddHiddenFile(PUNICODE_STRING FilePath, PULONGLONG ObjId)
|
NTSTATUS AddHiddenFile(PUNICODE_STRING FilePath, PULONGLONG ObjId)
|
||||||
{
|
{
|
||||||
const USHORT maxBufSize = FilePath->Length + NORMALIZE_INCREAMENT;
|
const USHORT maxBufSize = FilePath->Length + NORMALIZE_INCREAMENT;
|
||||||
|
@ -53,6 +53,6 @@ NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS Class, PVOID* InfoBuffe
|
|||||||
NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE ProcessId, PVOID* InfoBuffer, PSIZE_T InfoSize);
|
NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE ProcessId, PVOID* InfoBuffer, PSIZE_T InfoSize);
|
||||||
VOID FreeInformation(PVOID Buffer);
|
VOID FreeInformation(PVOID Buffer);
|
||||||
|
|
||||||
#define NORMALIZE_INCREAMENT (USHORT)64
|
#define NORMALIZE_INCREAMENT (USHORT)128
|
||||||
|
|
||||||
NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized);
|
NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
|
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
|
||||||
#define SYSTEM_PROCESS_ID (HANDLE)4
|
#define SYSTEM_PROCESS_ID (HANDLE)4
|
||||||
|
|
||||||
|
BOOLEAN g_psMonitorInited = FALSE;
|
||||||
PVOID g_obRegCallback = NULL;
|
PVOID g_obRegCallback = NULL;
|
||||||
|
|
||||||
OB_OPERATION_REGISTRATION g_regOperation[2];
|
OB_OPERATION_REGISTRATION g_regOperation[2];
|
||||||
@ -15,20 +16,71 @@ OB_CALLBACK_REGISTRATION g_regCallback;
|
|||||||
PsRulesContext g_excludeProcessRules;
|
PsRulesContext g_excludeProcessRules;
|
||||||
PsRulesContext g_protectProcessRules;
|
PsRulesContext g_protectProcessRules;
|
||||||
|
|
||||||
|
typedef struct _ProcessListEntry {
|
||||||
|
LPCWSTR path;
|
||||||
|
ULONG inherit;
|
||||||
|
} ProcessListEntry, *PProcessListEntry;
|
||||||
|
|
||||||
// Use this variable for hard code full path to applications that can see hidden objects
|
// Use this variable for hard code full path to applications that can see hidden objects
|
||||||
// For instance: L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc.exe",
|
// For instance: L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc.exe",
|
||||||
// Notice: this array should be NULL terminated
|
// Notice: this array should be NULL terminated
|
||||||
CONST PWCHAR g_excludeProcesses[] = {
|
CONST ProcessListEntry g_excludeProcesses[] = {
|
||||||
NULL
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use this variable for hard code full path to applications that will be protected
|
// Use this variable for hard code full path to applications that will be protected
|
||||||
// For instance: L"\\Device\\HarddiskVolume1\\Windows\\System32\\cmd.exe",
|
// For instance: L"\\Device\\HarddiskVolume1\\Windows\\System32\\cmd.exe",
|
||||||
// Notice: this array should be NULL terminated
|
// Notice: this array should be NULL terminated
|
||||||
CONST PWCHAR g_protectProcesses[] = {
|
CONST ProcessListEntry g_protectProcesses[] = {
|
||||||
NULL
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CSRSS_PAHT_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
UNICODE_STRING g_csrssPath;
|
||||||
|
WCHAR g_csrssPathBuffer[CSRSS_PAHT_BUFFER_SIZE];
|
||||||
|
|
||||||
|
BOOLEAN CheckProtectedOperation(HANDLE Source, HANDLE Destination)
|
||||||
|
{
|
||||||
|
ProcessTableEntry srcInfo, destInfo;
|
||||||
|
|
||||||
|
if (Source == Destination)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
destInfo.processId = Destination;
|
||||||
|
if (!GetProcessInProcessTable(&destInfo))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
srcInfo.processId = Source;
|
||||||
|
if (!GetProcessInProcessTable(&srcInfo))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Not-inited process can open any process (parent, csrss, etc)
|
||||||
|
if (!destInfo.inited)
|
||||||
|
{
|
||||||
|
// Update if source is subsystem and destination isn't inited
|
||||||
|
if (srcInfo.subsystem)
|
||||||
|
{
|
||||||
|
destInfo.inited = TRUE;
|
||||||
|
if (!UpdateProcessInProcessTable(&destInfo))
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": can't update initial state for process: %d\n", destInfo.processId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!destInfo.protected)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (srcInfo.protected)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (srcInfo.subsystem)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
|
OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(RegistrationContext);
|
UNREFERENCED_PARAMETER(RegistrationContext);
|
||||||
@ -36,16 +88,13 @@ OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_O
|
|||||||
if (OperationInformation->KernelHandle)
|
if (OperationInformation->KernelHandle)
|
||||||
return OB_PREOP_SUCCESS;
|
return OB_PREOP_SUCCESS;
|
||||||
|
|
||||||
if (!IsProcessProtected(PsGetProcessId(OperationInformation->Object)))
|
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! Process: %d(%d:%d), Oper: %s, Space: %s\n",
|
||||||
return OB_PREOP_SUCCESS;
|
// PsGetProcessId(OperationInformation->Object), PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||||
|
// (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE ? "create" : "dup"),
|
||||||
|
// (OperationInformation->KernelHandle ? "kernel" : "user")
|
||||||
|
//);
|
||||||
|
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! Process: %d(%d:%d), Oper: %s, Space: %s\n",
|
if (!CheckProtectedOperation(PsGetCurrentProcessId(), PsGetProcessId(OperationInformation->Object)))
|
||||||
PsGetProcessId(OperationInformation->Object), PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
|
||||||
(OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE ? "create" : "dup"),
|
|
||||||
(OperationInformation->KernelHandle ? "kernel" : "user")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (IsProcessProtected(PsGetCurrentProcessId()))
|
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! allow protected process %d\n", PsGetCurrentProcessId());
|
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! allow protected process %d\n", PsGetCurrentProcessId());
|
||||||
return OB_PREOP_SUCCESS;
|
return OB_PREOP_SUCCESS;
|
||||||
@ -68,16 +117,13 @@ OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OP
|
|||||||
if (OperationInformation->KernelHandle)
|
if (OperationInformation->KernelHandle)
|
||||||
return OB_PREOP_SUCCESS;
|
return OB_PREOP_SUCCESS;
|
||||||
|
|
||||||
if (!IsProcessProtected(PsGetProcessId(OperationInformation->Object)))
|
//DbgPrint("FsFilter1!" __FUNCTION__ ": Thread: %d(%d:%d), Oper: %s, Space: %s\n",
|
||||||
return OB_PREOP_SUCCESS;
|
// PsGetThreadId(OperationInformation->Object), PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||||
|
// (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE ? "create" : "dup"),
|
||||||
|
// (OperationInformation->KernelHandle ? "kernel" : "user")
|
||||||
|
//);
|
||||||
|
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": Thread: %d(%d:%d), Oper: %s, Space: %s\n",
|
if (!CheckProtectedOperation(PsGetCurrentProcessId(), PsGetProcessId(OperationInformation->Object)))
|
||||||
PsGetThreadId(OperationInformation->Object), PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
|
||||||
(OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE ? "create" : "dup"),
|
|
||||||
(OperationInformation->KernelHandle ? "kernel" : "user")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (IsProcessProtected(PsGetCurrentProcessId()))
|
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! allow protected thread %d\n", PsGetCurrentProcessId());
|
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! allow protected thread %d\n", PsGetCurrentProcessId());
|
||||||
return OB_PREOP_SUCCESS;
|
return OB_PREOP_SUCCESS;
|
||||||
@ -100,6 +146,9 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
|
|||||||
|
|
||||||
RtlZeroMemory(&lookup, sizeof(lookup));
|
RtlZeroMemory(&lookup, sizeof(lookup));
|
||||||
|
|
||||||
|
Entry->inited = (!g_psMonitorInited ? TRUE : FALSE);
|
||||||
|
Entry->subsystem = RtlEqualUnicodeString(&g_csrssPath, ImgPath, TRUE);
|
||||||
|
|
||||||
// Check exclude flag
|
// Check exclude flag
|
||||||
|
|
||||||
Entry->excluded = FALSE;
|
Entry->excluded = FALSE;
|
||||||
@ -242,12 +291,31 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
|
|||||||
{
|
{
|
||||||
const USHORT maxBufSize = 512;
|
const USHORT maxBufSize = 512;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
UNICODE_STRING str, normalized;
|
UNICODE_STRING str, normalized, csrss;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
PsRuleEntryId ruleId;
|
PsRuleEntryId ruleId;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(DriverObject);
|
UNREFERENCED_PARAMETER(DriverObject);
|
||||||
|
|
||||||
|
// Set csrss path
|
||||||
|
|
||||||
|
RtlZeroMemory(g_csrssPathBuffer, sizeof(g_csrssPathBuffer));
|
||||||
|
g_csrssPath.Buffer = g_csrssPathBuffer;
|
||||||
|
g_csrssPath.Length = 0;
|
||||||
|
g_csrssPath.MaximumLength = sizeof(g_csrssPathBuffer);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&csrss, L"\\SystemRoot\\System32\\csrss.exe");
|
||||||
|
status = NormalizeDevicePath(&csrss, &g_csrssPath);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": subsystem path normalization failed with code:%08x\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": subsystem path: %wZ\n", &g_csrssPath);
|
||||||
|
|
||||||
|
// Init normalization buffer
|
||||||
|
|
||||||
normalized.Buffer = (PWCH)ExAllocatePool(NonPagedPool, maxBufSize);
|
normalized.Buffer = (PWCH)ExAllocatePool(NonPagedPool, maxBufSize);
|
||||||
normalized.Length = 0;
|
normalized.Length = 0;
|
||||||
normalized.MaximumLength = maxBufSize;
|
normalized.MaximumLength = maxBufSize;
|
||||||
@ -260,27 +328,28 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
|
|||||||
// Initialize and fill exclude file\dir lists
|
// Initialize and fill exclude file\dir lists
|
||||||
|
|
||||||
// exclude
|
// exclude
|
||||||
|
|
||||||
status = InitializePsRuleListContext(&g_excludeProcessRules);
|
status = InitializePsRuleListContext(&g_excludeProcessRules);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": exclude process rules initialization failed with code:%08x\n", status);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": excluded process rules initialization failed with code:%08x\n", status);
|
||||||
ExFreePool(normalized.Buffer);
|
ExFreePool(normalized.Buffer);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; g_excludeProcesses[i]; i++)
|
for (i = 0; g_excludeProcesses[i].path; i++)
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&str, g_excludeProcesses[i]);
|
RtlInitUnicodeString(&str, g_excludeProcesses[i].path);
|
||||||
|
|
||||||
status = NormalizeDevicePath(&str, &normalized);
|
status = NormalizeDevicePath(&str, &normalized);
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": normalized exclude %wZ\n", &normalized);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": normalized excluded %wZ\n", &normalized);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": path normalization failed with code:%08x, path:%wZ\n", status, &str);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": path normalization failed with code:%08x, path:%wZ\n", status, &str);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddRuleToPsRuleList(g_excludeProcessRules, &normalized, PsRuleTypeWithoutInherit, &ruleId);
|
AddRuleToPsRuleList(g_excludeProcessRules, &normalized, g_excludeProcesses[i].inherit, &ruleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected
|
// protected
|
||||||
@ -288,25 +357,25 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
|
|||||||
status = InitializePsRuleListContext(&g_protectProcessRules);
|
status = InitializePsRuleListContext(&g_protectProcessRules);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": exclude process rules initialization failed with code:%08x\n", status);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": protected process rules initialization failed with code:%08x\n", status);
|
||||||
DestroyPsRuleListContext(g_excludeProcessRules);
|
DestroyPsRuleListContext(g_excludeProcessRules);
|
||||||
ExFreePool(normalized.Buffer);
|
ExFreePool(normalized.Buffer);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; g_protectProcesses[i]; i++)
|
for (i = 0; g_protectProcesses[i].path; i++)
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&str, g_protectProcesses[i]);
|
RtlInitUnicodeString(&str, g_protectProcesses[i].path);
|
||||||
|
|
||||||
status = NormalizeDevicePath(&str, &normalized);
|
status = NormalizeDevicePath(&str, &normalized);
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": normalized exclude %wZ\n", &normalized);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": normalized protected %wZ\n", &normalized);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": path normalization failed with code:%08x, path:%wZ\n", status, &str);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": path normalization failed with code:%08x, path:%wZ\n", status, &str);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddRuleToPsRuleList(g_protectProcessRules, &normalized, PsRuleTypeWithoutInherit, &ruleId);
|
AddRuleToPsRuleList(g_protectProcessRules, &normalized, g_protectProcesses[i].inherit, &ruleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = InitializeProcessTable(CheckProcessFlags);
|
status = InitializeProcessTable(CheckProcessFlags);
|
||||||
@ -320,6 +389,8 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
|
|||||||
|
|
||||||
ExFreePool(normalized.Buffer);
|
ExFreePool(normalized.Buffer);
|
||||||
|
|
||||||
|
g_psMonitorInited = TRUE;
|
||||||
|
|
||||||
// Register ps\thr pre create\duplicate object callback
|
// Register ps\thr pre create\duplicate object callback
|
||||||
|
|
||||||
g_regOperation[0].ObjectType = PsProcessType;
|
g_regOperation[0].ObjectType = PsProcessType;
|
||||||
@ -361,6 +432,9 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
|
|||||||
|
|
||||||
NTSTATUS DestroyPsMonitor()
|
NTSTATUS DestroyPsMonitor()
|
||||||
{
|
{
|
||||||
|
if (!g_psMonitorInited)
|
||||||
|
return STATUS_ALREADY_DISCONNECTED;
|
||||||
|
|
||||||
if (g_obRegCallback)
|
if (g_obRegCallback)
|
||||||
{
|
{
|
||||||
ObUnRegisterCallbacks(g_obRegCallback);
|
ObUnRegisterCallbacks(g_obRegCallback);
|
||||||
@ -373,6 +447,7 @@ NTSTATUS DestroyPsMonitor()
|
|||||||
DestroyPsRuleListContext(g_protectProcessRules);
|
DestroyPsRuleListContext(g_protectProcessRules);
|
||||||
|
|
||||||
DestroyProcessTable();
|
DestroyProcessTable();
|
||||||
|
g_psMonitorInited = FALSE;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -407,8 +482,6 @@ NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGL
|
|||||||
ExFreePool(normalized.Buffer);
|
ExFreePool(normalized.Buffer);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
//DbgPrint("FsFilter1!" __FUNCTION__ ": protect image: %wZ\n", ImagePath);
|
|
||||||
//return AddRuleToPsRuleList(g_protectProcessRules, ImagePath, InheritType, ObjId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable)
|
NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable)
|
||||||
|
@ -179,6 +179,9 @@ NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEnt
|
|||||||
if (entry.protected)
|
if (entry.protected)
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": protected process:%d\n", entry.processId);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": protected process:%d\n", entry.processId);
|
||||||
|
|
||||||
|
if (entry.subsystem)
|
||||||
|
DbgPrint("FsFilter1!" __FUNCTION__ ": subsystem process:%d\n", entry.processId);
|
||||||
|
|
||||||
// Go to next
|
// Go to next
|
||||||
|
|
||||||
FreeInformation(procName);
|
FreeInformation(procName);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Ntddk.h>
|
#include <Ntddk.h>
|
||||||
#include "PsTable.h"
|
|
||||||
|
|
||||||
typedef struct _ProcessTableEntry {
|
typedef struct _ProcessTableEntry {
|
||||||
HANDLE processId;
|
HANDLE processId;
|
||||||
@ -12,6 +11,9 @@ typedef struct _ProcessTableEntry{
|
|||||||
BOOLEAN protected;
|
BOOLEAN protected;
|
||||||
ULONG inheritProtection;
|
ULONG inheritProtection;
|
||||||
|
|
||||||
|
BOOLEAN subsystem;
|
||||||
|
BOOLEAN inited;
|
||||||
|
|
||||||
} ProcessTableEntry, *PProcessTableEntry;
|
} ProcessTableEntry, *PProcessTableEntry;
|
||||||
|
|
||||||
NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEntry, PCUNICODE_STRING, HANDLE));
|
NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEntry, PCUNICODE_STRING, HANDLE));
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#define FILTER_ALLOC_TAG 'FRlF'
|
#define FILTER_ALLOC_TAG 'FRlF'
|
||||||
|
|
||||||
|
BOOLEAN g_regFilterInited = FALSE;
|
||||||
|
|
||||||
ExcludeContext g_excludeRegKeyContext;
|
ExcludeContext g_excludeRegKeyContext;
|
||||||
ExcludeContext g_excludeRegValueContext;
|
ExcludeContext g_excludeRegValueContext;
|
||||||
|
|
||||||
@ -602,6 +604,7 @@ NTSTATUS InitializeRegistryFilter(PDRIVER_OBJECT DriverObject)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_regFilterInited = TRUE;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,10 +612,18 @@ NTSTATUS DestroyRegistryFilter()
|
|||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!g_regFilterInited)
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
|
||||||
status = CmUnRegisterCallback(g_regCookie);
|
status = CmUnRegisterCallback(g_regCookie);
|
||||||
if (!NT_SUCCESS(status))
|
if (!NT_SUCCESS(status))
|
||||||
DbgPrint("FsFilter1!" __FUNCTION__ ": Registry filter unregistration failed with code:%08x\n", status);
|
DbgPrint("FsFilter1!" __FUNCTION__ ": Registry filter unregistration failed with code:%08x\n", status);
|
||||||
|
|
||||||
|
DestroyExcludeListContext(g_excludeRegKeyContext);
|
||||||
|
DestroyExcludeListContext(g_excludeRegValueContext);
|
||||||
|
|
||||||
|
g_regFilterInited = FALSE;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@
|
|||||||
+ FS filter
|
+ FS filter
|
||||||
+ Reg filter
|
+ Reg filter
|
||||||
+ Реализовать RemoveAllExcludeListEntries
|
+ Реализовать RemoveAllExcludeListEntries
|
||||||
- Реализовать все ф-и Ps monitor
|
+ Реализовать все ф-и Ps monitor
|
||||||
- Добавить в библиотеку поддержку get\set state
|
+ Добавить в библиотеку поддержку get\set state
|
||||||
- Решить проблему с protected (возможно разрешить создавать такие процессы только из protected\system)
|
+ Решить проблему с protected (возможно разрешить создавать такие процессы только из protected\system)
|
||||||
- Реализовать IOCTL протокол управления
|
- Реализовать IOCTL протокол управления
|
||||||
+ Реализовать usermode библиотеку для работы с IOCTL API
|
+ Реализовать usermode библиотеку для работы с IOCTL API
|
||||||
- Реализовать программу управления драйвером, средствами IOCTL API
|
- Реализовать программу управления драйвером, средствами IOCTL API
|
||||||
|
@ -39,13 +39,13 @@ CONST PWCHAR g_excludeRegValues[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CONST PWCHAR g_protectProcesses[] = {
|
CONST PWCHAR g_protectProcesses[] = {
|
||||||
L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc.exe",
|
L"c:\\Windows\\System32\\calc.exe",
|
||||||
L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc2.exe",
|
L"c:\\Windows\\System32\\calc2.exe",
|
||||||
};
|
};
|
||||||
|
|
||||||
CONST PWCHAR g_excludeProcesses[] = {
|
CONST PWCHAR g_excludeProcesses[] = {
|
||||||
L"\\Device\\HarddiskVolume1\\Windows\\System32\\cmd.exe",
|
L"c:\\Windows\\System32\\cmd.exe",
|
||||||
L"\\Device\\HarddiskVolume1\\Windows\\System32\\cmd2.exe",
|
L"c:\\Windows\\System32\\cmd2.exe",
|
||||||
};
|
};
|
||||||
|
|
||||||
int wmain(int argc, wchar_t *argv[])
|
int wmain(int argc, wchar_t *argv[])
|
||||||
|
@ -400,7 +400,7 @@ void do_regmon_tests(HidContext context)
|
|||||||
hid_status = Hid_RemoveHiddenRegValue(context, objId[1]);
|
hid_status = Hid_RemoveHiddenRegValue(context, objId[1]);
|
||||||
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
{
|
{
|
||||||
wcout << L"Error, unhidden reg value hasn't been found, code: " << error_code << endl;
|
wcout << L"Error, unhidden reg value hasn't been found, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
throw exception();
|
throw exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,12 +440,195 @@ void do_regmon_tests(HidContext context)
|
|||||||
Hid_RemoveAllHiddenRegValues(context);
|
Hid_RemoveAllHiddenRegValues(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_psmon_tests(HidContext context)
|
void do_psmon_prot_tests(HidContext context)
|
||||||
|
{
|
||||||
|
HidStatus hid_status;
|
||||||
|
unsigned int error_code;
|
||||||
|
STARTUPINFOW si;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
wchar_t path[] = L"c:\\windows\\system32\\calc.exe";
|
||||||
|
HidObjId objId[3];
|
||||||
|
HANDLE hproc = 0;
|
||||||
|
HidActiveState state;
|
||||||
|
HidPsInheritTypes inheritType;
|
||||||
|
|
||||||
|
wcout << L"--------------------------------" << endl;
|
||||||
|
wcout << L"Process monitor prot tests result:" << endl;
|
||||||
|
wcout << L"--------------------------------" << endl;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
// test 1: create proc, protect, check, unprotect
|
||||||
|
|
||||||
|
wcout << L"Test 1: create process, protect, check, unprotect" << endl;
|
||||||
|
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
|
||||||
|
wcout << L"step" << 1 << endl;
|
||||||
|
|
||||||
|
hid_status = Hid_GetProtectedState(context, GetCurrentProcessId(), &state, &inheritType);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't get self state, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != HidActiveState::StateDisabled)
|
||||||
|
{
|
||||||
|
wcout << L"Error, state isn't StateDisabled, state: " << state << " " << inheritType << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 2 << endl;
|
||||||
|
hid_status = Hid_AttachProtectedState(context, GetCurrentProcessId(), HidPsInheritTypes::WithoutInherit);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't protect self image, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
hid_status = Hid_GetProtectedState(context, GetCurrentProcessId(), &state, &inheritType);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't get self status, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != HidActiveState::StateEnabled || inheritType != HidPsInheritTypes::WithoutInherit)
|
||||||
|
{
|
||||||
|
wcout << L"Error, state isn't StateEnabled, state: " << state << " " << inheritType << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 3 << endl;
|
||||||
|
hid_status = Hid_AddProtectedImage(context, path, HidPsInheritTypes::WithoutInherit, &objId[1]);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't protect image, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 3 << endl;
|
||||||
|
//hid_status = Hid_AttachProtectedState(context, 420, HidPsInheritTypes::WithoutInherit);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't protect csrss image, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wcout << L"step" << 4 << endl;
|
||||||
|
if (!CreateProcessW(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||||
|
{
|
||||||
|
error_code = GetLastError();
|
||||||
|
wcout << L"Error, CreateProcessW() failed with code: " << error_code << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 5 << endl;
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
|
hid_status = Hid_RemoveProtectedState(context, GetCurrentProcessId());
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't can't remove self protection, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 6 << endl;
|
||||||
|
hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
|
||||||
|
if (!hproc)
|
||||||
|
{
|
||||||
|
error_code = GetLastError();
|
||||||
|
wcout << L"Error, OpenProcess() failed with code: " << error_code << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
wcout << L"step" << 7 << endl;
|
||||||
|
if (VirtualAllocEx(hproc, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
|
||||||
|
{
|
||||||
|
wcout << L"Error, process protection doesn't work" << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hproc);
|
||||||
|
hproc = 0;
|
||||||
|
|
||||||
|
wcout << L"step" << 8 << endl;
|
||||||
|
hid_status = Hid_RemoveProtectedImage(context, objId[1]);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't remove protected rule, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
hid_status = Hid_RemoveProtectedState(context, pi.dwProcessId);
|
||||||
|
if (!HID_STATUS_SUCCESSFUL(hid_status))
|
||||||
|
{
|
||||||
|
wcout << L"Error, can't unprotect image, code: " << HID_STATUS_CODE(hid_status) << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
|
||||||
|
if (!hproc)
|
||||||
|
{
|
||||||
|
error_code = GetLastError();
|
||||||
|
wcout << L"Error, OpenProcess() failed with code " << error_code << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VirtualAllocEx(hproc, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
|
||||||
|
{
|
||||||
|
error_code = GetLastError();
|
||||||
|
wcout << L"Error, VirtualAllocEx() failed with code: " << error_code << endl;
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hproc);
|
||||||
|
hproc = 0;
|
||||||
|
|
||||||
|
wcout << L" successful!" << endl;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (exception&)
|
||||||
|
{
|
||||||
|
wcout << L" failed!" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hproc)
|
||||||
|
CloseHandle(hproc);
|
||||||
|
|
||||||
|
if (pi.hProcess)
|
||||||
|
{
|
||||||
|
CloseHandle(hproc);
|
||||||
|
TerminateProcess(pi.hProcess, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Hid_RemoveAllProtectedImages(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_psmon_excl_tests(HidContext context)
|
||||||
{
|
{
|
||||||
//HidStatus hid_status;
|
//HidStatus hid_status;
|
||||||
|
|
||||||
wcout << L"--------------------------------" << endl;
|
wcout << L"--------------------------------" << endl;
|
||||||
wcout << L"Process monitor tests result:" << endl;
|
wcout << L"Process monitor excl tests result:" << endl;
|
||||||
wcout << L"--------------------------------" << endl;
|
wcout << L"--------------------------------" << endl;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (exception&)
|
||||||
|
{
|
||||||
|
wcout << L" failed!" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t* argv[])
|
int wmain(int argc, wchar_t* argv[])
|
||||||
@ -464,7 +647,8 @@ int wmain(int argc, wchar_t* argv[])
|
|||||||
|
|
||||||
do_fsmon_tests(hid_context);
|
do_fsmon_tests(hid_context);
|
||||||
do_regmon_tests(hid_context);
|
do_regmon_tests(hid_context);
|
||||||
do_psmon_tests(hid_context);
|
do_psmon_prot_tests(hid_context);
|
||||||
|
do_psmon_excl_tests(hid_context);
|
||||||
|
|
||||||
//Hid_Destroy(hid_context);
|
//Hid_Destroy(hid_context);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user