static analysis stuf

This commit is contained in:
lhodges1 2023-10-10 05:19:51 +11:00
parent b2bed7dde8
commit d8ef7493b0
12 changed files with 176 additions and 22 deletions

View file

@ -37,8 +37,11 @@ EnumHandleCallback(
#pragma alloc_text(PAGE, EnumerateProcessHandles)
#pragma alloc_text(PAGE, EnumerateProcessListWithCallbackFunction)
#pragma alloc_text(PAGE, InitialiseThreadList)
#pragma alloc_text(PAGE, ExUnlockHandleTableEntry)
#endif
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
CleanupThreadListOnDriverUnload()
{
@ -59,18 +62,22 @@ CleanupThreadListOnDriverUnload()
* Important to remember the callback function will run at irql = DISPATCH_LEVEL since
* we hold the spinlock during enumeration.
*/
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(&thread_list->lock)
_Releases_lock_(&thread_list->lock)
_IRQL_restores_global_(irql, SpinLock)
VOID
EnumerateThreadListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
_In_opt_ PVOID Context
)
{
if (!CallbackRoutine)
return;
KIRQL irql = KeGetCurrentIrql();
KeAcquireSpinLock(&thread_list->lock, &irql);
if (!CallbackRoutine)
goto unlock;
PTHREAD_LIST_ENTRY entry = thread_list->start.Next;
while (entry)
@ -80,24 +87,31 @@ EnumerateThreadListWithCallbackRoutine(
entry = entry->list.Next;
}
unlock:
KeReleaseSpinLock(&thread_list->lock, irql);
}
NTSTATUS
InitialiseThreadList()
{
PAGED_CODE();
thread_list =
ExAllocatePool2(POOL_FLAG_NON_PAGED, sizeof(THREAD_LIST), POOL_TAG_THREAD_LIST);
if (!thread_list)
return STATUS_MEMORY_NOT_ALLOCATED;
thread_list->active = TRUE;
InterlockedExchange(&thread_list->active, TRUE);
ListInit(&thread_list->start, &thread_list->lock);
return STATUS_SUCCESS;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(&thread_list->lock)
_Releases_lock_(&thread_list->lock)
_IRQL_restores_global_(irql, SpinLock)
VOID
FindThreadListEntryByThreadAddress(
_In_ PKTHREAD Thread,
@ -131,6 +145,8 @@ ThreadCreateNotifyRoutine(
_In_ BOOLEAN Create
)
{
PAGED_CODE();
PTHREAD_LIST_ENTRY entry = NULL;
PKTHREAD thread = NULL;
PKPROCESS process = NULL;
@ -176,7 +192,7 @@ ObPostOpCallbackRoutine(
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
)
{
PAGED_CODE();
}
OB_PREOP_CALLBACK_STATUS
@ -185,6 +201,8 @@ ObPreOpCallbackRoutine(
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistrationContext);
/* access mask to completely strip permissions */
@ -357,6 +375,8 @@ EnumHandleCallback(
_In_ PVOID Context
)
{
PAGED_CODE();
PVOID object;
PVOID object_header;
POBJECT_TYPE object_type;

View file

@ -100,13 +100,29 @@ ThreadCreateNotifyRoutine(
_In_ BOOLEAN Create
);
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
CleanupThreadListOnDriverUnload();
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(&thread_list->lock)
_Releases_lock_(&thread_list->lock)
_IRQL_restores_global_(irql, SpinLock)
VOID
FindThreadListEntryByThreadAddress(
_In_ PKTHREAD Thread,
_Inout_ PTHREAD_LIST_ENTRY* Entry
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(&thread_list->lock)
_Releases_lock_(&thread_list->lock)
_IRQL_restores_global_(irql, SpinLock)
VOID
EnumerateThreadListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
_In_opt_ PVOID Context
);
#endif

View file

@ -60,7 +60,7 @@ DrvLoadInitialiseObCbConfig();
STATIC
VOID
DrvLoadInitialiseReportQueue(
_In_ PBOOLEAN Flag
_Out_ PBOOLEAN Flag
);
STATIC
@ -146,6 +146,8 @@ PROCESS_CONFIG process_config = { 0 };
VOID
TerminateProtectedProcessOnViolation()
{
PAGED_CODE();
NTSTATUS status;
ULONG process_id = 0;
@ -186,6 +188,8 @@ RegistryPathQueryCallbackRoutine(
IN PVOID EntryContext
)
{
PAGED_CODE();
UNICODE_STRING value_name;
UNICODE_STRING image_path = RTL_CONSTANT_STRING(L"ImagePath");
UNICODE_STRING display_name = RTL_CONSTANT_STRING(L"DisplayName");
@ -483,6 +487,8 @@ GetDriverName(
_Out_ LPCSTR* DriverName
)
{
PAGED_CODE();
if (DriverName == NULL)
return;
@ -497,6 +503,8 @@ GetDriverPath(
_Out_ PUNICODE_STRING DriverPath
)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DriverPath, sizeof(UNICODE_STRING));
RtlInitUnicodeString(DriverPath, driver_config.driver_path.Buffer);
@ -508,6 +516,8 @@ GetDriverRegistryPath(
_Out_ PUNICODE_STRING RegistryPath
)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(RegistryPath, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(RegistryPath, &driver_config.registry_path);
@ -519,6 +529,8 @@ GetDriverDeviceName(
_Out_ PUNICODE_STRING DeviceName
)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceName, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceName, &driver_config.device_name);
@ -530,6 +542,8 @@ GetDriverSymbolicLink(
_Out_ PUNICODE_STRING DeviceSymbolicLink
)
{
PAGED_CODE();
KeAcquireGuardedMutex(&driver_config.lock);
RtlZeroMemory(DeviceSymbolicLink, sizeof(UNICODE_STRING));
RtlCopyUnicodeString(DeviceSymbolicLink, &driver_config.device_symbolic_link);
@ -541,6 +555,8 @@ GetDriverConfigSystemInformation(
_Out_ PSYSTEM_INFORMATION* SystemInformation
)
{
PAGED_CODE();
if (SystemInformation == NULL)
return;
@ -555,6 +571,8 @@ ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
)
{
PAGED_CODE();
if (Flag == NULL)
return;
@ -568,6 +586,8 @@ GetProtectedProcessEProcess(
_Out_ PEPROCESS* Process
)
{
PAGED_CODE();
if (Process == NULL)
return;
@ -582,6 +602,8 @@ GetProtectedProcessId(
_Out_ PLONG ProcessId
)
{
PAGED_CODE();
KeAcquireGuardedMutex(&process_config.lock);
RtlZeroMemory(ProcessId, sizeof(LONG));
*ProcessId = process_config.km_handle;
@ -597,6 +619,8 @@ GetProtectedProcessId(
VOID
ProcCloseDisableObCallbacks()
{
PAGED_CODE();
KeAcquireGuardedMutex(&process_config.ob_cb_config.lock);
if (process_config.ob_cb_config.registration_handle)
@ -611,6 +635,8 @@ ProcCloseDisableObCallbacks()
VOID
ProcCloseClearProcessConfiguration()
{
PAGED_CODE();
DEBUG_LOG("Process closed, clearing driver process_configuration");
KeAcquireGuardedMutex(&process_config.lock);
process_config.km_handle = NULL;
@ -887,7 +913,7 @@ DrvLoadInitialiseObCbConfig()
STATIC
VOID
DrvLoadInitialiseReportQueue(
_In_ PBOOLEAN Flag
_Out_ PBOOLEAN Flag
)
{
InitialiseGlobalReportQueue(Flag);

View file

@ -78,6 +78,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>

View file

@ -87,6 +87,8 @@ PerformVirtualizationDetection(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
HYPERVISOR_DETECTION_REPORT report;
report.aperf_msr_timing_check = APERFMsrTimingCheck();
report.invd_emulation_check = TestINVDEmulation();

View file

@ -136,6 +136,8 @@ GetDriverImageSize(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
SYSTEM_MODULES modules = { 0 };
PRTL_MODULE_EXTENDED_INFO driver_info;
@ -169,6 +171,8 @@ GetModuleInformationByName(
_In_ LPCSTR ModuleName
)
{
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
SYSTEM_MODULES modules = { 0 };
PRTL_MODULE_EXTENDED_INFO driver_info;
@ -212,6 +216,8 @@ StoreModuleExecutableRegionsInBuffer(
_Inout_ PSIZE_T BytesWritten
)
{
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PIMAGE_DOS_HEADER dos_header;
PLOCAL_NT_HEADER nt_header;
@ -235,7 +241,7 @@ StoreModuleExecutableRegionsInBuffer(
*Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, ModuleSize + sizeof(INTEGRITY_CHECK_HEADER), POOL_TAG_INTEGRITY);
if (!*Buffer)
if (*Buffer == NULL)
return STATUS_MEMORY_NOT_ALLOCATED;
/*
@ -337,6 +343,8 @@ MapDiskImageIntoVirtualAddressSpace(
_Inout_ PSIZE_T Size
)
{
PAGED_CODE();
NTSTATUS status;
HANDLE file_handle;
OBJECT_ATTRIBUTES object_attributes;
@ -444,6 +452,8 @@ ComputeHashOfBuffer(
_Inout_ PULONG HashResultSize
)
{
PAGED_CODE();
/*
* Since the windows documentation for the BCrypt functions contain the worst variable naming scheme
* in existence, I will try to explain what they do. (for my sake and any readers who also aren't smart
@ -680,7 +690,7 @@ VerifyInMemoryImageVsDiskImage(
"driver.sys"
);
if (!NT_SUCCESS(status))
if (!NT_SUCCESS(status) || !module_info.ImageBase || !module_info.ImageSize)
{
DEBUG_ERROR("GetModuleInformationByName failed with status %x", status);
//TerminateProtectedProcessOnViolation();
@ -811,7 +821,7 @@ RetrieveInMemoryModuleExecutableSections(
"driver.sys"
);
if (!NT_SUCCESS(status))
if (!NT_SUCCESS(status) || !module_info.ImageBase || !module_info.ImageSize)
{
DEBUG_ERROR("GetModuleInformationByName failed with status %x", status);
return status;
@ -863,6 +873,8 @@ GetNextSMBIOSStructureInTable(
_Inout_ PSMBIOS_TABLE_HEADER* CurrentStructure
)
{
PAGED_CODE();
PCHAR string_section_start = (PCHAR)((UINT64)*CurrentStructure + (*CurrentStructure)->Length);
PCHAR current_char_in_strings = string_section_start;
PCHAR next_char_in_strings = string_section_start + 1;
@ -899,6 +911,8 @@ GetStringAtIndexFromSMBIOSTable(
_In_ SIZE_T BufferSize
)
{
PAGED_CODE();
INT current_string_char_index = 0;
INT string_count = 0;
PCHAR current_string_char = (PCHAR)((UINT64)Table + Table->Length);
@ -1041,6 +1055,8 @@ ValidateProcessLoadedModule(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
BOOLEAN bstatus;
PROCESS_MODULE_VALIDATION_RESULT validation_result;
@ -1191,6 +1207,8 @@ GetHardDiskDriveSerialNumber(
_In_ SIZE_T ConfigDrive0MaxSize
)
{
PAGED_CODE();
NTSTATUS status;
HANDLE handle;
OBJECT_ATTRIBUTES attributes;

View file

@ -47,6 +47,8 @@ DispatchApcOperation(
_In_ PAPC_OPERATION_ID Operation
)
{
PAGED_CODE();
NTSTATUS status;
switch (Operation->operation_id)
@ -77,6 +79,7 @@ DeviceControl(
)
{
UNREFERENCED_PARAMETER(DriverObject);
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack_location = IoGetCurrentIrpStackLocation(Irp);
@ -155,9 +158,6 @@ DeviceControl(
goto end;
}
/* KeWaitForSingleObject with infinite time must be called from IRQL <= APC_LEVEL */
PAGED_CODE();
KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
ZwClose(handle);
@ -249,8 +249,6 @@ DeviceControl(
goto end;
}
PAGED_CODE();
KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);;
ZwClose(handle);
@ -399,6 +397,8 @@ DeviceCreate(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
DEBUG_LOG("Handle opened to DonnaAC");
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;

View file

@ -191,6 +191,7 @@ ApcNormalRoutine(
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2);
_IRQL_always_function_min_(DISPATCH_LEVEL)
STATIC
VOID
ValidateThreadViaKernelApcCallback(
@ -229,6 +230,8 @@ FindSystemModuleByName(
_In_ PSYSTEM_MODULES SystemModules
)
{
PAGED_CODE();
if (!ModuleName || !SystemModules)
return STATUS_INVALID_PARAMETER;
@ -251,6 +254,8 @@ PopulateWhitelistedModuleBuffer(
_In_ PSYSTEM_MODULES SystemModules
)
{
PAGED_CODE();
if (!Buffer || !SystemModules)
return STATUS_INVALID_PARAMETER;
@ -287,6 +292,8 @@ ValidateDriverIOCTLDispatchRegion(
_Out_ PBOOLEAN Flag
)
{
PAGED_CODE();
if (!Modules || !Driver || !Flag || !WhitelistedRegions)
return STATUS_INVALID_PARAMETER;
@ -392,6 +399,8 @@ RemoveInvalidDriverFromList(
_Inout_ PINVALID_DRIVERS_HEAD InvalidDriversHead
)
{
PAGED_CODE();
if (InvalidDriversHead->first_entry)
{
PINVALID_DRIVER entry = InvalidDriversHead->first_entry;
@ -406,6 +415,8 @@ EnumerateInvalidDrivers(
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead
)
{
PAGED_CODE();
PINVALID_DRIVER entry = InvalidDriversHead->first_entry;
while (entry != NULL)
@ -1234,6 +1245,7 @@ FlipKThreadMiscFlagsFlag(
#define THREAD_STATE_WAIT 5
#define THREAD_STATE_INIT 0
_IRQL_always_function_min_(DISPATCH_LEVEL)
STATIC
VOID
ValidateThreadViaKernelApcCallback(

View file

@ -112,6 +112,8 @@ CheckIfProcessAllocationIsInProcessList(
PKDDEBUGGER_DATA64
GetGlobalDebuggerData()
{
PAGED_CODE();
CONTEXT context = { 0 };
PDUMP_HEADER dump_header = { 0 };
UINT64 thread_state;
@ -157,10 +159,11 @@ GetPsActiveProcessHead(
_Out_ PUINT64 Address
)
{
PAGED_CODE();
PKDDEBUGGER_DATA64 debugger_data = GetGlobalDebuggerData();
*Address = *(UINT64*)(debugger_data->PsActiveProcessHead);
ExFreePoolWithTag(debugger_data, POOL_DEBUGGER_DATA_TAG);
}
@ -206,6 +209,8 @@ ValidateIfAddressIsProcessStructure(
_In_ PPOOL_HEADER PoolHeader
)
{
PAGED_CODE();
UINT64 peak_virtual_size = NULL;
UINT64 dir_table_base = NULL;
UINT64 allocation_size = NULL;
@ -365,6 +370,8 @@ IsPhysicalAddressInPhysicalMemoryRange(
_In_ PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges
)
{
PAGED_CODE();
ULONG page_index = 0;
UINT64 start_address = 0;
UINT64 end_address = 0;
@ -392,6 +399,8 @@ EnumerateKernelLargePages(
_In_ ULONG ObjectIndex
)
{
PAGED_CODE();
/*
* Split the large pages up into blocks of 0x1000 and scan each block
*/

View file

@ -57,6 +57,10 @@ InitialiseGlobalReportQueue(
// return head;
//}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
VOID
QueuePush(
_Inout_ PQUEUE_HEAD Head,
@ -87,6 +91,10 @@ end:
KeReleaseSpinLock(&Head->lock, irql);
}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
PVOID
QueuePop(
_Inout_ PQUEUE_HEAD Head
@ -116,6 +124,10 @@ end:
return data;
}
_IRQL_raises_(APC_LEVEL)
_Acquires_lock_(&report_queue_config.lock)
_Releases_lock_(&report_queue_config.lock)
_IRQL_restores_global_(irql, GuardedMutex)
VOID
InsertReportToQueue(
_In_ PVOID Report
@ -156,6 +168,8 @@ HandlePeriodicGlobalReportQueueQuery(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
PVOID report = NULL;
INT count = 0;
GLOBAL_REPORT_QUEUE_HEADER header;
@ -293,6 +307,10 @@ ListInit(
Head->Next = NULL;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
VOID
ListInsert(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -311,6 +329,10 @@ ListInsert(
KeReleaseSpinLock(Lock, irql);
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
BOOLEAN
ListFreeFirstEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -333,6 +355,10 @@ ListFreeFirstEntry(
return result;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
VOID
ListRemoveEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,

View file

@ -36,12 +36,20 @@ typedef struct _REPORT_HEADER
#define LIST_POOL_TAG 'list'
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
VOID
QueuePush(
_Inout_ PQUEUE_HEAD Head,
_In_ PVOID Data
);
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
PVOID
QueuePop(
_Inout_ PQUEUE_HEAD Head
@ -52,6 +60,10 @@ InitialiseGlobalReportQueue(
_Out_ PBOOLEAN Status
);
_IRQL_raises_(APC_LEVEL)
_Acquires_lock_(&report_queue_config.lock)
_Releases_lock_(&report_queue_config.lock)
_IRQL_restores_global_(irql, GuardedMutex)
VOID
InsertReportToQueue(
_In_ PVOID Report
@ -71,6 +83,10 @@ ListInit(
_Inout_ PKSPIN_LOCK Lock
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
VOID
ListInsert(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -78,12 +94,20 @@ ListInsert(
_In_ PKSPIN_LOCK Lock
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
BOOLEAN
ListFreeFirstEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,
_In_ PKSPIN_LOCK Lock
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
VOID
ListRemoveEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -91,10 +115,4 @@ ListRemoveEntry(
_In_ PKSPIN_LOCK Lock
);
VOID
EnumerateThreadListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
_In_opt_ PVOID Context
);
#endif

View file

@ -21,6 +21,7 @@ typedef struct _KPRCB_THREAD_VALIDATION_CTX
}KPRCB_THREAD_VALIDATION_CTX, * PKPRCB_THREAD_VALIDATION_CTX;
_IRQL_always_function_min_(DISPATCH_LEVEL)
STATIC
VOID
KPRCBThreadValidationProcessCallback(
@ -74,6 +75,8 @@ ValidateKPCRBThreads(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
UINT64 kpcr;
UINT64 kprcb;
KAFFINITY old_affinity = { 0 };
@ -134,6 +137,7 @@ ValidateKPCRBThreads(
}
}
_IRQL_always_function_min_(DISPATCH_LEVEL)
STATIC
VOID
DetectAttachedThreadsProcessCallback(
@ -186,6 +190,8 @@ DetectAttachedThreadsProcessCallback(
*/
VOID DetectThreadsAttachedToProtectedProcess()
{
PAGED_CODE();
EnumerateThreadListWithCallbackRoutine(
DetectAttachedThreadsProcessCallback,
NULL