mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-23 20:05:26 +00:00
696 lines
18 KiB
C
696 lines
18 KiB
C
|
#include "stdafx.h"
|
||
|
|
||
|
// defined in driver.cpp
|
||
|
extern UNICODE_STRING m_RegistryPath;
|
||
|
extern KMUTEX m_CommonMutex;
|
||
|
|
||
|
BOOLEAN g_RuleInited = FALSE;
|
||
|
ERESOURCE g_RuleResource;
|
||
|
LIST_ENTRY g_DenyRuleList;
|
||
|
LIST_ENTRY g_AllowRuleList;
|
||
|
LIST_ENTRY g_DbgcbRuleList;
|
||
|
|
||
|
FORCEINLINE
|
||
|
VOID
|
||
|
RuleLock(
|
||
|
__in BOOLEAN Exclusive
|
||
|
)
|
||
|
{
|
||
|
KeEnterCriticalRegion();
|
||
|
if (Exclusive)
|
||
|
ExAcquireResourceExclusiveLite(&g_RuleResource, TRUE);
|
||
|
else
|
||
|
ExAcquireResourceSharedLite(&g_RuleResource, TRUE);
|
||
|
}
|
||
|
|
||
|
FORCEINLINE
|
||
|
VOID
|
||
|
RuleUnlock()
|
||
|
{
|
||
|
ExReleaseResourceLite(&g_RuleResource);
|
||
|
KeLeaveCriticalRegion();
|
||
|
}
|
||
|
|
||
|
NTSTATUS FltInitRuleList()
|
||
|
{
|
||
|
NTSTATUS Status = 0;
|
||
|
|
||
|
InitializeListHead( &g_DenyRuleList );
|
||
|
InitializeListHead( &g_AllowRuleList );
|
||
|
InitializeListHead( &g_DbgcbRuleList );
|
||
|
|
||
|
Status = ExInitializeResourceLite( &g_RuleResource );
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
return Status;
|
||
|
|
||
|
g_RuleInited = TRUE;
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
VOID FltUnInitRuleList()
|
||
|
{
|
||
|
if(!g_RuleInited)
|
||
|
return;
|
||
|
|
||
|
FltFlushAllList();
|
||
|
|
||
|
g_RuleInited = FALSE;
|
||
|
|
||
|
ExDeleteResourceLite(&g_RuleResource);
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
wchar_t xchrlower_w(wchar_t chr)
|
||
|
{
|
||
|
if ((chr >= 'A') && (chr <= 'Z'))
|
||
|
{
|
||
|
return chr + ('a'-'A');
|
||
|
}
|
||
|
|
||
|
return chr;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
BOOLEAN EqualUnicodeString_r(PUNICODE_STRING Str1, PUNICODE_STRING Str2, BOOLEAN CaseInSensitive)
|
||
|
{
|
||
|
USHORT CmpLen = min(Str1->Length, Str2->Length) / sizeof(WCHAR);
|
||
|
USHORT i = 0;
|
||
|
for ( i = 1; i < CmpLen; i++)
|
||
|
{
|
||
|
WCHAR Chr1 = Str1->Buffer[Str1->Length / sizeof(WCHAR) - i],
|
||
|
Chr2 = Str2->Buffer[Str2->Length / sizeof(WCHAR) - i];
|
||
|
|
||
|
if (CaseInSensitive)
|
||
|
{
|
||
|
Chr1 = xchrlower_w(Chr1);
|
||
|
Chr2 = xchrlower_w(Chr2);
|
||
|
}
|
||
|
|
||
|
if (Chr1 != Chr2)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
PIOCTL_FILTER FltAdd(PIOCTL_FILTER f, PLIST_ENTRY ListEntry, ULONG KdCommandLength)
|
||
|
{
|
||
|
ULONG Length = 0;
|
||
|
PIOCTL_FILTER f_entry = NULL;
|
||
|
|
||
|
if(!g_RuleInited || !ListEntry || !f)
|
||
|
return NULL;
|
||
|
|
||
|
Length = KdCommandLength + sizeof(IOCTL_FILTER);
|
||
|
f_entry = (PIOCTL_FILTER)ExAllocatePool(NonPagedPool, Length);
|
||
|
if (f_entry)
|
||
|
{
|
||
|
RtlZeroMemory(f_entry, Length);
|
||
|
RtlCopyMemory(f_entry, f, sizeof(IOCTL_FILTER));
|
||
|
|
||
|
InsertHeadList(ListEntry, &f_entry->List);
|
||
|
|
||
|
return f_entry;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, "ExAllocatePool() fails\n");
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
VOID DeferenceRuleCount(PIOCTL_FILTER Item)
|
||
|
{
|
||
|
if(!g_RuleInited)
|
||
|
return;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
Item->ReferenceCount--;
|
||
|
RuleUnlock();
|
||
|
}
|
||
|
|
||
|
PIOCTL_FILTER FltAddDenyRule(PIOCTL_FILTER f, ULONG KdCommandLength)
|
||
|
{
|
||
|
PIOCTL_FILTER Item = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return NULL;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
Item = FltAdd(f, &g_DenyRuleList, KdCommandLength);
|
||
|
Item->ReferenceCount +=1 ;
|
||
|
RuleUnlock();
|
||
|
|
||
|
return Item;
|
||
|
}
|
||
|
|
||
|
PIOCTL_FILTER FltAddAllowRule(PIOCTL_FILTER f, ULONG KdCommandLength)
|
||
|
{
|
||
|
PIOCTL_FILTER Item = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return NULL;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
Item = FltAdd(f, &g_AllowRuleList, KdCommandLength);
|
||
|
Item->ReferenceCount +=1 ;
|
||
|
RuleUnlock();
|
||
|
|
||
|
return Item;
|
||
|
}
|
||
|
|
||
|
PIOCTL_FILTER FltAddDbgcbRule(PIOCTL_FILTER f, ULONG KdCommandLength)
|
||
|
{
|
||
|
PIOCTL_FILTER Item = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return NULL;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
Item = FltAdd(f, &g_DbgcbRuleList, KdCommandLength);
|
||
|
Item->ReferenceCount +=1 ;
|
||
|
RuleUnlock();
|
||
|
|
||
|
return Item;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
void FltFlushList(PLIST_ENTRY ListEntryHead)
|
||
|
{
|
||
|
PLIST_ENTRY ListEntry = NULL;
|
||
|
PLIST_ENTRY ListRemove = NULL;
|
||
|
PIOCTL_FILTER RuleItem = NULL;
|
||
|
|
||
|
if(!g_RuleInited || !ListEntryHead)
|
||
|
return;
|
||
|
|
||
|
ListEntry = ListEntryHead->Flink;
|
||
|
while(ListEntry != ListEntryHead)
|
||
|
{
|
||
|
RuleItem = CONTAINING_RECORD(ListEntry, IOCTL_FILTER, List);
|
||
|
|
||
|
if(RuleItem->ReferenceCount != 0)
|
||
|
{
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (RuleItem->Type == FLT_DEVICE_NAME ||
|
||
|
RuleItem->Type == FLT_DRIVER_NAME ||
|
||
|
RuleItem->Type == FLT_PROCESS_PATH)
|
||
|
{
|
||
|
RtlFreeUnicodeString(&RuleItem->usName);
|
||
|
}
|
||
|
|
||
|
ListRemove = ListEntry;
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
RemoveEntryList(ListRemove);
|
||
|
|
||
|
ExFreePool(RuleItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void FltFlushAllList()
|
||
|
{
|
||
|
if(!g_RuleInited)
|
||
|
return ;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
FltFlushList(&g_DenyRuleList);
|
||
|
FltFlushList(&g_AllowRuleList);
|
||
|
FltFlushList(&g_DbgcbRuleList);
|
||
|
RuleUnlock();
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
PIOCTL_FILTER FltMatch(
|
||
|
PLIST_ENTRY ListEntryHead,
|
||
|
PUNICODE_STRING fDeviceName,
|
||
|
PUNICODE_STRING fDriverName,
|
||
|
ULONG IoControlCode,
|
||
|
PUNICODE_STRING fProcessName)
|
||
|
{
|
||
|
PIOCTL_FILTER ret = NULL;
|
||
|
PIOCTL_FILTER RuleItem = NULL;
|
||
|
PLIST_ENTRY ListEntry = NULL;
|
||
|
|
||
|
if(!ListEntryHead)
|
||
|
return NULL;
|
||
|
|
||
|
// match parameters by filter list
|
||
|
ListEntry = ListEntryHead->Flink;
|
||
|
while (ListEntry != ListEntryHead)
|
||
|
{
|
||
|
RuleItem = CONTAINING_RECORD(ListEntry, IOCTL_FILTER, List);
|
||
|
|
||
|
if (RuleItem->bDbgcbAction)
|
||
|
{
|
||
|
// skip entries with debugger commands
|
||
|
goto next;
|
||
|
}
|
||
|
|
||
|
if (RuleItem->Type == FLT_DEVICE_NAME)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fDeviceName, TRUE))
|
||
|
{
|
||
|
ret = RuleItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_DRIVER_NAME)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fDriverName, TRUE))
|
||
|
{
|
||
|
ret = RuleItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_IOCTL_CODE)
|
||
|
{
|
||
|
if (RuleItem->IoctlCode == IoControlCode)
|
||
|
{
|
||
|
ret = RuleItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_PROCESS_PATH)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fProcessName, TRUE))
|
||
|
{
|
||
|
ret = RuleItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
next:
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
BOOLEAN FltMatchDeny(
|
||
|
PUNICODE_STRING fDeviceName,
|
||
|
PUNICODE_STRING fDriverName,
|
||
|
ULONG IoControlCode,
|
||
|
PUNICODE_STRING fProcessName)
|
||
|
{
|
||
|
PIOCTL_FILTER Rule = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(FALSE);
|
||
|
Rule = FltMatch(&g_DenyRuleList, fDeviceName, fDriverName, IoControlCode, fProcessName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
if(Rule)
|
||
|
return TRUE;
|
||
|
else
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOLEAN FltMatchAllow(
|
||
|
PUNICODE_STRING fDeviceName,
|
||
|
PUNICODE_STRING fDriverName,
|
||
|
ULONG IoControlCode,
|
||
|
PUNICODE_STRING fProcessName)
|
||
|
{
|
||
|
PIOCTL_FILTER Rule = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(FALSE);
|
||
|
|
||
|
if(IsListEmpty(&g_AllowRuleList))
|
||
|
return TRUE;
|
||
|
|
||
|
Rule = FltMatch(&g_AllowRuleList, fDeviceName, fDriverName, IoControlCode, fProcessName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
if(Rule)
|
||
|
return TRUE;
|
||
|
else
|
||
|
return FALSE;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
char *FltGetKdCommand(
|
||
|
PUNICODE_STRING fDeviceName,
|
||
|
PUNICODE_STRING fDriverName,
|
||
|
ULONG IoControlCode,
|
||
|
PUNICODE_STRING fProcessName)
|
||
|
{
|
||
|
char *lpszCmd = NULL;
|
||
|
PLIST_ENTRY ListEntry = NULL;
|
||
|
PIOCTL_FILTER RuleItem = NULL;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return NULL;
|
||
|
|
||
|
RuleLock(FALSE);
|
||
|
// match parameters by filter list
|
||
|
ListEntry = g_DbgcbRuleList.Flink;
|
||
|
while (ListEntry != &g_DbgcbRuleList)
|
||
|
{
|
||
|
RuleItem = CONTAINING_RECORD(ListEntry, IOCTL_FILTER, List);
|
||
|
if (!RuleItem->bDbgcbAction)
|
||
|
{
|
||
|
// skip entries with debugger commands
|
||
|
goto next;
|
||
|
}
|
||
|
|
||
|
if (RuleItem->Type == FLT_DEVICE_NAME)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fDeviceName, TRUE))
|
||
|
{
|
||
|
lpszCmd = RuleItem->szKdCommand;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_DRIVER_NAME)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fDriverName, TRUE))
|
||
|
{
|
||
|
lpszCmd = RuleItem->szKdCommand;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_IOCTL_CODE)
|
||
|
{
|
||
|
if (RuleItem->IoctlCode == IoControlCode)
|
||
|
{
|
||
|
lpszCmd = RuleItem->szKdCommand;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (RuleItem->Type == FLT_PROCESS_PATH)
|
||
|
{
|
||
|
if (EqualUnicodeString_r(&RuleItem->usName, fProcessName, TRUE))
|
||
|
{
|
||
|
lpszCmd = RuleItem->szKdCommand;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
next:
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
}
|
||
|
RuleUnlock();
|
||
|
|
||
|
return lpszCmd;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
BOOLEAN FltIsMatchedRequest(
|
||
|
PUNICODE_STRING fDeviceName,
|
||
|
PUNICODE_STRING fDriverName,
|
||
|
ULONG IoControlCode,
|
||
|
PUNICODE_STRING fProcessName)
|
||
|
{
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
// match process by allow/deny list
|
||
|
if (FltMatchAllow(fDeviceName, fDriverName, IoControlCode, fProcessName) &&
|
||
|
FltMatchDeny(fDeviceName, fDriverName, IoControlCode, fProcessName) == FALSE)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
BOOLEAN SaveRules(PLIST_ENTRY ListEntryHead, HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
ULONG BuffSize = 0, RulesToSerialize = 0;
|
||
|
PLIST_ENTRY ListEntry = NULL;
|
||
|
PIOCTL_FILTER RuleItem = NULL;
|
||
|
|
||
|
if(!ListEntryHead)
|
||
|
return FALSE;
|
||
|
|
||
|
// calculate reqired buffer size
|
||
|
ListEntry = ListEntryHead->Flink;
|
||
|
while (ListEntry != ListEntryHead)
|
||
|
{
|
||
|
RuleItem = CONTAINING_RECORD(ListEntry, IOCTL_FILTER, List);
|
||
|
if (!RuleItem->bDbgcbAction)
|
||
|
{
|
||
|
BuffSize += sizeof(IOCTL_FILTER_SERIALIZED);
|
||
|
|
||
|
if (RuleItem->Type == FLT_DEVICE_NAME ||
|
||
|
RuleItem->Type == FLT_DRIVER_NAME ||
|
||
|
RuleItem->Type == FLT_PROCESS_PATH)
|
||
|
{
|
||
|
// we an have object name
|
||
|
BuffSize += RuleItem->usName.Length;
|
||
|
}
|
||
|
|
||
|
RulesToSerialize++;
|
||
|
}
|
||
|
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
}
|
||
|
|
||
|
if (BuffSize > 0)
|
||
|
{
|
||
|
// allocate memory for serialized rules
|
||
|
PUCHAR Buff = (PUCHAR)M_ALLOC(BuffSize);
|
||
|
if (Buff)
|
||
|
{
|
||
|
NTSTATUS ns = STATUS_UNSUCCESSFUL;
|
||
|
PIOCTL_FILTER_SERIALIZED f_s = NULL;
|
||
|
RtlZeroMemory(Buff, BuffSize);
|
||
|
f_s = (PIOCTL_FILTER_SERIALIZED)Buff;
|
||
|
|
||
|
// serialize available entries
|
||
|
ListEntry = ListEntryHead->Flink;
|
||
|
while (ListEntry != ListEntryHead)
|
||
|
{
|
||
|
RuleItem = CONTAINING_RECORD(ListEntry, IOCTL_FILTER, List);
|
||
|
if (!RuleItem->bDbgcbAction)
|
||
|
{
|
||
|
ULONG NextEntryOffset = sizeof(IOCTL_FILTER_SERIALIZED);
|
||
|
|
||
|
f_s->Type = RuleItem->Type;
|
||
|
f_s->IoctlCode = RuleItem->IoctlCode;
|
||
|
|
||
|
if (RuleItem->Type == FLT_DEVICE_NAME ||
|
||
|
RuleItem->Type == FLT_DRIVER_NAME ||
|
||
|
RuleItem->Type == FLT_PROCESS_PATH)
|
||
|
{
|
||
|
// we have an object name
|
||
|
f_s->NameLen = RuleItem->usName.Length;
|
||
|
NextEntryOffset += f_s->NameLen;
|
||
|
memcpy(&f_s->Name, RuleItem->usName.Buffer, f_s->NameLen);
|
||
|
}
|
||
|
|
||
|
// go to the next serialized entry
|
||
|
f_s = (PIOCTL_FILTER_SERIALIZED)((PUCHAR)f_s + NextEntryOffset);
|
||
|
}
|
||
|
|
||
|
ListEntry = ListEntry->Flink;
|
||
|
}
|
||
|
|
||
|
ns = ZwSetValueKey(hKey, usValueName, 0, REG_BINARY, Buff, BuffSize);
|
||
|
if (NT_SUCCESS(ns))
|
||
|
{
|
||
|
bRet = TRUE;
|
||
|
|
||
|
DbgMsg(
|
||
|
__FILE__, __LINE__,
|
||
|
__FUNCTION__"(): %d rules (%d bytes) saved in '%wZ'\n",
|
||
|
RulesToSerialize, BuffSize, usValueName
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, "ZwSetValueKey() fails; status: 0x%.8x\n", ns);
|
||
|
}
|
||
|
|
||
|
M_FREE(Buff);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
BOOLEAN SaveDenyRules(HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(FALSE);
|
||
|
bRet = SaveRules(&g_DenyRuleList, hKey, usValueName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
BOOLEAN SaveAllowRules(HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(FALSE);
|
||
|
bRet = SaveRules(&g_AllowRuleList, hKey, usValueName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|
||
|
BOOLEAN LoadRules(PLIST_ENTRY ListEntryHead, HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
PKEY_VALUE_FULL_INFORMATION KeyInfo = NULL;
|
||
|
ULONG Length = 0, RulesLoaded = 0;
|
||
|
NTSTATUS ns = 0;
|
||
|
|
||
|
if(!ListEntryHead)
|
||
|
return FALSE;
|
||
|
|
||
|
// query buffer size
|
||
|
ns = ZwQueryValueKey(
|
||
|
hKey,
|
||
|
usValueName,
|
||
|
KeyValueFullInformation,
|
||
|
KeyInfo,
|
||
|
0,
|
||
|
&Length
|
||
|
);
|
||
|
if (ns == STATUS_BUFFER_OVERFLOW ||
|
||
|
ns == STATUS_BUFFER_TOO_SMALL)
|
||
|
{
|
||
|
// allocate buffer
|
||
|
PKEY_VALUE_FULL_INFORMATION KeyInfo = (PKEY_VALUE_FULL_INFORMATION)M_ALLOC(Length);
|
||
|
if (KeyInfo)
|
||
|
{
|
||
|
// query value
|
||
|
ns = ZwQueryValueKey(
|
||
|
hKey,
|
||
|
usValueName,
|
||
|
KeyValueFullInformation,
|
||
|
KeyInfo,
|
||
|
Length,
|
||
|
&Length
|
||
|
);
|
||
|
if (NT_SUCCESS(ns))
|
||
|
{
|
||
|
if (KeyInfo->DataLength > 0)
|
||
|
{
|
||
|
// deserialize rules
|
||
|
PUCHAR Buff = (PUCHAR)KeyInfo + KeyInfo->DataOffset;
|
||
|
PIOCTL_FILTER_SERIALIZED f_s = (PIOCTL_FILTER_SERIALIZED)Buff;
|
||
|
|
||
|
while ((ULONG)((PUCHAR)f_s - Buff) < KeyInfo->DataLength)
|
||
|
{
|
||
|
// add rule into list
|
||
|
IOCTL_FILTER Flt;
|
||
|
RtlZeroMemory(&Flt, sizeof(Flt));
|
||
|
|
||
|
Flt.Type = f_s->Type;
|
||
|
Flt.IoctlCode = f_s->IoctlCode;
|
||
|
|
||
|
if ((f_s->Type == FLT_DEVICE_NAME ||
|
||
|
f_s->Type == FLT_DRIVER_NAME ||
|
||
|
f_s->Type == FLT_PROCESS_PATH) &&
|
||
|
f_s->NameLen > 0)
|
||
|
{
|
||
|
// we have an object name
|
||
|
if (AllocUnicodeString(&Flt.usName, (USHORT)f_s->NameLen))
|
||
|
{
|
||
|
Flt.usName.Length = (USHORT)f_s->NameLen;
|
||
|
memcpy(Flt.usName.Buffer, &f_s->Name, f_s->NameLen);
|
||
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): '%wZ'\n", &Flt.usName);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
goto err;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!FltAdd(&Flt, ListEntryHead, 0))
|
||
|
{
|
||
|
if (Flt.usName.Buffer)
|
||
|
{
|
||
|
RtlFreeUnicodeString(&Flt.usName);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RulesLoaded++;
|
||
|
}
|
||
|
err:
|
||
|
// go to the next serialized entry
|
||
|
f_s = (PIOCTL_FILTER_SERIALIZED)((PUCHAR)f_s +
|
||
|
sizeof(IOCTL_FILTER_SERIALIZED) + f_s->NameLen);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DbgMsg(
|
||
|
__FILE__, __LINE__,
|
||
|
__FUNCTION__"(): %d rules loaded from '%wZ'\n",
|
||
|
RulesLoaded, usValueName
|
||
|
);
|
||
|
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, "ZwQueryValueKey() fails; status: 0x%.8x\n", ns);
|
||
|
}
|
||
|
|
||
|
M_FREE(KeyInfo);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() WARNING: '%wZ' value is not set\n", usValueName);
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
BOOLEAN LoadDenyRules(HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
bRet = LoadRules(&g_DenyRuleList, hKey, usValueName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
BOOLEAN LoadAllowRules(HANDLE hKey, PUNICODE_STRING usValueName)
|
||
|
{
|
||
|
BOOLEAN bRet = FALSE;
|
||
|
|
||
|
if(!g_RuleInited)
|
||
|
return FALSE;
|
||
|
|
||
|
RuleLock(TRUE);
|
||
|
bRet = LoadRules(&g_AllowRuleList, hKey, usValueName);
|
||
|
RuleUnlock();
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------
|