6
0
mirror of https://github.com/JKornev/hidden synced 2024-06-16 12:08:05 +00:00
hidden/Hidden/PsRules.c

246 lines
6.6 KiB
C
Raw Normal View History

#include "PsRules.h"
2018-12-02 21:56:39 +00:00
#include "Helper.h"
#define PSRULE_ALLOC_TAG 'lRsP'
typedef struct _PsRulesInternalContext {
RTL_AVL_TABLE table;
ULONGLONG idCounter;
2016-12-29 19:48:37 +00:00
FAST_MUTEX tableLock;
} PsRulesInternalContext, *PPsRulesInternalContext;
2017-02-02 22:55:19 +00:00
_Function_class_(RTL_AVL_COMPARE_ROUTINE)
RTL_GENERIC_COMPARE_RESULTS ComparePsRuleEntry(struct _RTL_AVL_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct)
{
2017-01-29 15:43:20 +00:00
PPsRuleEntry first = *(PPsRuleEntry*)FirstStruct;
PPsRuleEntry second = *(PPsRuleEntry*)SecondStruct;
INT res;
UNREFERENCED_PARAMETER(Table);
res = RtlCompareUnicodeString(&first->imagePath, &second->imagePath, TRUE);
if (res > 0)
return GenericGreaterThan;
if (res < 0)
return GenericLessThan;
return GenericEqual;
}
2017-02-02 22:55:19 +00:00
_Function_class_(RTL_AVL_ALLOCATE_ROUTINE)
PVOID AllocatePsRuleEntry(struct _RTL_AVL_TABLE *Table, CLONG ByteSize)
{
UNREFERENCED_PARAMETER(Table);
return ExAllocatePoolWithTag(NonPagedPool, ByteSize, PSRULE_ALLOC_TAG);
}
2017-02-02 22:55:19 +00:00
_Function_class_(RTL_AVL_FREE_ROUTINE)
VOID FreePsRuleEntry(struct _RTL_AVL_TABLE *Table, PVOID Buffer)
{
UNREFERENCED_PARAMETER(Table);
ExFreePoolWithTag(Buffer, PSRULE_ALLOC_TAG);
}
NTSTATUS InitializePsRuleListContext(PPsRulesContext pRuleContext)
{
NTSTATUS status = STATUS_SUCCESS;
PPsRulesInternalContext context;
context = (PPsRulesInternalContext)ExAllocatePoolWithTag(NonPagedPool, sizeof(PsRulesInternalContext), PSRULE_ALLOC_TAG);
if (!context)
{
2018-12-02 21:56:39 +00:00
LogWarning("Error, can't allocate memory");
return STATUS_MEMORY_NOT_ALLOCATED;
}
context->idCounter = 1;
2016-12-29 19:48:37 +00:00
ExInitializeFastMutex(&context->tableLock);
RtlInitializeGenericTableAvl(&context->table, ComparePsRuleEntry, AllocatePsRuleEntry, FreePsRuleEntry, NULL);
*pRuleContext = context;
return status;
}
VOID DestroyPsRuleListContext(PsRulesContext RuleContext)
{
RemoveAllRulesFromPsRuleList(RuleContext);
ExFreePoolWithTag(RuleContext, PSRULE_ALLOC_TAG);
}
NTSTATUS AddRuleToPsRuleList(PsRulesContext RuleContext, PUNICODE_STRING ImgPath, ULONG InheritType, PPsRuleEntryId EntryId)
{
PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext;
NTSTATUS status = STATUS_SUCCESS;
ULONGLONG guid;
PPsRuleEntry entry;
ULONG entryLen;
BOOLEAN newElem;
PVOID buf;
if (InheritType > PsRuleTypeMax)
{
2018-12-02 21:56:39 +00:00
LogWarning("Error, invalid inherit type: %d", InheritType);
2016-08-31 22:28:18 +00:00
return STATUS_INVALID_PARAMETER_3;
}
entryLen = sizeof(PsRuleEntry) + ImgPath->Length;
entry = (PPsRuleEntry)ExAllocatePoolWithTag(NonPagedPool, entryLen, PSRULE_ALLOC_TAG);
if (!entry)
{
2018-12-02 21:56:39 +00:00
LogWarning("Error, can't allocate memory");
return STATUS_MEMORY_NOT_ALLOCATED;
}
entry->inheritType = InheritType;
entry->len = entryLen;
entry->imagePath.Buffer = (PWCH)(entry + 1);
entry->imagePath.Length = 0;
entry->imagePath.MaximumLength = ImgPath->Length;
RtlCopyUnicodeString(&entry->imagePath, ImgPath);
2016-12-29 19:48:37 +00:00
ExAcquireFastMutex(&context->tableLock);
guid = context->idCounter++;
entry->guid = guid;
2017-01-29 15:43:20 +00:00
buf = RtlInsertElementGenericTableAvl(&context->table, &entry, sizeof(&entry)/*entryLen*/, &newElem);
2016-12-29 19:48:37 +00:00
ExReleaseFastMutex(&context->tableLock);
if (!buf)
{
2017-01-31 20:03:37 +00:00
ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG);
2018-12-02 21:56:39 +00:00
LogWarning("Error, can't allocate memory for a new element");
return STATUS_MEMORY_NOT_ALLOCATED;
}
if (!newElem)
{
2017-01-31 20:03:37 +00:00
ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG);
2018-12-02 21:56:39 +00:00
LogWarning("Error, this path already in a rules list");
return STATUS_DUPLICATE_NAME;
}
*EntryId = guid;
return status;
}
NTSTATUS RemoveRuleFromPsRuleList(PsRulesContext RuleContext, PsRuleEntryId EntryId)
{
PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext;
NTSTATUS status = STATUS_NOT_FOUND;
2017-01-29 15:43:20 +00:00
PPsRuleEntry entry, *pentry;
PVOID restartKey = NULL;
2016-12-29 19:48:37 +00:00
ExAcquireFastMutex(&context->tableLock);
2017-01-29 15:43:20 +00:00
for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey);
pentry != NULL;
pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey))
{
2017-01-29 15:43:20 +00:00
entry = *pentry;
if (entry->guid == EntryId)
{
2017-01-29 15:43:20 +00:00
if (!RtlDeleteElementGenericTableAvl(&context->table, pentry))
2018-12-02 21:56:39 +00:00
LogWarning("Error, can't remove element from process rules table, looks like memory leak");
2017-01-29 15:43:20 +00:00
else
ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG);
status = STATUS_SUCCESS;
break;
}
}
2016-12-29 19:48:37 +00:00
ExReleaseFastMutex(&context->tableLock);
return status;
}
NTSTATUS RemoveAllRulesFromPsRuleList(PsRulesContext RuleContext)
{
PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext;
NTSTATUS status = STATUS_SUCCESS;
2017-01-29 15:43:20 +00:00
PPsRuleEntry entry, *pentry;
PVOID restartKey = NULL;
2016-12-29 19:48:37 +00:00
ExAcquireFastMutex(&context->tableLock);
2017-01-29 15:43:20 +00:00
for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey);
pentry != NULL;
pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey))
{
2017-01-29 15:43:20 +00:00
entry = *pentry;
if (!RtlDeleteElementGenericTableAvl(&context->table, pentry))
2018-12-02 21:56:39 +00:00
LogWarning("Error, can't remove element from process rules table, looks like memory leak");
2017-01-29 15:43:20 +00:00
else
ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG);
restartKey = NULL; // reset enum
}
2016-12-29 19:48:37 +00:00
ExReleaseFastMutex(&context->tableLock);
return status;
}
NTSTATUS CheckInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PPsRuleEntry Rule, ULONG RuleSize, PULONG OutSize)
{
PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext;
NTSTATUS status = STATUS_NOT_FOUND;
2017-01-29 15:43:20 +00:00
PPsRuleEntry entry, *pentry;
PVOID restartKey = NULL;
2016-12-29 19:48:37 +00:00
ExAcquireFastMutex(&context->tableLock);
2017-01-29 15:43:20 +00:00
for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey);
pentry != NULL;
pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey))
{
2017-01-29 15:43:20 +00:00
entry = *pentry;
if (RtlCompareUnicodeString(&entry->imagePath, ImgPath, TRUE) == 0)
{
*OutSize = entry->len;
if (RuleSize < entry->len)
{
status = STATUS_BUFFER_TOO_SMALL;
break;
}
RtlCopyMemory(Rule, entry, entry->len);
status = STATUS_SUCCESS;
break;
}
}
2016-12-29 19:48:37 +00:00
ExReleaseFastMutex(&context->tableLock);
return status;
}
BOOLEAN FindInheritanceInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PULONG pInheritance)
{
PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext;
2017-01-29 15:43:20 +00:00
PPsRuleEntry entry, *pentry;
PVOID restartKey = NULL;
BOOLEAN result = FALSE;
2016-12-29 19:48:37 +00:00
ExAcquireFastMutex(&context->tableLock);
2017-01-29 15:43:20 +00:00
for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey);
pentry != NULL;
pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey))
{
2017-01-29 15:43:20 +00:00
entry = *pentry;
if (RtlCompareUnicodeString(&entry->imagePath, ImgPath, TRUE) == 0)
{
*pInheritance = entry->inheritType;
result = TRUE;
break;
}
}
2016-12-29 19:48:37 +00:00
ExReleaseFastMutex(&context->tableLock);
return result;
}