indentation

This commit is contained in:
donnaskiez 2024-04-13 18:23:14 +10:00
parent 49c7ff65f1
commit 3aa74dedfe
23 changed files with 6728 additions and 7041 deletions

View file

@ -61,7 +61,7 @@ ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentPPDirectives: AfterHash
IndentWidth: 8
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp

View file

@ -6,30 +6,30 @@
VOID
GetApcContextByIndex(_Out_ PVOID* Context, _In_ INT Index)
{
AcquireDriverConfigLock();
*Context = GetApcContextArray()[Index];
ReleaseDriverConfigLock();
AcquireDriverConfigLock();
*Context = GetApcContextArray()[Index];
ReleaseDriverConfigLock();
}
VOID
GetApcContext(_Out_ PVOID* Context, _In_ LONG ContextIdentifier)
{
AcquireDriverConfigLock();
AcquireDriverConfigLock();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PAPC_CONTEXT_HEADER header = GetApcContextArray()[index];
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PAPC_CONTEXT_HEADER header = GetApcContextArray()[index];
if (!header)
continue;
if (!header)
continue;
if (header->context_id != ContextIdentifier)
continue;
if (header->context_id != ContextIdentifier)
continue;
*Context = header;
goto unlock;
}
*Context = header;
goto unlock;
}
unlock:
ReleaseDriverConfigLock();
ReleaseDriverConfigLock();
}
/*
@ -41,54 +41,54 @@ unlock:
BOOLEAN
FreeApcContextStructure(_Out_ PAPC_CONTEXT_HEADER Context)
{
DEBUG_VERBOSE("All APCs executed, freeing context structure");
DEBUG_VERBOSE("All APCs executed, freeing context structure");
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
if (entry[index] != Context)
continue;
if (entry[index] != Context)
continue;
if (Context->count > 0)
return FALSE;
if (Context->count > 0)
return FALSE;
ImpExFreePoolWithTag(Context, POOL_TAG_APC);
entry[index] = NULL;
return TRUE;
}
ImpExFreePoolWithTag(Context, POOL_TAG_APC);
entry[index] = NULL;
return TRUE;
}
return FALSE;
return FALSE;
}
VOID
IncrementApcCount(_In_ LONG ContextId)
{
PAPC_CONTEXT_HEADER header = NULL;
GetApcContext(&header, ContextId);
PAPC_CONTEXT_HEADER header = NULL;
GetApcContext(&header, ContextId);
if (!header)
return;
if (!header)
return;
/* i actually dont think we need this lock here */
AcquireDriverConfigLock();
header->count += 1;
ReleaseDriverConfigLock();
/* i actually dont think we need this lock here */
AcquireDriverConfigLock();
header->count += 1;
ReleaseDriverConfigLock();
}
VOID
FreeApcAndDecrementApcCount(_Inout_ PRKAPC Apc, _In_ LONG ContextId)
{
PAPC_CONTEXT_HEADER context = NULL;
PAPC_CONTEXT_HEADER context = NULL;
ImpExFreePoolWithTag(Apc, POOL_TAG_APC);
GetApcContext(&context, ContextId);
ImpExFreePoolWithTag(Apc, POOL_TAG_APC);
GetApcContext(&context, ContextId);
if (!context)
return;
if (!context)
return;
AcquireDriverConfigLock();
context->count -= 1;
ReleaseDriverConfigLock();
AcquireDriverConfigLock();
context->count -= 1;
ReleaseDriverConfigLock();
}
/*
@ -121,49 +121,49 @@ FreeApcAndDecrementApcCount(_Inout_ PRKAPC Apc, _In_ LONG ContextId)
NTSTATUS
QueryActiveApcContextsForCompletion()
{
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PAPC_CONTEXT_HEADER entry = NULL;
GetApcContextByIndex(&entry, index);
AcquireDriverConfigLock();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PAPC_CONTEXT_HEADER entry = NULL;
GetApcContextByIndex(&entry, index);
AcquireDriverConfigLock();
if (!entry)
goto increment;
if (!entry)
goto increment;
if (entry->count > 0 || entry->allocation_in_progress == TRUE)
goto increment;
if (entry->count > 0 || entry->allocation_in_progress == TRUE)
goto increment;
switch (entry->context_id) {
case APC_CONTEXT_ID_STACKWALK:
FreeApcStackwalkApcContextInformation(entry);
FreeApcContextStructure(entry);
break;
}
increment:
ReleaseDriverConfigLock();
switch (entry->context_id) {
case APC_CONTEXT_ID_STACKWALK:
FreeApcStackwalkApcContextInformation(entry);
FreeApcContextStructure(entry);
break;
}
return STATUS_SUCCESS;
increment:
ReleaseDriverConfigLock();
}
return STATUS_SUCCESS;
}
VOID
InsertApcContext(_In_ PVOID Context)
{
if (IsDriverUnloading())
return STATUS_UNSUCCESSFUL;
if (IsDriverUnloading())
return STATUS_UNSUCCESSFUL;
AcquireDriverConfigLock();
PAPC_CONTEXT_HEADER header = Context;
AcquireDriverConfigLock();
PAPC_CONTEXT_HEADER header = Context;
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
if (entry[index] == NULL) {
entry[index] = Context;
goto end;
}
if (entry[index] == NULL) {
entry[index] = Context;
goto end;
}
}
end:
ReleaseDriverConfigLock();
ReleaseDriverConfigLock();
}
/*
@ -196,24 +196,24 @@ end:
BOOLEAN
DrvUnloadFreeAllApcContextStructures()
{
AcquireDriverConfigLock();
AcquireDriverConfigLock();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
for (INT index = 0; index < MAXIMUM_APC_CONTEXTS; index++) {
PUINT64 entry = GetApcContextArray();
if (entry[index] == NULL)
continue;
if (entry[index] == NULL)
continue;
PAPC_CONTEXT_HEADER context = entry[index];
PAPC_CONTEXT_HEADER context = entry[index];
if (context->count > 0) {
ReleaseDriverConfigLock();
return FALSE;
}
ImpExFreePoolWithTag(entry, POOL_TAG_APC);
if (context->count > 0) {
ReleaseDriverConfigLock();
return FALSE;
}
ImpExFreePoolWithTag(entry, POOL_TAG_APC);
}
unlock:
ReleaseDriverConfigLock();
return TRUE;
ReleaseDriverConfigLock();
return TRUE;
}

File diff suppressed because it is too large Load diff

View file

@ -16,20 +16,20 @@ typedef void (*PROCESSLIST_CALLBACK_ROUTINE)(
#define SHA_256_HASH_LENGTH 32
typedef struct _DRIVER_LIST_ENTRY {
SINGLE_LIST_ENTRY list;
PVOID ImageBase;
ULONG ImageSize;
BOOLEAN hashed;
BOOLEAN x86;
CHAR path[DRIVER_PATH_LENGTH];
CHAR text_hash[SHA_256_HASH_LENGTH];
SINGLE_LIST_ENTRY list;
PVOID ImageBase;
ULONG ImageSize;
BOOLEAN hashed;
BOOLEAN x86;
CHAR path[DRIVER_PATH_LENGTH];
CHAR text_hash[SHA_256_HASH_LENGTH];
/*
* This LIST_ENTRY is to be used for modules where the hashing needs to
* be deferred. For example, when x86 modules can't be hashed on driver
* load.
*/
LIST_ENTRY deferred_entry;
/*
* This LIST_ENTRY is to be used for modules where the hashing needs to
* be deferred. For example, when x86 modules can't be hashed on driver
* load.
*/
LIST_ENTRY deferred_entry;
} DRIVER_LIST_ENTRY, *PDRIVER_LIST_ENTRY;

File diff suppressed because it is too large Load diff

View file

@ -14,37 +14,34 @@ STATIC
__m256i
CryptGenerateSseXorKey()
{
return _mm256_set_epi64x(XOR_KEY_1, XOR_KEY_2, XOR_KEY_3, XOR_KEY_4);
return _mm256_set_epi64x(XOR_KEY_1, XOR_KEY_2, XOR_KEY_3, XOR_KEY_4);
}
VOID
CryptEncryptImportsArray(_In_ PUINT64 Array, _In_ UINT32 Entries)
{
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
UINT32 block_count = Entries / block_size;
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
UINT32 block_count = Entries / block_size;
/*
* Here we break down the import array into blocks of 32 bytes. Each
* block is loaded into an SSE register, xored with the key, and then
* copied back into the array.
*/
for (UINT32 block_index = 0; block_index < block_count; block_index++) {
__m256i current_block = {0};
__m256i load_block = {0};
__m256i xored_block = {0};
/*
* Here we break down the import array into blocks of 32 bytes. Each
* block is loaded into an SSE register, xored with the key, and then
* copied back into the array.
*/
for (UINT32 block_index = 0; block_index < block_count; block_index++) {
__m256i current_block = {0};
__m256i load_block = {0};
__m256i xored_block = {0};
RtlCopyMemory(&current_block,
&Array[block_index * block_size],
sizeof(__m256i));
RtlCopyMemory(
&current_block, &Array[block_index * block_size], sizeof(__m256i));
load_block = _mm256_loadu_si256(&current_block);
xored_block =
_mm256_xor_si256(load_block, CryptGenerateSseXorKey());
load_block = _mm256_loadu_si256(&current_block);
xored_block = _mm256_xor_si256(load_block, CryptGenerateSseXorKey());
RtlCopyMemory(&Array[block_index * block_size],
&xored_block,
sizeof(__m256i));
}
RtlCopyMemory(
&Array[block_index * block_size], &xored_block, sizeof(__m256i));
}
}
STATIC
@ -52,13 +49,13 @@ INLINE
__m256i
CryptDecryptImportBlock(_In_ PUINT64 Array, _In_ UINT32 BlockIndex)
{
__m256i load_block = {0};
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
__m256i load_block = {0};
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
RtlCopyMemory(
&load_block, &Array[BlockIndex * block_size], sizeof(__m256i));
RtlCopyMemory(
&load_block, &Array[BlockIndex * block_size], sizeof(__m256i));
return _mm256_xor_si256(load_block, CryptGenerateSseXorKey());
return _mm256_xor_si256(load_block, CryptGenerateSseXorKey());
}
STATIC
@ -69,28 +66,28 @@ CryptFindContainingBlockForArrayIndex(_In_ UINT32 EntryIndex,
_Out_ PUINT32 ContainingBlockIndex,
_Out_ PUINT32 BlockSubIndex)
{
UINT32 containing_block = EntryIndex;
UINT32 block_index = 0;
UINT32 containing_block = EntryIndex;
UINT32 block_index = 0;
if (EntryIndex < BlockSize) {
*ContainingBlockIndex = 0;
*BlockSubIndex = EntryIndex;
return;
}
if (EntryIndex < BlockSize) {
*ContainingBlockIndex = 0;
*BlockSubIndex = EntryIndex;
return;
}
if (EntryIndex == BlockSize) {
*ContainingBlockIndex = 1;
*BlockSubIndex = 0;
return;
}
if (EntryIndex == BlockSize) {
*ContainingBlockIndex = 1;
*BlockSubIndex = 0;
return;
}
while (containing_block % BlockSize != 0) {
containing_block--;
block_index++;
}
while (containing_block % BlockSize != 0) {
containing_block--;
block_index++;
}
*ContainingBlockIndex = containing_block / BlockSize;
*BlockSubIndex = block_index;
*ContainingBlockIndex = containing_block / BlockSize;
*BlockSubIndex = block_index;
}
UINT64
@ -98,36 +95,36 @@ CryptDecryptImportsArrayEntry(_In_ PUINT64 Array,
_In_ UINT32 Entries,
_In_ UINT32 EntryIndex)
{
__m256i original_block = {0};
__m128i original_half = {0};
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
UINT32 containing_block_index = 0;
UINT32 block_sub_index = 0;
UINT64 pointer = 0;
__m256i original_block = {0};
__m128i original_half = {0};
UINT32 block_size = sizeof(__m256i) / sizeof(UINT64);
UINT32 containing_block_index = 0;
UINT32 block_sub_index = 0;
UINT64 pointer = 0;
CryptFindContainingBlockForArrayIndex(
EntryIndex, block_size, &containing_block_index, &block_sub_index);
CryptFindContainingBlockForArrayIndex(
EntryIndex, block_size, &containing_block_index, &block_sub_index);
original_block = CryptDecryptImportBlock(Array, containing_block_index);
original_block = CryptDecryptImportBlock(Array, containing_block_index);
if (block_sub_index < 2) {
original_half = _mm256_extracti128_si256(original_block, 0);
if (block_sub_index < 2) {
original_half = _mm256_extracti128_si256(original_block, 0);
if (block_sub_index < 1)
pointer = _mm_extract_epi64(original_half, 0);
else
pointer = _mm_extract_epi64(original_half, 1);
}
else {
original_half = _mm256_extracti128_si256(original_block, 1);
if (block_sub_index < 1)
pointer = _mm_extract_epi64(original_half, 0);
else
pointer = _mm_extract_epi64(original_half, 1);
}
else {
original_half = _mm256_extracti128_si256(original_block, 1);
if (block_sub_index == 2)
pointer = _mm_extract_epi64(original_half, 0);
else
pointer = _mm_extract_epi64(original_half, 1);
}
if (block_sub_index == 2)
pointer = _mm_extract_epi64(original_half, 0);
else
pointer = _mm_extract_epi64(original_half, 1);
}
return pointer;
return pointer;
}
/*
@ -138,9 +135,8 @@ CryptDecryptBufferWithCookie(_In_ PVOID Buffer,
_In_ UINT32 BufferSize,
_In_ UINT32 Cookie)
{
PCHAR buffer = (PCHAR)Buffer;
for (UINT32 index = 0; index < BufferSize; index++) {
buffer[index] ^= Cookie;
}
PCHAR buffer = (PCHAR)Buffer;
for (UINT32 index = 0; index < BufferSize; index++) {
buffer[index] ^= Cookie;
}
}

View file

@ -7,9 +7,13 @@ VOID
CryptEncryptImportsArray(_In_ PUINT64 Array, _In_ UINT32 Entries);
UINT64
CryptDecryptImportsArrayEntry(_In_ PUINT64 Array, _In_ UINT32 Entries, _In_ UINT32 EntryIndex);
CryptDecryptImportsArrayEntry(_In_ PUINT64 Array,
_In_ UINT32 Entries,
_In_ UINT32 EntryIndex);
VOID
CryptDecryptBufferWithCookie(_In_ PVOID Buffer, _In_ UINT32 BufferSize, _In_ UINT32 Cookie);
CryptDecryptBufferWithCookie(_In_ PVOID Buffer,
_In_ UINT32 BufferSize,
_In_ UINT32 Cookie);
#endif

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@
#include "io.h"
#ifdef ALLOC_PRAGMA
# pragma alloc_text(PAGE, PerformVirtualizationDetection)
# pragma alloc_text(PAGE, PerformVirtualizationDetection)
#endif
#define TOTAL_ITERATION_COUNT 20
@ -25,86 +25,85 @@
BOOLEAN
APERFMsrTimingCheck()
{
KAFFINITY new_affinity = {0};
KAFFINITY old_affinity = {0};
UINT64 old_irql = 0;
INT cpuid_result[4];
KAFFINITY new_affinity = {0};
KAFFINITY old_affinity = {0};
UINT64 old_irql = 0;
INT cpuid_result[4];
/*
* First thing we do is we lock the current thread to the logical
* processor its executing on.
*/
new_affinity = (KAFFINITY)(1ull << KeGetCurrentProcessorNumber());
old_affinity = ImpKeSetSystemAffinityThreadEx(new_affinity);
/*
* First thing we do is we lock the current thread to the logical
* processor its executing on.
*/
new_affinity = (KAFFINITY)(1ull << KeGetCurrentProcessorNumber());
old_affinity = ImpKeSetSystemAffinityThreadEx(new_affinity);
/*
* Once we've locked our thread to the current core, we save the old
* irql and raise to HIGH_LEVEL to ensure the chance our thread is
* preempted by a thread with a higher IRQL is extremely low.
*/
old_irql = __readcr8();
__writecr8(HIGH_LEVEL);
/*
* Once we've locked our thread to the current core, we save the old
* irql and raise to HIGH_LEVEL to ensure the chance our thread is
* preempted by a thread with a higher IRQL is extremely low.
*/
old_irql = __readcr8();
__writecr8(HIGH_LEVEL);
/*
* Then we also disable interrupts, once again making sure our thread
* is not preempted.
*/
_disable();
/*
* Then we also disable interrupts, once again making sure our thread
* is not preempted.
*/
_disable();
/*
* Once our thread is ready for the test, we read the APERF from the
* MSR register and store it. We then execute a CPUID instruction
* which we don't really care about and immediately after read the APERF
* counter once again and store it in a seperate variable.
*/
UINT64 aperf_before = __readmsr(IA32_APERF_MSR) << 32;
__cpuid(cpuid_result, 1);
UINT64 aperf_after = __readmsr(IA32_APERF_MSR) << 32;
/*
* Once our thread is ready for the test, we read the APERF from the
* MSR register and store it. We then execute a CPUID instruction
* which we don't really care about and immediately after read the APERF
* counter once again and store it in a seperate variable.
*/
UINT64 aperf_before = __readmsr(IA32_APERF_MSR) << 32;
__cpuid(cpuid_result, 1);
UINT64 aperf_after = __readmsr(IA32_APERF_MSR) << 32;
/*
* Once we have performed our test, we want to make sure we are not
* hogging the cpu time from other threads, so we reverse the initial
* preparation process. i.e we first enable interrupts, lower our irql
* to the threads previous irql before it was raised and then restore
* the threads affinity back to its original affinity.
*/
_enable();
__writecr8(old_irql);
ImpKeRevertToUserAffinityThreadEx(old_affinity);
/*
* Once we have performed our test, we want to make sure we are not
* hogging the cpu time from other threads, so we reverse the initial
* preparation process. i.e we first enable interrupts, lower our irql
* to the threads previous irql before it was raised and then restore
* the threads affinity back to its original affinity.
*/
_enable();
__writecr8(old_irql);
ImpKeRevertToUserAffinityThreadEx(old_affinity);
/*
* Now the only thing left to do is calculate the change. Now, on some
* VMs such as VMWARE the aperf value will be 0, meaning the change will
* be 0. This is a dead giveaway we are executing in a VM.
*/
UINT64 aperf_delta = aperf_after - aperf_before;
/*
* Now the only thing left to do is calculate the change. Now, on some
* VMs such as VMWARE the aperf value will be 0, meaning the change will
* be 0. This is a dead giveaway we are executing in a VM.
*/
UINT64 aperf_delta = aperf_after - aperf_before;
return aperf_delta == 0 ? TRUE : FALSE;
return aperf_delta == 0 ? TRUE : FALSE;
}
NTSTATUS
PerformVirtualizationDetection(_Inout_ PIRP Irp)
{
PAGED_CODE();
PAGED_CODE();
NTSTATUS status =
ValidateIrpOutputBuffer(Irp, sizeof(HYPERVISOR_DETECTION_REPORT));
NTSTATUS status =
ValidateIrpOutputBuffer(Irp, sizeof(HYPERVISOR_DETECTION_REPORT));
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpOutputBuffer failed with status %x",
status);
return status;
}
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpOutputBuffer failed with status %x", status);
return status;
}
HYPERVISOR_DETECTION_REPORT report = {0};
report.aperf_msr_timing_check = APERFMsrTimingCheck();
report.invd_emulation_check = TestINVDEmulation();
HYPERVISOR_DETECTION_REPORT report = {0};
report.aperf_msr_timing_check = APERFMsrTimingCheck();
report.invd_emulation_check = TestINVDEmulation();
Irp->IoStatus.Information = sizeof(HYPERVISOR_DETECTION_REPORT);
Irp->IoStatus.Information = sizeof(HYPERVISOR_DETECTION_REPORT);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&report,
sizeof(HYPERVISOR_DETECTION_REPORT));
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&report,
sizeof(HYPERVISOR_DETECTION_REPORT));
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}

View file

@ -67,51 +67,49 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
_Out_ PVOID Buffer,
_In_ UINT32 BufferLength)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
KEVENT event = {0};
IO_STATUS_BLOCK io = {0};
PIRP irp = NULL;
PIO_STACK_LOCATION io_stack_location = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
KEVENT event = {0};
IO_STATUS_BLOCK io = {0};
PIRP irp = NULL;
PIO_STACK_LOCATION io_stack_location = NULL;
if (BufferLength == 0)
return STATUS_BUFFER_TOO_SMALL;
if (BufferLength == 0)
return STATUS_BUFFER_TOO_SMALL;
KeInitializeEvent(&event, NotificationEvent, FALSE);
KeInitializeEvent(&event, NotificationEvent, FALSE);
/*
* we dont need to free this IRP as the IO manager will free it when the
* request is completed
*/
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP, DeviceObject, NULL, 0, NULL, &event, &io);
/*
* we dont need to free this IRP as the IO manager will free it when the
* request is completed
*/
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP, DeviceObject, NULL, 0, NULL, &event, &io);
if (!irp) {
DEBUG_ERROR(
"IoBuildSynchronousFsdRequest failed with no status.");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (!irp) {
DEBUG_ERROR("IoBuildSynchronousFsdRequest failed with no status.");
return STATUS_INSUFFICIENT_RESOURCES;
}
io_stack_location = IoGetNextIrpStackLocation(irp);
io_stack_location->MinorFunction = IRP_MN_READ_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.WhichSpace =
PCI_WHICHSPACE_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.Offset = Offset;
io_stack_location->Parameters.ReadWriteConfig.Buffer = Buffer;
io_stack_location->Parameters.ReadWriteConfig.Length = BufferLength;
io_stack_location = IoGetNextIrpStackLocation(irp);
io_stack_location->MinorFunction = IRP_MN_READ_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.WhichSpace =
PCI_WHICHSPACE_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.Offset = Offset;
io_stack_location->Parameters.ReadWriteConfig.Buffer = Buffer;
io_stack_location->Parameters.ReadWriteConfig.Length = BufferLength;
status = IoCallDriver(DeviceObject, irp);
status = IoCallDriver(DeviceObject, irp);
if (status = STATUS_PENDING) {
KeWaitForSingleObject(
&event, Executive, KernelMode, FALSE, NULL);
status = io.Status;
}
if (status = STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = io.Status;
}
if (!NT_SUCCESS(status))
DEBUG_ERROR("Failed to read configuration space with status %x",
status);
if (!NT_SUCCESS(status))
DEBUG_ERROR("Failed to read configuration space with status %x",
status);
return status;
return status;
}
/*
@ -123,45 +121,44 @@ EnumerateDriverObjectDeviceObjects(_In_ PDRIVER_OBJECT DriverObject,
_Out_ PDEVICE_OBJECT** DeviceObjectArray,
_Out_ PUINT32 ArrayEntries)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 object_count = 0;
PDEVICE_OBJECT* buffer = NULL;
UINT32 buffer_size = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 object_count = 0;
PDEVICE_OBJECT* buffer = NULL;
UINT32 buffer_size = 0;
*DeviceObjectArray = NULL;
*DeviceObjectArray = NULL;
status =
IoEnumerateDeviceObjectList(DriverObject, NULL, 0, &object_count);
if (status != STATUS_BUFFER_TOO_SMALL) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x",
status);
return status;
}
buffer_size = object_count * sizeof(UINT64);
buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_HW);
if (!buffer)
return STATUS_INSUFFICIENT_RESOURCES;
status = IoEnumerateDeviceObjectList(
DriverObject, buffer, buffer_size, &object_count);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x",
status);
ExFreePoolWithTag(buffer, POOL_TAG_HW);
return status;
}
DEBUG_VERBOSE("EnumerateDriverObjectDeviceObjects: Object Count: %lx",
object_count);
*DeviceObjectArray = buffer;
*ArrayEntries = object_count;
status = IoEnumerateDeviceObjectList(DriverObject, NULL, 0, &object_count);
if (status != STATUS_BUFFER_TOO_SMALL) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x",
status);
return status;
}
buffer_size = object_count * sizeof(UINT64);
buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_HW);
if (!buffer)
return STATUS_INSUFFICIENT_RESOURCES;
status = IoEnumerateDeviceObjectList(
DriverObject, buffer, buffer_size, &object_count);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("IoEnumerateDeviceObjectList failed with status %x",
status);
ExFreePoolWithTag(buffer, POOL_TAG_HW);
return status;
}
DEBUG_VERBOSE("EnumerateDriverObjectDeviceObjects: Object Count: %lx",
object_count);
*DeviceObjectArray = buffer;
*ArrayEntries = object_count;
return status;
}
/*
@ -173,7 +170,7 @@ STATIC
BOOLEAN
IsDeviceObjectValidPdo(_In_ PDEVICE_OBJECT DeviceObject)
{
return DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE ? TRUE : FALSE;
return DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE ? TRUE : FALSE;
}
/*
@ -197,114 +194,108 @@ NTSTATUS
EnumeratePciDeviceObjects(_In_ PCI_DEVICE_CALLBACK CallbackRoutine,
_In_opt_ PVOID Context)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UNICODE_STRING pci = RTL_CONSTANT_STRING(L"\\Driver\\pci");
PDRIVER_OBJECT pci_driver_object = NULL;
PDEVICE_OBJECT* pci_device_objects = NULL;
PDEVICE_OBJECT current_device = NULL;
UINT32 pci_device_objects_count = 0;
USHORT vendor_id = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
UNICODE_STRING pci = RTL_CONSTANT_STRING(L"\\Driver\\pci");
PDRIVER_OBJECT pci_driver_object = NULL;
PDEVICE_OBJECT* pci_device_objects = NULL;
PDEVICE_OBJECT current_device = NULL;
UINT32 pci_device_objects_count = 0;
USHORT vendor_id = 0;
status = GetDriverObjectByDriverName(&pci, &pci_driver_object);
status = GetDriverObjectByDriverName(&pci, &pci_driver_object);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GetDriverObjectByDriverName failed with status %x",
status);
return status;
}
status = EnumerateDriverObjectDeviceObjects(
pci_driver_object, &pci_device_objects, &pci_device_objects_count);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR(
"EnumerateDriverObjectDeviceObjects failed with status %x",
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("GetDriverObjectByDriverName failed with status %x",
status);
return status;
return status;
}
status = EnumerateDriverObjectDeviceObjects(
pci_driver_object, &pci_device_objects, &pci_device_objects_count);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("EnumerateDriverObjectDeviceObjects failed with status %x",
status);
return status;
}
for (UINT32 index = 0; index < pci_device_objects_count; index++) {
current_device = pci_device_objects[index];
/* make sure we have a valid PDO */
if (!IsDeviceObjectValidPdo(current_device)) {
ObDereferenceObject(current_device);
continue;
}
for (UINT32 index = 0; index < pci_device_objects_count; index++) {
current_device = pci_device_objects[index];
status = CallbackRoutine(current_device, Context);
/* make sure we have a valid PDO */
if (!IsDeviceObjectValidPdo(current_device)) {
ObDereferenceObject(current_device);
continue;
}
if (!NT_SUCCESS(status))
DEBUG_ERROR(
"EnumeratePciDeviceObjects CallbackRoutine failed with status %x",
status);
status = CallbackRoutine(current_device, Context);
if (!NT_SUCCESS(status))
DEBUG_ERROR(
"EnumeratePciDeviceObjects CallbackRoutine failed with status %x",
status);
ObDereferenceObject(current_device);
}
ObDereferenceObject(current_device);
}
end:
if (pci_device_objects)
ExFreePoolWithTag(pci_device_objects, POOL_TAG_HW);
if (pci_device_objects)
ExFreePoolWithTag(pci_device_objects, POOL_TAG_HW);
return status;
return status;
}
BOOLEAN
IsPciConfigurationSpaceFlagged(_In_ PPCI_COMMON_HEADER Configuration)
{
for (UINT32 index = 0; index < FLAGGED_DEVICE_ID_COUNT; index++) {
if (Configuration->DeviceID == FLAGGED_DEVICE_IDS[index])
return TRUE;
}
for (UINT32 index = 0; index < FLAGGED_DEVICE_ID_COUNT; index++) {
if (Configuration->DeviceID == FLAGGED_DEVICE_IDS[index])
return TRUE;
}
return FALSE;
return FALSE;
}
STATIC
NTSTATUS
PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PCI_COMMON_HEADER header = {0};
NTSTATUS status = STATUS_UNSUCCESSFUL;
PCI_COMMON_HEADER header = {0};
status = QueryPciDeviceConfigurationSpace(DeviceObject,
PCI_VENDOR_ID_OFFSET,
&header,
sizeof(PCI_COMMON_HEADER));
status = QueryPciDeviceConfigurationSpace(
DeviceObject, PCI_VENDOR_ID_OFFSET, &header, sizeof(PCI_COMMON_HEADER));
if (!NT_SUCCESS(status)) {
DEBUG_ERROR(
"QueryPciDeviceConfigurationSpace failed with status %x",
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("QueryPciDeviceConfigurationSpace failed with status %x",
status);
return status;
}
if (IsPciConfigurationSpaceFlagged(&header)) {
DEBUG_VERBOSE(
"Flagged DeviceID found. Device: %llx, DeviceId: %lx",
(UINT64)DeviceObject,
header.DeviceID);
}
else {
DEBUG_VERBOSE("Device: %llx, DeviceID: %lx, VendorID: %lx",
DeviceObject,
header.DeviceID,
header.VendorID);
}
return status;
}
if (IsPciConfigurationSpaceFlagged(&header)) {
DEBUG_VERBOSE("Flagged DeviceID found. Device: %llx, DeviceId: %lx",
(UINT64)DeviceObject,
header.DeviceID);
}
else {
DEBUG_VERBOSE("Device: %llx, DeviceID: %lx, VendorID: %lx",
DeviceObject,
header.DeviceID,
header.VendorID);
}
return status;
}
NTSTATUS
ValidatePciDevices()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
status = EnumeratePciDeviceObjects(PciDeviceQueryCallback, NULL);
status = EnumeratePciDeviceObjects(PciDeviceQueryCallback, NULL);
if (!NT_SUCCESS(status))
DEBUG_ERROR("EnumeratePciDeviceObjects failed with status %x",
status);
if (!NT_SUCCESS(status))
DEBUG_ERROR("EnumeratePciDeviceObjects failed with status %x", status);
return status;
return status;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,56 +6,55 @@
#include "common.h"
typedef struct _MODULE_DISPATCHER_HEADER {
volatile UINT32
validated; // if this is > 0, a thread is already using it
UINT8 result;
volatile UINT32 validated; // if this is > 0, a thread is already using it
UINT8 result;
} MODULE_DISPATCHER_HEADER, *PMODULE_DISPATCHER_HEADER;
typedef struct _SYSTEM_MODULE_INFORMATION {
MODULE_DISPATCHER_HEADER dispatcher_header;
RTL_MODULE_EXTENDED_INFO module_information;
MODULE_DISPATCHER_HEADER dispatcher_header;
RTL_MODULE_EXTENDED_INFO module_information;
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
#define VERIFICATION_THREAD_COUNT 4
typedef struct _SYS_MODULE_VAL_CONTEXT {
/* Stores the number of actively executing worker threads */
volatile LONG active_thread_count;
/* Stores the number of actively executing worker threads */
volatile LONG active_thread_count;
/* determines whether a validation is in progress */
volatile LONG active;
/* determines whether a validation is in progress */
volatile LONG active;
/* determines whether a validation is complete */
volatile LONG complete;
/* determines whether a validation is complete */
volatile LONG complete;
/* current count of validated modules */
volatile LONG current_count;
/* current count of validated modules */
volatile LONG current_count;
/* total count of modules */
UINT32 total_count;
/* total count of modules */
UINT32 total_count;
/* number of modules to validate in a single sweep */
UINT32 block_size;
/* number of modules to validate in a single sweep */
UINT32 block_size;
/* pointer to the buffer containing the system module information */
PRTL_MODULE_EXTENDED_INFO module_info;
/* pointer to the buffer containing the system module information */
PRTL_MODULE_EXTENDED_INFO module_info;
/* pointer to the array of dispatcher info used to synchonize threads */
PMODULE_DISPATCHER_HEADER dispatcher_info;
/* pointer to the array of dispatcher info used to synchonize threads */
PMODULE_DISPATCHER_HEADER dispatcher_info;
/* array of pointers to work items, used to free work items when
* complete */
PIO_WORKITEM work_items[VERIFICATION_THREAD_COUNT];
/* array of pointers to work items, used to free work items when
* complete */
PIO_WORKITEM work_items[VERIFICATION_THREAD_COUNT];
} SYS_MODULE_VAL_CONTEXT, *PSYS_MODULE_VAL_CONTEXT;
typedef enum _SMBIOS_TABLE_INDEX {
SmbiosInformation = 0,
SystemInformation,
VendorSpecificInformation,
ChassisInformation
SmbiosInformation = 0,
SystemInformation,
VendorSpecificInformation,
ChassisInformation
} SMBIOS_TABLE_INDEX;

File diff suppressed because it is too large Load diff

View file

@ -7,40 +7,40 @@
#include "common.h"
typedef struct _SHARED_MAPPING_INIT {
PVOID buffer;
SIZE_T size;
PVOID buffer;
SIZE_T size;
} SHARED_MAPPING_INIT, *PSHARED_MAPPING_INIT;
typedef enum _SHARED_STATE_OPERATION_ID {
ssRunNmiCallbacks = 0,
ssValidateDriverObjects,
ssEnumerateHandleTables,
ssScanForUnlinkedProcesses,
ssPerformModuleIntegrityCheck,
ssScanForAttachedThreads,
ssScanForEptHooks,
ssInitiateDpcStackwalk,
ssValidateSystemModules,
ssRunNmiCallbacks = 0,
ssValidateDriverObjects,
ssEnumerateHandleTables,
ssScanForUnlinkedProcesses,
ssPerformModuleIntegrityCheck,
ssScanForAttachedThreads,
ssScanForEptHooks,
ssInitiateDpcStackwalk,
ssValidateSystemModules,
} SHARED_STATE_OPERATION_ID;
typedef struct _SHARED_STATE {
volatile UINT32 status;
volatile UINT16 operation_id;
volatile UINT32 status;
volatile UINT16 operation_id;
} SHARED_STATE, *PSHARED_STATE;
typedef struct _SHARED_MAPPING {
volatile LONG work_item_status;
PVOID user_buffer;
PSHARED_STATE kernel_buffer;
PMDL mdl;
SIZE_T size;
volatile BOOLEAN active;
KTIMER timer;
KDPC timer_dpc;
PIO_WORKITEM work_item;
volatile LONG work_item_status;
PVOID user_buffer;
PSHARED_STATE kernel_buffer;
PMDL mdl;
SIZE_T size;
volatile BOOLEAN active;
KTIMER timer;
KDPC timer_dpc;
PIO_WORKITEM work_item;
} SHARED_MAPPING, *PSHARED_MAPPING;

View file

@ -29,8 +29,8 @@
VOID
ListInit(_Inout_ PSINGLE_LIST_ENTRY Head, _Inout_ PKGUARDED_MUTEX Lock)
{
ImpKeInitializeGuardedMutex(Lock);
Head->Next = NULL;
ImpKeInitializeGuardedMutex(Lock);
Head->Next = NULL;
}
VOID
@ -38,14 +38,14 @@ ListInsert(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY NewEntry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY old_entry = Head->Next;
PSINGLE_LIST_ENTRY old_entry = Head->Next;
Head->Next = NewEntry;
NewEntry->Next = old_entry;
Head->Next = NewEntry;
NewEntry->Next = old_entry;
ImpKeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
}
/*
@ -59,22 +59,22 @@ ListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine)
{
BOOLEAN result = FALSE;
ImpKeAcquireGuardedMutex(Lock);
BOOLEAN result = FALSE;
ImpKeAcquireGuardedMutex(Lock);
if (Head->Next) {
PSINGLE_LIST_ENTRY entry = Head->Next;
if (Head->Next) {
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
CallbackRoutine(entry);
if (CallbackRoutine)
CallbackRoutine(entry);
Head->Next = Head->Next->Next;
ImpExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
result = TRUE;
}
Head->Next = Head->Next->Next;
ImpExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
ImpKeReleaseGuardedMutex(Lock);
return result;
}
/*
@ -86,31 +86,31 @@ ListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PSINGLE_LIST_ENTRY entry = Head->Next;
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (!entry)
goto unlock;
if (entry == Entry) {
Head->Next = entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
if (entry == Entry) {
Head->Next = entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
while (entry->Next) {
if (entry->Next == Entry) {
entry->Next = Entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
while (entry->Next) {
if (entry->Next == Entry) {
entry->Next = Entry->Next;
ImpExFreePoolWithTag(Entry, POOL_TAG_THREAD_LIST);
goto unlock;
}
entry = entry->Next;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
}
VOID
@ -118,32 +118,32 @@ LookasideListRemoveEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_Inout_ PSINGLE_LIST_ENTRY Entry,
_In_ PKGUARDED_MUTEX Lock)
{
ImpKeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
PSINGLE_LIST_ENTRY entry = Head->Next;
PTHREAD_LIST_HEAD head = GetThreadList();
PSINGLE_LIST_ENTRY entry = Head->Next;
if (!entry)
goto unlock;
if (!entry)
goto unlock;
if (entry == Entry) {
Head->Next = entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
if (entry == Entry) {
Head->Next = entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
while (entry->Next) {
if (entry->Next == Entry) {
entry->Next = Entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
while (entry->Next) {
if (entry->Next == Entry) {
entry->Next = Entry->Next;
ExFreeToLookasideListEx(&head->lookaside_list, Entry);
goto unlock;
}
entry = entry->Next;
}
entry = entry->Next;
}
unlock:
ImpKeReleaseGuardedMutex(Lock);
ImpKeReleaseGuardedMutex(Lock);
}
BOOLEAN
@ -151,22 +151,22 @@ LookasideListFreeFirstEntry(_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKGUARDED_MUTEX Lock,
_In_opt_ FREE_LIST_ITEM_CALLBACK CallbackRoutine)
{
ImpKeAcquireGuardedMutex(Lock);
ImpKeAcquireGuardedMutex(Lock);
PTHREAD_LIST_HEAD head = GetThreadList();
BOOLEAN result = FALSE;
PTHREAD_LIST_HEAD head = GetThreadList();
BOOLEAN result = FALSE;
if (Head->Next) {
PSINGLE_LIST_ENTRY entry = Head->Next;
if (Head->Next) {
PSINGLE_LIST_ENTRY entry = Head->Next;
if (CallbackRoutine)
CallbackRoutine(entry);
if (CallbackRoutine)
CallbackRoutine(entry);
Head->Next = Head->Next->Next;
ExFreeToLookasideListEx(&head->lookaside_list, entry);
result = TRUE;
}
Head->Next = Head->Next->Next;
ExFreeToLookasideListEx(&head->lookaside_list, entry);
result = TRUE;
}
ImpKeReleaseGuardedMutex(Lock);
return result;
ImpKeReleaseGuardedMutex(Lock);
return result;
}

File diff suppressed because it is too large Load diff

View file

@ -8,30 +8,30 @@
#include "queue.h"
typedef struct _APC_OPERATION_ID {
int operation_id;
int operation_id;
} APC_OPERATION_ID, *PAPC_OPERATION_ID;
/* system modules information */
typedef struct _SYSTEM_MODULES {
PVOID address;
INT module_count;
PVOID address;
INT module_count;
} SYSTEM_MODULES, *PSYSTEM_MODULES;
#define APC_CONTEXT_ID_STACKWALK 0x1
typedef struct _APC_CONTEXT_HEADER {
LONG context_id;
volatile INT count;
volatile INT allocation_in_progress;
LONG context_id;
volatile INT count;
volatile INT allocation_in_progress;
} APC_CONTEXT_HEADER, *PAPC_CONTEXT_HEADER;
typedef struct _APC_STACKWALK_CONTEXT {
APC_CONTEXT_HEADER header;
PSYSTEM_MODULES modules;
APC_CONTEXT_HEADER header;
PSYSTEM_MODULES modules;
} APC_STACKWALK_CONTEXT, *PAPC_STACKWALK_CONTEXT;

File diff suppressed because it is too large Load diff

View file

@ -14,52 +14,52 @@
VOID
QueuePush(_Inout_ PQUEUE_HEAD Head, _In_ PVOID Data)
{
ImpKeAcquireGuardedMutex(&Head->lock);
ImpKeAcquireGuardedMutex(&Head->lock);
PQUEUE_NODE temp = ExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(QUEUE_NODE), QUEUE_POOL_TAG);
PQUEUE_NODE temp = ExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(QUEUE_NODE), QUEUE_POOL_TAG);
if (!temp)
goto end;
if (!temp)
goto end;
Head->entries += 1;
Head->entries += 1;
temp->data = Data;
temp->data = Data;
if (Head->end != NULL)
Head->end->next = temp;
if (Head->end != NULL)
Head->end->next = temp;
Head->end = temp;
Head->end = temp;
if (Head->start == NULL)
Head->start = temp;
if (Head->start == NULL)
Head->start = temp;
end:
ImpKeReleaseGuardedMutex(&Head->lock);
ImpKeReleaseGuardedMutex(&Head->lock);
}
PVOID
QueuePop(_Inout_ PQUEUE_HEAD Head)
{
ImpKeAcquireGuardedMutex(&Head->lock);
ImpKeAcquireGuardedMutex(&Head->lock);
PVOID data = NULL;
PQUEUE_NODE temp = Head->start;
PVOID data = NULL;
PQUEUE_NODE temp = Head->start;
if (temp == NULL)
goto end;
if (temp == NULL)
goto end;
Head->entries = Head->entries - 1;
Head->entries = Head->entries - 1;
data = temp->data;
Head->start = temp->next;
data = temp->data;
Head->start = temp->next;
if (Head->end == temp)
Head->end = NULL;
if (Head->end == temp)
Head->end = NULL;
ImpExFreePoolWithTag(temp, QUEUE_POOL_TAG);
ImpExFreePoolWithTag(temp, QUEUE_POOL_TAG);
end:
ImpKeReleaseGuardedMutex(&Head->lock);
return data;
ImpKeReleaseGuardedMutex(&Head->lock);
return data;
}

View file

@ -7,10 +7,10 @@
#define MAX_REPORTS_PER_IRP 20
typedef struct QUEUE_HEAD {
struct _QUEUE_NODE* start;
struct _QUEUE_NODE* end;
KGUARDED_MUTEX lock;
INT entries;
struct _QUEUE_NODE* start;
struct _QUEUE_NODE* end;
KGUARDED_MUTEX lock;
INT entries;
} QUEUE_HEAD, *PQUEUE_HEAD;
@ -23,25 +23,25 @@ typedef struct QUEUE_HEAD {
* of the spinlock.
*/
typedef struct _REPORT_QUEUE_HEAD {
QUEUE_HEAD head;
volatile BOOLEAN is_driver_unloading;
KGUARDED_MUTEX lock;
QUEUE_HEAD head;
volatile BOOLEAN is_driver_unloading;
KGUARDED_MUTEX lock;
} REPORT_QUEUE_HEAD, *PREPORT_QUEUE_HEAD;
typedef struct _QUEUE_NODE {
struct _QUEUE_NODE* next;
PVOID data;
struct _QUEUE_NODE* next;
PVOID data;
} QUEUE_NODE, *PQUEUE_NODE;
typedef struct _GLOBAL_REPORT_QUEUE_HEADER {
INT count;
INT count;
} GLOBAL_REPORT_QUEUE_HEADER, *PGLOBAL_REPORT_QUEUE_HEADER;
typedef struct _REPORT_HEADER {
INT report_id;
INT report_id;
} REPORT_HEADER, *PREPORT_HEADER;

View file

@ -5,180 +5,177 @@
/* for now, lets just xor the aes key with our cookie */
typedef struct _SESSION_INITIATION_PACKET {
UINT32 session_cookie;
CHAR session_aes_key[AES_128_KEY_SIZE];
PVOID protected_process_id;
UINT32 session_cookie;
CHAR session_aes_key[AES_128_KEY_SIZE];
PVOID protected_process_id;
} SESSION_INITIATION_PACKET, *PSESSION_INITIATION_PACKET;
VOID
SessionInitialiseStructure()
{
PAGED_CODE();
ImpKeInitializeGuardedMutex(&GetActiveSession()->lock);
PAGED_CODE();
ImpKeInitializeGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionInitialiseCallbackConfiguration()
{
PAGED_CODE();
InitialiseObCallbacksConfiguration(GetActiveSession());
PAGED_CODE();
InitialiseObCallbacksConfiguration(GetActiveSession());
}
VOID
SessionIsActive(_Out_ PBOOLEAN Flag)
{
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*Flag = GetActiveSession()->is_session_active;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*Flag = GetActiveSession()->is_session_active;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionGetProcess(_Out_ PEPROCESS* Process)
{
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*Process = GetActiveSession()->process;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*Process = GetActiveSession()->process;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionGetProcessId(_Out_ PLONG ProcessId)
{
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*ProcessId = GetActiveSession()->km_handle;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
PAGED_CODE();
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*ProcessId = GetActiveSession()->km_handle;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionGetCallbackConfiguration(
_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration)
{
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*CallbackConfiguration = &GetActiveSession()->callback_configuration;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
*CallbackConfiguration = &GetActiveSession()->callback_configuration;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionTerminate()
{
PAGED_CODE();
DEBUG_INFO("Termination active session.");
PAGED_CODE();
DEBUG_INFO("Termination active session.");
PACTIVE_SESSION session = GetActiveSession();
PACTIVE_SESSION session = GetActiveSession();
ImpKeAcquireGuardedMutex(&session->lock);
session->km_handle = NULL;
session->um_handle = NULL;
session->process = NULL;
session->is_session_active = FALSE;
ImpKeReleaseGuardedMutex(&session->lock);
ImpKeAcquireGuardedMutex(&session->lock);
session->km_handle = NULL;
session->um_handle = NULL;
session->process = NULL;
session->is_session_active = FALSE;
ImpKeReleaseGuardedMutex(&session->lock);
}
NTSTATUS
SessionInitialise(_In_ PIRP Irp)
{
PAGED_CODE();
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
PEPROCESS process = NULL;
PSESSION_INITIATION_PACKET information = NULL;
PACTIVE_SESSION session = GetActiveSession();
NTSTATUS status = STATUS_UNSUCCESSFUL;
PEPROCESS process = NULL;
PSESSION_INITIATION_PACKET information = NULL;
PACTIVE_SESSION session = GetActiveSession();
DEBUG_VERBOSE("Initialising new session.");
DEBUG_VERBOSE("Initialising new session.");
status = ValidateIrpInputBuffer(Irp, sizeof(SESSION_INITIATION_PACKET));
status = ValidateIrpInputBuffer(Irp, sizeof(SESSION_INITIATION_PACKET));
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x",
status);
return status;
}
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("ValidateIrpInputBuffer failed with status %x", status);
return status;
}
information =
(PSESSION_INITIATION_PACKET)Irp->AssociatedIrp.SystemBuffer;
information = (PSESSION_INITIATION_PACKET)Irp->AssociatedIrp.SystemBuffer;
ImpKeAcquireGuardedMutex(&session->lock);
ImpKeAcquireGuardedMutex(&session->lock);
session->um_handle = information->protected_process_id;
session->um_handle = information->protected_process_id;
/* What if we pass an invalid handle here? not good. */
status = ImpPsLookupProcessByProcessId(session->um_handle, &process);
/* What if we pass an invalid handle here? not good. */
status = ImpPsLookupProcessByProcessId(session->um_handle, &process);
if (!NT_SUCCESS(status)) {
status = STATUS_INVALID_PARAMETER;
goto end;
}
if (!NT_SUCCESS(status)) {
status = STATUS_INVALID_PARAMETER;
goto end;
}
session->km_handle = ImpPsGetProcessId(process);
session->process = process;
session->is_session_active = TRUE;
session->session_cookie = information->session_cookie;
session->km_handle = ImpPsGetProcessId(process);
session->process = process;
session->is_session_active = TRUE;
session->session_cookie = information->session_cookie;
RtlCopyMemory(session->session_aes_key,
information->session_aes_key,
AES_128_KEY_SIZE);
RtlCopyMemory(session->session_aes_key,
information->session_aes_key,
AES_128_KEY_SIZE);
end:
ImpKeReleaseGuardedMutex(&session->lock);
return status;
ImpKeReleaseGuardedMutex(&session->lock);
return status;
}
VOID
SessionTerminateProcess()
{
PAGED_CODE();
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG process_id = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG process_id = 0;
SessionGetProcessId(&process_id);
SessionGetProcessId(&process_id);
if (!process_id) {
DEBUG_ERROR(
"Failed to terminate process as process id is null");
return;
}
if (!process_id) {
DEBUG_ERROR("Failed to terminate process as process id is null");
return;
}
/* Make sure we pass a km handle to ZwTerminateProcess and NOT a
* usermode handle. */
status = ZwTerminateProcess(process_id,
STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION);
/* Make sure we pass a km handle to ZwTerminateProcess and NOT a
* usermode handle. */
status = ZwTerminateProcess(process_id,
STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION);
if (!NT_SUCCESS(status)) {
/*
* We don't want to clear the process config if
* ZwTerminateProcess fails so we can try again.
*/
DEBUG_ERROR("ZwTerminateProcess failed with status %x", status);
return;
}
/* this wont be needed when procloadstuff is implemented */
SessionTerminate();
if (!NT_SUCCESS(status)) {
/*
* We don't want to clear the process config if
* ZwTerminateProcess fails so we can try again.
*/
DEBUG_ERROR("ZwTerminateProcess failed with status %x", status);
return;
}
/* this wont be needed when procloadstuff is implemented */
SessionTerminate();
}
VOID
SessionIncrementIrpsProcessedCount()
{
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->irps_processed++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->irps_processed++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionIncrementReportCount()
{
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->report_count++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->report_count++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}
VOID
SessionIncrementHeartbeatCount()
{
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->heartbeat_count++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
ImpKeAcquireGuardedMutex(&GetActiveSession()->lock);
GetActiveSession()->heartbeat_count++;
ImpKeReleaseGuardedMutex(&GetActiveSession()->lock);
}

View file

@ -10,55 +10,55 @@
#include "imports.h"
#ifdef ALLOC_PRAGMA
# pragma alloc_text(PAGE, DetectThreadsAttachedToProtectedProcess)
# pragma alloc_text(PAGE, ValidateThreadsPspCidTableEntry)
# pragma alloc_text(PAGE, DetectThreadsAttachedToProtectedProcess)
# pragma alloc_text(PAGE, ValidateThreadsPspCidTableEntry)
#endif
BOOLEAN
ValidateThreadsPspCidTableEntry(_In_ PETHREAD Thread)
{
PAGED_CODE();
PAGED_CODE();
NTSTATUS status = STATUS_UNSUCCESSFUL;
HANDLE thread_id = NULL;
PETHREAD thread = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
HANDLE thread_id = NULL;
PETHREAD thread = NULL;
/*
* PsGetThreadId simply returns ETHREAD->Cid.UniqueThread
*/
thread_id = ImpPsGetThreadId(Thread);
/*
* For each core on the processor, the first x threads equal to x cores
* will be assigned a cid equal to its equivalent core. These threads
* are generally executing the HLT instruction or some other boring
* stuff while the processor is not busy. The reason this is important
* is because passing in a handle value of 0 which, even though is a
* valid cid, returns a non success status meaning we mark it an invalid
* cid entry even though it is. To combat this we simply add a little
* check here. The problem is this can be easily bypassed by simply
* modifying the ETHREAD->Cid.UniqueThread identifier.. So while it isnt
* a perfect detection method for now it's good enough.
*/
if ((UINT64)thread_id < (UINT64)ImpKeQueryActiveProcessorCount(NULL))
return TRUE;
/*
* PsLookupThreadByThreadId will use a threads id to find its cid entry,
* and return the pointer contained in the HANDLE_TABLE entry pointing
* to the thread object. Meaning if we pass a valid thread id which we
* retrieved above and dont receive a STATUS_SUCCESS the cid entry could
* potentially be removed or disrupted..
*/
status = ImpPsLookupThreadByThreadId(thread_id, &thread);
if (!NT_SUCCESS(status)) {
DEBUG_WARNING(
"Failed to lookup thread by id. PspCidTable entry potentially removed.");
return FALSE;
}
/*
* PsGetThreadId simply returns ETHREAD->Cid.UniqueThread
*/
thread_id = ImpPsGetThreadId(Thread);
/*
* For each core on the processor, the first x threads equal to x cores
* will be assigned a cid equal to its equivalent core. These threads
* are generally executing the HLT instruction or some other boring
* stuff while the processor is not busy. The reason this is important
* is because passing in a handle value of 0 which, even though is a
* valid cid, returns a non success status meaning we mark it an invalid
* cid entry even though it is. To combat this we simply add a little
* check here. The problem is this can be easily bypassed by simply
* modifying the ETHREAD->Cid.UniqueThread identifier.. So while it isnt
* a perfect detection method for now it's good enough.
*/
if ((UINT64)thread_id < (UINT64)ImpKeQueryActiveProcessorCount(NULL))
return TRUE;
/*
* PsLookupThreadByThreadId will use a threads id to find its cid entry,
* and return the pointer contained in the HANDLE_TABLE entry pointing
* to the thread object. Meaning if we pass a valid thread id which we
* retrieved above and dont receive a STATUS_SUCCESS the cid entry could
* potentially be removed or disrupted..
*/
status = ImpPsLookupThreadByThreadId(thread_id, &thread);
if (!NT_SUCCESS(status)) {
DEBUG_WARNING(
"Failed to lookup thread by id. PspCidTable entry potentially removed.");
return FALSE;
}
return TRUE;
}
/*
@ -79,55 +79,52 @@ STATIC VOID
DetectAttachedThreadsProcessCallback(_In_ PTHREAD_LIST_ENTRY ThreadListEntry,
_Inout_opt_ PVOID Context)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Context);
PKAPC_STATE apc_state = NULL;
PEPROCESS protected_process = NULL;
PKAPC_STATE apc_state = NULL;
PEPROCESS protected_process = NULL;
SessionGetProcess(&protected_process);
SessionGetProcess(&protected_process);
if (!protected_process)
return;
if (!protected_process)
return;
apc_state = (PKAPC_STATE)((UINT64)ThreadListEntry->thread +
KTHREAD_APC_STATE_OFFSET);
apc_state = (PKAPC_STATE)((UINT64)ThreadListEntry->thread +
KTHREAD_APC_STATE_OFFSET);
/*
* We don't care if a thread owned by our protected process is attached
*
* todo: this is filterless and will just report anything, need to have
* a look into what processes actually attach to real games
*/
if (!(apc_state->Process == protected_process &&
ThreadListEntry->owning_process != protected_process)) {
return;
}
/*
* We don't care if a thread owned by our protected process is attached
*
* todo: this is filterless and will just report anything, need to have
* a look into what processes actually attach to real games
*/
if (!(apc_state->Process == protected_process &&
ThreadListEntry->owning_process != protected_process)) {
return;
}
DEBUG_WARNING("Thread is attached to our protected process: %llx",
(UINT64)ThreadListEntry->thread);
DEBUG_WARNING("Thread is attached to our protected process: %llx",
(UINT64)ThreadListEntry->thread);
PATTACH_PROCESS_REPORT report =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED,
sizeof(ATTACH_PROCESS_REPORT),
REPORT_POOL_TAG);
PATTACH_PROCESS_REPORT report = ImpExAllocatePool2(
POOL_FLAG_NON_PAGED, sizeof(ATTACH_PROCESS_REPORT), REPORT_POOL_TAG);
if (!report)
return;
if (!report)
return;
report->report_code = REPORT_ILLEGAL_ATTACH_PROCESS;
report->thread_id = ImpPsGetThreadId(ThreadListEntry->thread);
report->thread_address = ThreadListEntry->thread;
report->report_code = REPORT_ILLEGAL_ATTACH_PROCESS;
report->thread_id = ImpPsGetThreadId(ThreadListEntry->thread);
report->thread_address = ThreadListEntry->thread;
if (!NT_SUCCESS(
IrpQueueCompleteIrp(report, sizeof(ATTACH_PROCESS_REPORT))))
DEBUG_ERROR("IrpQueueCompleteIrp failed with no status.");
if (!NT_SUCCESS(IrpQueueCompleteIrp(report, sizeof(ATTACH_PROCESS_REPORT))))
DEBUG_ERROR("IrpQueueCompleteIrp failed with no status.");
}
VOID
DetectThreadsAttachedToProtectedProcess()
{
PAGED_CODE();
DEBUG_VERBOSE("Detecting threads attached to our process...");
EnumerateThreadListWithCallbackRoutine(
DetectAttachedThreadsProcessCallback, NULL);
PAGED_CODE();
DEBUG_VERBOSE("Detecting threads attached to our process...");
EnumerateThreadListWithCallbackRoutine(DetectAttachedThreadsProcessCallback,
NULL);
}