6
0
mirror of https://github.com/JKornev/hidden synced 2024-06-24 07:58:04 +00:00

Multiple changes

- Fixed issue with signing Release driver builds
- Renamed all Nt* functions to Zw* (access denied fix, KTHREAD!PreviousMode)
- Added "apply to all processes" feature for adding exluded\protected images api
- Fixed sync issues for process table, sync primitives moved to external code
etc
This commit is contained in:
JKornev 2016-10-19 00:28:55 +03:00
parent 3e5e5e8679
commit 3851dcd17d
16 changed files with 309 additions and 94 deletions

@ -440,6 +440,16 @@
<UseLocalTime>true</UseLocalTime>
</Inf2Cat>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Inf2Cat>
<UseLocalTime>true</UseLocalTime>
</Inf2Cat>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Inf2Cat>
<UseLocalTime>true</UseLocalTime>
</Inf2Cat>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>

@ -192,10 +192,10 @@ NTSTATUS AddPsObject(PHid_AddPsObjectPacket Packet, USHORT Size, PULONGLONG ObjI
switch (Packet->objType)
{
case PsExcludedObject:
status = AddExcludedImage(&path, Packet->inheritType, ObjId);
status = AddExcludedImage(&path, Packet->inheritType, (Packet->applyForProcesses ? TRUE : FALSE), ObjId);
break;
case PsProtectedObject:
status = AddProtectedImage(&path, Packet->inheritType, ObjId);
status = AddProtectedImage(&path, Packet->inheritType, (Packet->applyForProcesses ? TRUE : FALSE), ObjId);
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", Packet->objType);

@ -60,7 +60,7 @@ typedef struct _Hid_AddPsObjectPacket {
unsigned short objType;
unsigned short dataSize;
unsigned short inheritType;
unsigned short reserved;
unsigned short applyForProcesses;
} Hid_AddPsObjectPacket, *PHid_AddPsObjectPacket;
typedef struct _Hid_GetPsObjectInfoPacket {

@ -106,7 +106,7 @@ FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation(
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
@ -137,7 +137,7 @@ FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation(
if (neededPrevent)
{
DbgPrint("FsFilter1!" __FUNCTION__ ": Create file\\dir operation canceled for: %wZ\n", &Data->Iopb->TargetFileObject->FileName);
DbgPrint("FsFilter1!" __FUNCTION__ ": Create file\\dir operation canceled for: %wZ, %d\n", &Data->Iopb->TargetFileObject->FileName, PsGetCurrentProcessId());
Data->IoStatus.Status = STATUS_NO_SUCH_FILE;
return FLT_PREOP_COMPLETE;
}

@ -9,7 +9,7 @@ NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS Class, PVOID* InfoBuffe
ULONG size = 0, written = 0;
// Query required size
status = NtQuerySystemInformation(Class, 0, 0, &size);
status = ZwQuerySystemInformation(Class, 0, 0, &size);
if (status != STATUS_INFO_LENGTH_MISMATCH)
return status;
@ -24,7 +24,7 @@ NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS Class, PVOID* InfoBuffe
if (!info)
break;
status = NtQuerySystemInformation(Class, info, size, &written);
status = ZwQuerySystemInformation(Class, info, size, &written);
}
if (!info)
@ -49,7 +49,7 @@ NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE Process, PVOID*
ULONG size = 0, written = 0;
// Query required size
status = NtQueryInformationProcess(Process, Class, 0, 0, &size);
status = ZwQueryInformationProcess(Process, Class, 0, 0, &size);
if (status != STATUS_INFO_LENGTH_MISMATCH)
return status;
@ -64,7 +64,7 @@ NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE Process, PVOID*
if (!info)
break;
status = NtQueryInformationProcess(Process, Class, info, size, &written);
status = ZwQueryInformationProcess(Process, Class, info, size, &written);
}
if (!info)

@ -34,14 +34,14 @@ typedef struct _SYSTEM_PROCESS_INFORMATION {
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSYSAPI NTSTATUS NTAPI NtQueryInformationProcess(
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,

@ -16,6 +16,8 @@ OB_CALLBACK_REGISTRATION g_regCallback;
PsRulesContext g_excludeProcessRules;
PsRulesContext g_protectProcessRules;
KSPIN_LOCK g_processTableLock;
typedef struct _ProcessListEntry {
LPCWSTR path;
ULONG inherit;
@ -43,32 +45,57 @@ WCHAR g_csrssPathBuffer[CSRSS_PAHT_BUFFER_SIZE];
BOOLEAN CheckProtectedOperation(HANDLE Source, HANDLE Destination)
{
ProcessTableEntry srcInfo, destInfo;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
if (Source == Destination)
return FALSE;
destInfo.processId = Destination;
if (!GetProcessInProcessTable(&destInfo))
srcInfo.processId = Source;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&srcInfo);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return FALSE;
srcInfo.processId = Source;
if (!GetProcessInProcessTable(&srcInfo))
destInfo.processId = Destination;
// Spinlock is locked once for both Get\Update process table functions
// because we want to prevent situations when another thread can change
// any state of process beetwen get and update functions on this place
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
if (!GetProcessInProcessTable(&destInfo))
{
KeReleaseInStackQueuedSpinLock(&lockHandle);
return FALSE;
}
// Not-inited process can open any process (parent, csrss, etc)
if (!destInfo.inited)
{
result = TRUE;
// 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);
result = FALSE;
}
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
DbgPrint("FsFilter1!" __FUNCTION__ ": can't update initial state for process: %d\n", destInfo.processId);
return FALSE;
}
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!destInfo.protected)
return FALSE;
@ -143,6 +170,8 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
{
ProcessTableEntry lookup;
ULONG inheritType;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
RtlZeroMemory(&lookup, sizeof(lookup));
@ -162,7 +191,12 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
else if (ParentId != 0)
{
lookup.processId = ParentId;
if (GetProcessInProcessTable(&lookup))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&lookup);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (result)
{
if (lookup.inheritExclusion == PsRuleTypeInherit)
{
@ -190,7 +224,12 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
else if (ParentId != 0)
{
lookup.processId = ParentId;
if (GetProcessInProcessTable(&lookup))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&lookup);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (result)
{
if (lookup.inheritProtection == PsRuleTypeInherit)
{
@ -209,6 +248,8 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
VOID CreateProcessNotifyCallback(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo)
{
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
UNREFERENCED_PARAMETER(Process);
@ -252,14 +293,22 @@ VOID CreateProcessNotifyCallback(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE
if (entry.protected)
DbgPrint("FsFilter1!" __FUNCTION__ ": protected process:%d\n", ProcessId);
if (!AddProcessToProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = AddProcessToProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
DbgPrint("FsFilter1!" __FUNCTION__ ": can't add process(pid:%d) to process table\n", ProcessId);
ExFreePool(normalized.Buffer);
}
else
{
if (!RemoveProcessFromProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = RemoveProcessFromProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
DbgPrint("FsFilter1!" __FUNCTION__ ": can't remove process(pid:%d) from process table\n", ProcessId);
}
@ -268,9 +317,16 @@ VOID CreateProcessNotifyCallback(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE
BOOLEAN IsProcessExcluded(HANDLE ProcessId)
{
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return FALSE;
return entry.excluded;
@ -279,9 +335,16 @@ BOOLEAN IsProcessExcluded(HANDLE ProcessId)
BOOLEAN IsProcessProtected(HANDLE ProcessId)
{
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return FALSE;
return entry.protected;
@ -378,6 +441,10 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
AddRuleToPsRuleList(g_protectProcessRules, &normalized, g_protectProcesses[i].inherit, &ruleId);
}
// Process table
KeInitializeSpinLock(&g_processTableLock);
status = InitializeProcessTable(CheckProcessFlags);
if (!NT_SUCCESS(status))
{
@ -432,6 +499,8 @@ NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject)
NTSTATUS DestroyPsMonitor()
{
KLOCK_QUEUE_HANDLE lockHandle;
if (!g_psMonitorInited)
return STATUS_ALREADY_DISCONNECTED;
@ -446,13 +515,112 @@ NTSTATUS DestroyPsMonitor()
DestroyPsRuleListContext(g_excludeProcessRules);
DestroyPsRuleListContext(g_protectProcessRules);
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
DestroyProcessTable();
KeReleaseInStackQueuedSpinLock(&lockHandle);
g_psMonitorInited = FALSE;
return STATUS_SUCCESS;
}
NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLONG ObjId)
NTSTATUS SetStateForProcessesByImage(PCUNICODE_STRING ImagePath, BOOLEAN Excluded, BOOLEAN Protected)
{
PSYSTEM_PROCESS_INFORMATION processInfo = NULL, first;
SIZE_T size = 0, offset;
NTSTATUS status;
status = QuerySystemInformation(SystemProcessInformation, &processInfo, &size);
if (!NT_SUCCESS(status))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": query system information(pslist) failed with code:%08x\n", status);
return status;
}
offset = 0;
first = processInfo;
do
{
HANDLE hProcess;
CLIENT_ID clientId;
OBJECT_ATTRIBUTES attribs;
PUNICODE_STRING procName;
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
processInfo = (PSYSTEM_PROCESS_INFORMATION)((SIZE_T)processInfo + offset);
if (processInfo->ProcessId == 0)
{
offset = processInfo->NextEntryOffset;
continue;
}
InitializeObjectAttributes(&attribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
clientId.UniqueProcess = processInfo->ProcessId;
clientId.UniqueThread = 0;
status = ZwOpenProcess(&hProcess, 0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, &attribs, &clientId);
if (!NT_SUCCESS(status))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": can't open process (pid:%d) failed with code:%08x\n", processInfo->ProcessId, status);
offset = processInfo->NextEntryOffset;
continue;
}
status = QueryProcessInformation(ProcessImageFileName, hProcess, &procName, &size);
ZwClose(hProcess);
if (!NT_SUCCESS(status))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": query process information(pid:%d) failed with code:%08x\n", processInfo->ProcessId, status);
offset = processInfo->NextEntryOffset;
continue;
}
entry.processId = processInfo->ProcessId;
if (RtlCompareUnicodeString(procName, ImagePath, TRUE) == 0)
{
BOOLEAN result = TRUE;
// Spinlock is locked once for both Get\Update process table functions
// because we want to prevent situations when another thread can change
// any state of process beetwen get and update functions on this place
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
if (GetProcessInProcessTable(&entry))
{
if (Excluded)
{
entry.excluded = TRUE;
entry.inheritExclusion = PsRuleTypeWithoutInherit;
}
if (Protected)
{
entry.protected = TRUE;
entry.inheritProtection = PsRuleTypeWithoutInherit;
}
if (!UpdateProcessInProcessTable(&entry))
result = FALSE;
}
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
DbgPrint("FsFilter1!" __FUNCTION__ ": can't update process %d\n", processInfo->ProcessId);
}
FreeInformation(procName);
offset = processInfo->NextEntryOffset;
} while (offset);
FreeInformation(first);
return STATUS_SUCCESS;
}
NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId)
{
const USHORT maxBufSize = ImagePath->Length + NORMALIZE_INCREAMENT;
UNICODE_STRING normalized;
@ -479,6 +647,9 @@ NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGL
DbgPrint("FsFilter1!" __FUNCTION__ ": protect image: %wZ\n", &normalized);
status = AddRuleToPsRuleList(g_protectProcessRules, &normalized, InheritType, ObjId);
if (ApplyForProcesses)
SetStateForProcessesByImage(&normalized, FALSE, TRUE);
ExFreePool(normalized.Buffer);
return status;
@ -487,9 +658,16 @@ NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGL
NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable)
{
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
*Enable = entry.protected;
@ -502,9 +680,16 @@ NTSTATUS SetProtectedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN E
{
NTSTATUS status = STATUS_SUCCESS;
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
if (Enable)
@ -517,7 +702,11 @@ NTSTATUS SetProtectedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN E
entry.protected = FALSE;
}
if (!UpdateProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = UpdateProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
return status;
@ -533,7 +722,7 @@ NTSTATUS RemoveAllProtectedImages()
return RemoveAllRulesFromPsRuleList(g_protectProcessRules);
}
NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLONG ObjId)
NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId)
{
const USHORT maxBufSize = ImagePath->Length + NORMALIZE_INCREAMENT;
UNICODE_STRING normalized;
@ -560,6 +749,9 @@ NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLO
DbgPrint("FsFilter1!" __FUNCTION__ ": exclude image: %wZ\n", &normalized);
status = AddRuleToPsRuleList(g_excludeProcessRules, &normalized, InheritType, ObjId);
if (ApplyForProcesses)
SetStateForProcessesByImage(&normalized, TRUE, FALSE);
ExFreePool(normalized.Buffer);
return status;
@ -568,9 +760,16 @@ NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLO
NTSTATUS GetExcludedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable)
{
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
*Enable = entry.excluded;
@ -583,9 +782,16 @@ NTSTATUS SetExcludedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN En
{
NTSTATUS status = STATUS_SUCCESS;
ProcessTableEntry entry;
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
entry.processId = ProcessId;
if (!GetProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = GetProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
if (Enable)
@ -598,7 +804,11 @@ NTSTATUS SetExcludedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN En
entry.excluded = FALSE;
}
if (!UpdateProcessInProcessTable(&entry))
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = UpdateProcessInProcessTable(&entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (!result)
return STATUS_NOT_FOUND;
return status;

@ -13,13 +13,13 @@ NTSTATUS DestroyPsMonitor();
BOOLEAN IsProcessExcluded(HANDLE ProcessId);
BOOLEAN IsProcessProtected(HANDLE ProcessId);
NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLONG ObjId);
NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId);
NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable);
NTSTATUS SetProtectedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable);
NTSTATUS RemoveProtectedImage(ULONGLONG ObjId);
NTSTATUS RemoveAllProtectedImages();
NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, PULONGLONG ObjId);
NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId);
NTSTATUS GetExcludedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable);
NTSTATUS SetExcludedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable);
NTSTATUS RemoveExcludedImage(ULONGLONG ObjId);

@ -4,7 +4,6 @@
#define PSTREE_ALLOC_TAG 'rTsP'
RTL_AVL_TABLE g_processTable;
KSPIN_LOCK g_processTableLock;
RTL_GENERIC_COMPARE_RESULTS CompareProcessTableEntry(struct _RTL_AVL_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct)
{
@ -38,15 +37,9 @@ VOID FreeProcessTableEntry(struct _RTL_AVL_TABLE *Table, PVOID Buffer)
BOOLEAN AddProcessToProcessTable(PProcessTableEntry entry)
{
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result = FALSE;
PVOID buf;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
buf = RtlInsertElementGenericTableAvl(&g_processTable, entry, sizeof(ProcessTableEntry), &result);
KeReleaseInStackQueuedSpinLock(&lockHandle);
if (buf == NULL)
if (RtlInsertElementGenericTableAvl(&g_processTable, entry, sizeof(ProcessTableEntry), &result) == NULL)
return FALSE;
return result;
@ -54,46 +47,29 @@ BOOLEAN AddProcessToProcessTable(PProcessTableEntry entry)
BOOLEAN RemoveProcessFromProcessTable(PProcessTableEntry entry)
{
KLOCK_QUEUE_HANDLE lockHandle;
BOOLEAN result;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
result = RtlDeleteElementGenericTableAvl(&g_processTable, entry);
KeReleaseInStackQueuedSpinLock(&lockHandle);
return result;
return RtlDeleteElementGenericTableAvl(&g_processTable, entry);
}
BOOLEAN GetProcessInProcessTable(PProcessTableEntry entry)
{
KLOCK_QUEUE_HANDLE lockHandle;
PProcessTableEntry entry2;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
entry2 = (PProcessTableEntry)RtlLookupElementGenericTableAvl(&g_processTable, entry);
if (entry2)
RtlCopyMemory(entry, entry2, sizeof(ProcessTableEntry));
KeReleaseInStackQueuedSpinLock(&lockHandle);
return (entry2 ? TRUE : FALSE);
}
BOOLEAN UpdateProcessInProcessTable(PProcessTableEntry entry)
{
KLOCK_QUEUE_HANDLE lockHandle;
PProcessTableEntry entry2;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
entry2 = (PProcessTableEntry)RtlLookupElementGenericTableAvl(&g_processTable, entry);
if (entry2)
RtlCopyMemory(entry2, entry, sizeof(ProcessTableEntry));
KeReleaseInStackQueuedSpinLock(&lockHandle);
return (entry2 ? TRUE : FALSE);
}
@ -107,7 +83,6 @@ NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEnt
// Init process table
KeInitializeSpinLock(&g_processTableLock);
RtlInitializeGenericTableAvl(&g_processTable, CompareProcessTableEntry, AllocateProcessTableEntry, FreeProcessTableEntry, NULL);
// We should query processes information for creation process table for existing processes
@ -144,7 +119,7 @@ NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEnt
clientId.UniqueProcess = processInfo->ProcessId;
clientId.UniqueThread = 0;
status = NtOpenProcess(&hProcess, 0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, &attribs, &clientId);
status = ZwOpenProcess(&hProcess, 0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, &attribs, &clientId);
if (!NT_SUCCESS(status))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": can't open process (pid:%d) failed with code:%08x\n", processInfo->ProcessId, status);
@ -195,12 +170,9 @@ NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEnt
VOID DestroyProcessTable()
{
KLOCK_QUEUE_HANDLE lockHandle;
PProcessTableEntry entry;
PVOID restartKey = NULL;
KeAcquireInStackQueuedSpinLock(&g_processTableLock, &lockHandle);
for (entry = RtlEnumerateGenericTableWithoutSplayingAvl(&g_processTable, &restartKey);
entry != NULL;
entry = RtlEnumerateGenericTableWithoutSplayingAvl(&g_processTable, &restartKey))
@ -210,6 +182,4 @@ VOID DestroyProcessTable()
restartKey = NULL; // reset enum
}
KeReleaseInStackQueuedSpinLock(&lockHandle);
}

@ -19,6 +19,12 @@ typedef struct _ProcessTableEntry {
NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEntry, PCUNICODE_STRING, HANDLE));
VOID DestroyProcessTable();
// Important notice:
// Keep in mind that internal sync mechanisms removed from functions below (including DestroyProcessTable)
// because in some situations we need to perform two operation under one lock, for instance we should
// perform GetProcessInProcessTable and UpdateProcessInProcessTable under one lock. So in this case all
// functions, excluding InitializeProcessTable, should be synced manualy from external code
BOOLEAN AddProcessToProcessTable(PProcessTableEntry entry);
BOOLEAN RemoveProcessFromProcessTable(PProcessTableEntry entry);
BOOLEAN GetProcessInProcessTable(PProcessTableEntry entry);

@ -114,7 +114,7 @@ NTSTATUS RegPreCreateKey(PVOID context, PREG_PRE_CREATE_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -135,7 +135,7 @@ NTSTATUS RegPreCreateKeyEx(PVOID context, PREG_CREATE_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -154,7 +154,7 @@ NTSTATUS RegPreOpenKey(PVOID context, PREG_PRE_OPEN_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -175,7 +175,7 @@ NTSTATUS RegPreOpenKeyEx(PVOID context, PREG_OPEN_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -228,7 +228,7 @@ NTSTATUS RegPostEnumKey(PVOID context, PREG_POST_OPERATION_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -326,7 +326,7 @@ NTSTATUS RegPostEnumValue(PVOID context, PREG_POST_OPERATION_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -393,7 +393,7 @@ NTSTATUS RegPreSetValue(PVOID context, PREG_SET_VALUE_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -424,7 +424,7 @@ NTSTATUS RegPreDeleteValue(PVOID context, PREG_DELETE_VALUE_KEY_INFORMATION info
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -455,7 +455,7 @@ NTSTATUS RegPreQueryValue(PVOID context, PREG_QUERY_VALUE_KEY_INFORMATION info)
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}
@ -486,7 +486,7 @@ NTSTATUS RegPreQueryMultipleValue(PVOID context, PREG_QUERY_MULTIPLE_VALUE_KEY_I
if (IsProcessExcluded(PsGetCurrentProcessId()))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
//DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!! process excluded %d\n", PsGetCurrentProcessId());
return STATUS_SUCCESS;
}

@ -41,8 +41,10 @@
+ Реализовать IOCTL протокол управления
+ Реализовать usermode библиотеку для работы с IOCTL API
+ Слинковать с IOCTL API lib
+ Добавить поддержку флага автоприсвоение состояния существующим процессам для Hid_AddExcludedImage\Hid_AddProtectedImage
- Реализовать HiddenCLI
+ Портировать драйвер под архитектуру x64
- Портировать под версии Windows 8, 8.1, 10
+ Залить проект на Git
+ Переименовать проект драйвера в Hidden
+ Привести в порядок все версии билда Release, Debug, ...

@ -10,18 +10,18 @@ CONST PWCHAR g_excludeFiles[] = {
// L"c:\\Windows\\System32\\calc.exe",
// L"c:\\test.txt",
// L"c:\\abcd\\test.txt",
L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc.exe",
//L"\\Device\\HarddiskVolume1\\Windows\\System32\\calc.exe",
L"\\??\\C:\\test.txt",
L"\\??\\C:\\abcd\\test.txt",
//L"c:\\Program Files\\VMware",
};
CONST PWCHAR g_excludeDirs[] = {
// L"\\Device\\HarddiskVolume1\\abc",
// L"\\Device\\HarddiskVolume1\\abcd\\abc",
// L"\\Device\\HarddiskVolume1\\New folder",
L"\\Device\\HarddiskVolume1\\abc",
L"\\??\\C:\\abcd\\abc",
L"\\??\\C:\\New folder",
//L"\\Device\\HarddiskVolume1\\abc",
//L"\\??\\C:\\abcd\\abc",
L"c:\\Program Files\\VMware",
};
CONST PWCHAR g_excludeRegKeys[] = {
@ -44,8 +44,20 @@ CONST PWCHAR g_protectProcesses[] = {
};
CONST PWCHAR g_excludeProcesses[] = {
L"c:\\Windows\\System32\\cmd.exe",
L"c:\\Windows\\System32\\cmd2.exe",
L"C:\\Windows\\System32\\Services.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\vmtoolsd.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\TPAutoConnSvc.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\rpctool.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\rvmSetup.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\TPAutoConnect.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\TPVCGateway.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\VMwareHgfsClient.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\VMwareHostOpen.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\VMwareResolutionSet.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\VMwareToolboxCmd.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\VMwareXferlogs.exe",
L"C:\\Program Files\\VMware\\VMware Tools\\zip.exe",
L"c:\\Windows\\System32\\vssvc.exe",
};
int wmain(int argc, wchar_t *argv[])
@ -108,7 +120,7 @@ int wmain(int argc, wchar_t *argv[])
for (int i = 0; i < count; i++)
{
HidObjId objId;
hid_status = Hid_AddExcludedImage(hid_context, g_excludeProcesses[i], WithoutInherit, &objId);
hid_status = Hid_AddExcludedImage(hid_context, g_excludeProcesses[i], WithoutInherit, TRUE, &objId);
if (!HID_STATUS_SUCCESSFUL(hid_status))
cout << "Error, Hid_AddExcludedImage failed with code: " << HID_STATUS_CODE(hid_status) << endl;
}
@ -118,11 +130,15 @@ int wmain(int argc, wchar_t *argv[])
for (int i = 0; i < count; i++)
{
HidObjId objId;
hid_status = Hid_AddProtectedImage(hid_context, g_protectProcesses[i], WithoutInherit, &objId);
hid_status = Hid_AddProtectedImage(hid_context, g_protectProcesses[i], WithoutInherit, TRUE, &objId);
if (!HID_STATUS_SUCCESSFUL(hid_status))
cout << "Error, Hid_AddProtectedImage failed with code: " << HID_STATUS_CODE(hid_status) << endl;
}
//hid_status = Hid_AttachExcludedState(hid_context, 528, WithoutInherit);
//if (!HID_STATUS_SUCCESSFUL(hid_status))
// cout << "Error, Hid_AttachExcludedState failed with code: " << HID_STATUS_CODE(hid_status) << endl;
Hid_Destroy(hid_context);
cout << "Completed!" << endl;

@ -338,7 +338,7 @@ HidStatus SendIoctl_UnhideAllObjectsPacket(PHidContextInternal context, unsigned
return HID_SET_STATUS(TRUE, 0);
}
HidStatus SendIoctl_AddPsObjectPacket(PHidContextInternal context, const wchar_t* path, unsigned short type, HidPsInheritTypes inheritType, HidObjId* objId)
HidStatus SendIoctl_AddPsObjectPacket(PHidContextInternal context, const wchar_t* path, unsigned short type, HidPsInheritTypes inheritType, bool applyForProcess, HidObjId* objId)
{
PHid_AddPsObjectPacket hide;
Hid_StatusPacket result;
@ -357,6 +357,7 @@ HidStatus SendIoctl_AddPsObjectPacket(PHidContextInternal context, const wchar_t
hide->dataSize = (unsigned short)total;
hide->objType = type;
hide->inheritType = inheritType;
hide->applyForProcesses = applyForProcess;
memcpy((char*)hide + sizeof(Hid_AddPsObjectPacket), path, total);
@ -613,7 +614,7 @@ HidStatus _API Hid_RemoveAllHiddenDirs(HidContext context)
// Process exclude interface
HidStatus _API Hid_AddExcludedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, HidObjId* objId)
HidStatus _API Hid_AddExcludedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, bool applyForProcess, HidObjId* objId)
{
HidStatus status;
wchar_t* normalized;
@ -622,7 +623,7 @@ HidStatus _API Hid_AddExcludedImage(HidContext context, const wchar_t* imagePath
if (!HID_STATUS_SUCCESSFUL(status))
return status;
status = SendIoctl_AddPsObjectPacket((PHidContextInternal)context, normalized, PsExcludedObject, inheritType, objId);
status = SendIoctl_AddPsObjectPacket((PHidContextInternal)context, normalized, PsExcludedObject, inheritType, applyForProcess, objId);
FreeNormalizedPath(normalized);
return status;
@ -655,7 +656,7 @@ HidStatus _API Hid_RemoveExcludedState(HidContext context, HidProcId procId)
// Process protect interface
HidStatus _API Hid_AddProtectedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, HidObjId* objId)
HidStatus _API Hid_AddProtectedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, bool applyForProcess, HidObjId* objId)
{
HidStatus status;
wchar_t* normalized;
@ -664,7 +665,7 @@ HidStatus _API Hid_AddProtectedImage(HidContext context, const wchar_t* imagePat
if (!HID_STATUS_SUCCESSFUL(status))
return status;
status = SendIoctl_AddPsObjectPacket((PHidContextInternal)context, normalized, PsProtectedObject, inheritType, objId);
status = SendIoctl_AddPsObjectPacket((PHidContextInternal)context, normalized, PsProtectedObject, inheritType, applyForProcess, objId);
FreeNormalizedPath(normalized);
return status;

@ -65,14 +65,14 @@ HidStatus _API Hid_RemoveAllHiddenDirs(HidContext context);
// Ps
HidStatus _API Hid_AddExcludedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, HidObjId* objId);
HidStatus _API Hid_AddExcludedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, bool applyForProcess, HidObjId* objId);
HidStatus _API Hid_RemoveExcludedImage(HidContext context, HidObjId objId);
HidStatus _API Hid_RemoveAllExcludedImages(HidContext context);
HidStatus _API Hid_GetExcludedState(HidContext context, HidProcId procId, HidActiveState* state, HidPsInheritTypes* inheritType);
HidStatus _API Hid_AttachExcludedState(HidContext context, HidProcId procId, HidPsInheritTypes inheritType);
HidStatus _API Hid_RemoveExcludedState(HidContext context, HidProcId procId);
HidStatus _API Hid_AddProtectedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, HidObjId* objId);
HidStatus _API Hid_AddProtectedImage(HidContext context, const wchar_t* imagePath, HidPsInheritTypes inheritType, bool applyForProcess, HidObjId* objId);
HidStatus _API Hid_RemoveProtectedImage(HidContext context, HidObjId objId);
HidStatus _API Hid_RemoveAllProtectedImages(HidContext context);
HidStatus _API Hid_GetProtectedState(HidContext context, HidProcId procId, HidActiveState* state, HidPsInheritTypes* inheritType);

@ -524,7 +524,7 @@ void do_psmon_prot_tests(HidContext context)
wcout << L"Test 2: create process, protect, check, unprotect" << endl;
hid_status = Hid_AddProtectedImage(context, path, HidPsInheritTypes::WithoutInherit, &objId[1]);
hid_status = Hid_AddProtectedImage(context, path, HidPsInheritTypes::WithoutInherit, FALSE, &objId[1]);
if (!HID_STATUS_SUCCESSFUL(hid_status))
{
wcout << L"Error, can't protect image, code: " << HID_STATUS_CODE(hid_status) << endl;
@ -786,7 +786,7 @@ void do_psmon_excl_tests(HidContext context)
CloseHandle(pi.hProcess);
memset(&pi, 0, sizeof(pi));
hid_status = Hid_AddExcludedImage(context, L"c:\\windows\\system32\\cmd.exe", HidPsInheritTypes::InheritOnce, &objId[1]);
hid_status = Hid_AddExcludedImage(context, L"c:\\windows\\system32\\cmd.exe", HidPsInheritTypes::InheritOnce, FALSE, &objId[1]);
if (!HID_STATUS_SUCCESSFUL(hid_status))
{
wcout << L"Error, can't add excluded image, code: " << HID_STATUS_CODE(hid_status) << endl;