static anal stuff

This commit is contained in:
lhodges1 2023-10-11 00:52:42 +11:00
parent d8ef7493b0
commit 3ff97ceae9
13 changed files with 314 additions and 118 deletions

View file

@ -40,8 +40,6 @@ EnumHandleCallback(
#pragma alloc_text(PAGE, ExUnlockHandleTableEntry)
#endif
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
CleanupThreadListOnDriverUnload()
{
@ -62,10 +60,8 @@ 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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
EnumerateThreadListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,
@ -108,10 +104,8 @@ InitialiseThreadList()
return STATUS_SUCCESS;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(&thread_list->lock)
_Releases_lock_(&thread_list->lock)
_IRQL_restores_global_(irql, SpinLock)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
FindThreadListEntryByThreadAddress(
_In_ PKTHREAD Thread,
@ -145,8 +139,6 @@ ThreadCreateNotifyRoutine(
_In_ BOOLEAN Create
)
{
PAGED_CODE();
PTHREAD_LIST_ENTRY entry = NULL;
PKTHREAD thread = NULL;
PKPROCESS process = NULL;
@ -195,6 +187,9 @@ ObPostOpCallbackRoutine(
PAGED_CODE();
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(
_In_ PVOID RegistrationContext,
@ -570,6 +565,8 @@ EnumerateProcessListWithCallbackFunction(
_In_opt_ PVOID Context
)
{
PAGED_CODE();
UINT64 current_process;
PLIST_ENTRY process_list_head = NULL;
PLIST_ENTRY process_list_entry = NULL;

View file

@ -67,6 +67,9 @@ ObPostOpCallbackRoutine(
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
OB_PREOP_CALLBACK_STATUS
ObPreOpCallbackRoutine(
_In_ PVOID RegistrationContext,
@ -100,25 +103,19 @@ 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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
EnumerateThreadListWithCallbackRoutine(
_In_ PVOID CallbackRoutine,

View file

@ -15,6 +15,8 @@ VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject);
_Function_class_(DRIVER_INITIALIZE)
_IRQL_requires_same_
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
@ -99,6 +101,7 @@ DrvLoadInitialiseDriverConfig(
#pragma alloc_text(PAGE, DrvLoadInitialiseReportQueue)
#pragma alloc_text(PAGE, DrvLoadInitialiseProcessConfig)
#pragma alloc_text(PAGE, DrvLoadInitialiseDriverConfig)
#pragma alloc_text(PAGE, ReadProcessInitialisedConfigFlag)
#endif
#define MAXIMUM_APC_CONTEXTS 10
@ -280,6 +283,8 @@ unlock:
return result;
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
IncrementApcCount(
_In_ LONG ContextId
@ -297,6 +302,8 @@ IncrementApcCount(
KeReleaseSpinLock(&driver_config.spin_lock, irql);
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
FreeApcAndDecrementApcCount(
_Inout_ PRKAPC Apc,
@ -341,6 +348,8 @@ end:
* the count is 0 and allocation_in_progress is 0. We can then call this function alongside
* other query callbacks via IOCTL to constantly monitor the status of open APC contexts.
*/
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
NTSTATUS
QueryActiveApcContextsForCompletion()
{
@ -382,6 +391,8 @@ QueryActiveApcContextsForCompletion()
return STATUS_SUCCESS;
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
NTSTATUS
InsertApcContext(
_In_ PVOID Context
@ -418,6 +429,8 @@ end:
return status;
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
GetApcContext(
_Inout_ PVOID* Context,
@ -445,6 +458,8 @@ unlock:
KeReleaseSpinLock(&driver_config.spin_lock, irql);
}
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
GetApcContextByIndex(
_Inout_ PVOID* Context,
@ -467,7 +482,9 @@ GetApcContextByIndex(
* Config getters
*
*/
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetCallbackConfigStructure(
_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration
@ -482,6 +499,9 @@ GetCallbackConfigStructure(
KeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverName(
_Out_ LPCSTR* DriverName
@ -498,6 +518,9 @@ GetDriverName(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverPath(
_Out_ PUNICODE_STRING DriverPath
@ -511,6 +534,9 @@ GetDriverPath(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverRegistryPath(
_Out_ PUNICODE_STRING RegistryPath
@ -524,6 +550,9 @@ GetDriverRegistryPath(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverDeviceName(
_Out_ PUNICODE_STRING DeviceName
@ -537,6 +566,9 @@ GetDriverDeviceName(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverSymbolicLink(
_Out_ PUNICODE_STRING DeviceSymbolicLink
@ -550,6 +582,9 @@ GetDriverSymbolicLink(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverConfigSystemInformation(
_Out_ PSYSTEM_INFORMATION* SystemInformation
@ -566,6 +601,9 @@ GetDriverConfigSystemInformation(
KeReleaseGuardedMutex(&driver_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
@ -581,6 +619,9 @@ ReadProcessInitialisedConfigFlag(
KeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetProtectedProcessEProcess(
_Out_ PEPROCESS* Process
@ -597,6 +638,9 @@ GetProtectedProcessEProcess(
KeReleaseGuardedMutex(&process_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetProtectedProcessId(
_Out_ PLONG ProcessId
@ -616,6 +660,9 @@ GetProtectedProcessId(
*
*/
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ProcCloseDisableObCallbacks()
{
@ -632,6 +679,9 @@ ProcCloseDisableObCallbacks()
KeReleaseGuardedMutex(&process_config.ob_cb_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ProcCloseClearProcessConfiguration()
{
@ -660,9 +710,14 @@ ProcCloseClearProcessConfiguration()
* aswell as the sturcture being paged out as we allocate in a non-paged pool meaning theres no
* chance our mutex will cause an IRQL bug check due to being paged out during acquisition.
*/
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
ProcLoadEnableObCallbacks()
{
PAGED_CODE();
NTSTATUS status;
KeAcquireGuardedMutex(&process_config.lock);
@ -705,11 +760,16 @@ end:
return status;
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
ProcLoadInitialiseProcessConfig(
_In_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
PEPROCESS eprocess;
PDRIVER_INITIATION_INFORMATION information;
@ -752,6 +812,8 @@ STATIC
VOID
DrvUnloadUnregisterObCallbacks()
{
PAGED_CODE();
ProcCloseDisableObCallbacks();
}
@ -778,6 +840,8 @@ DrvUnloadUnregisterObCallbacks()
* It's important to remember that the driver can unload when pending APC's have not been freed due to the
* limitations windows places on APCs, however I am in the process of finding a solution for this.
*/
_Acquires_lock_(driver_config.spin_lock)
_Releases_lock_(driver_config.spin_lock)
STATIC
BOOLEAN
DrvUnloadFreeAllApcContextStructures()
@ -814,6 +878,8 @@ STATIC
VOID
DrvUnloadFreeConfigStrings()
{
PAGED_CODE();
if (driver_config.unicode_driver_name.Buffer)
ExFreePoolWithTag(driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS);
@ -828,6 +894,8 @@ STATIC
VOID
DrvUnloadFreeSymbolicLink()
{
PAGED_CODE();
IoDeleteSymbolicLink(&driver_config.device_symbolic_link);
}
@ -835,6 +903,8 @@ STATIC
VOID
DrvUnloadFreeGlobalReportQueue()
{
PAGED_CODE();
FreeGlobalReportQueueObjects();
}
@ -842,6 +912,8 @@ STATIC
VOID
DrvUnloadFreeThreadList()
{
PAGED_CODE();
CleanupThreadListOnDriverUnload();
}
@ -880,6 +952,8 @@ STATIC
NTSTATUS
DrvLoadEnableNotifyRoutines()
{
PAGED_CODE();
NTSTATUS status;
status = InitialiseThreadList();
@ -902,6 +976,7 @@ STATIC
NTSTATUS
DrvLoadInitialiseObCbConfig()
{
PAGED_CODE();
/*
* This mutex ensures we don't unregister our ObRegisterCallbacks while
* the callback function is running since this might cause some funny stuff
@ -916,6 +991,8 @@ DrvLoadInitialiseReportQueue(
_Out_ PBOOLEAN Flag
)
{
PAGED_CODE();
InitialiseGlobalReportQueue(Flag);
}
@ -923,6 +1000,8 @@ STATIC
VOID
DrvLoadInitialiseProcessConfig()
{
PAGED_CODE();
KeInitializeGuardedMutex(&process_config.lock);
}
@ -932,6 +1011,8 @@ DrvLoadInitialiseDriverConfig(
_In_ PUNICODE_STRING RegistryPath
)
{
PAGED_CODE();
NTSTATUS status;
/* 3rd page acts as a null terminator for the callback routine */
@ -1028,6 +1109,8 @@ DrvLoadInitialiseDriverConfig(
return status;
}
_Function_class_(DRIVER_INITIALIZE)
_IRQL_requires_same_
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,

View file

@ -33,96 +33,151 @@ typedef struct _OB_CALLBACKS_CONFIG
}OB_CALLBACKS_CONFIG, * POB_CALLBACKS_CONFIG;
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
ProcLoadInitialiseProcessConfig(
_In_ PIRP Irp
);
VOID GetProtectedProcessEProcess(
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetProtectedProcessEProcess(
_Out_ PEPROCESS* Process
);
VOID GetProtectedProcessId(
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetProtectedProcessId(
_Out_ PLONG ProcessId
);
VOID ReadProcessInitialisedConfigFlag(
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ReadProcessInitialisedConfigFlag(
_Out_ PBOOLEAN Flag
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID GetDriverPath(
_Out_ PUNICODE_STRING DriverPath
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID GetDriverConfigSystemInformation(
_Out_ PSYSTEM_INFORMATION* SystemInformation
);
VOID GetApcContext(
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
GetApcContext(
_Inout_ PVOID* Context,
_In_ LONG ContextIdentifier
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
NTSTATUS
InsertApcContext(
_In_ PVOID Context
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
GetApcContextByIndex(
_Inout_ PVOID* Context,
_In_ INT Index
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
IncrementApcCount(
_In_ LONG ContextId
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
FreeApcAndDecrementApcCount(
_Inout_ PRKAPC Apc,
_In_ LONG ContextId
);
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
NTSTATUS
QueryActiveApcContextsForCompletion(
);
QueryActiveApcContextsForCompletion();
VOID
TerminateProtectedProcessOnViolation();
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
ProcLoadEnableObCallbacks();
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ProcCloseDisableObCallbacks();
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
ProcCloseClearProcessConfiguration();
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetCallbackConfigStructure(
_Out_ POB_CALLBACKS_CONFIG* CallbackConfiguration
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverDeviceName(
_Out_ PUNICODE_STRING DeviceName
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverRegistryPath(
_Out_ PUNICODE_STRING RegistryPath
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverName(
_Out_ LPCSTR* DriverName
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
GetDriverSymbolicLink(
_Out_ PUNICODE_STRING DeviceSymbolicLink

View file

@ -79,6 +79,7 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
@ -105,6 +106,7 @@
</DriverSign>
<ClCompile>
<TreatWarningAsError>false</TreatWarningAsError>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<Link />
<Link>

View file

@ -56,26 +56,26 @@ GetModuleInformationByName(
STATIC
NTSTATUS
StoreModuleExecutableRegionsInBuffer(
_Inout_ PVOID* Buffer,
_Outptr_result_bytebuffer_(*BytesWritten) PVOID* Buffer,
_In_ PVOID ModuleBase,
_In_ SIZE_T ModuleSize,
_Inout_ PSIZE_T BytesWritten);
_Out_ _Deref_out_range_(>,0) PSIZE_T BytesWritten);
STATIC
NTSTATUS
MapDiskImageIntoVirtualAddressSpace(
_Inout_ PHANDLE SectionHandle,
_Inout_ PVOID* Section,
_Outptr_result_bytebuffer_(*Size) PVOID* Section,
_In_ PUNICODE_STRING Path,
_Inout_ PSIZE_T Size);
_Out_ _Deref_out_range_(>,0) PSIZE_T Size);
STATIC
NTSTATUS
ComputeHashOfBuffer(
_In_ PVOID Buffer,
_In_ ULONG BufferSize,
_Inout_ PVOID* HashResult,
_Inout_ PULONG HashResultSize);
_Outptr_result_bytebuffer_(*HashResultSize) PVOID* HashResult,
_Out_ _Deref_out_range_(>,0)PULONG HashResultSize);
STATIC
VOID
@ -94,7 +94,7 @@ STATIC
NTSTATUS
GetAverageReadTimeAtRoutine(
_In_ PVOID RoutineAddress,
_Inout_ PUINT64 AverageTime);
_Out_ PUINT64 AverageTime);
STATIC
NTSTATUS
@ -120,7 +120,6 @@ RegistryPathQueryTestSigningCallback(
#pragma alloc_text(PAGE, ValidateProcessLoadedModule)
#pragma alloc_text(PAGE, GetHardDiskDriveSerialNumber)
#pragma alloc_text(PAGE, ScanForSignature)
#pragma alloc_text(PAGE, GetAverageReadTimeAtRoutine)
#pragma alloc_text(PAGE, InitiateEptFunctionAddressArrays)
#pragma alloc_text(PAGE, DetectEptHooksInKeyFunctions)
#pragma alloc_text(PAGE, RegistryPathQueryTestSigningCallback)
@ -210,10 +209,10 @@ GetModuleInformationByName(
STATIC
NTSTATUS
StoreModuleExecutableRegionsInBuffer(
_Inout_ PVOID* Buffer,
_Outptr_result_bytebuffer_(*BytesWritten) PVOID* Buffer,
_In_ PVOID ModuleBase,
_In_ SIZE_T ModuleSize,
_Inout_ PSIZE_T BytesWritten
_Out_ _Deref_out_range_(>,0) PSIZE_T BytesWritten
)
{
PAGED_CODE();
@ -227,7 +226,8 @@ StoreModuleExecutableRegionsInBuffer(
ULONG num_executable_sections = 0;
UINT64 buffer_base;
ULONG bytes_returned;
MM_COPY_ADDRESS address;
MM_COPY_ADDRESS address = { 0 };
ULONG buffer_size;
if (!ModuleBase || !ModuleSize)
return STATUS_INVALID_PARAMETER;
@ -239,7 +239,10 @@ StoreModuleExecutableRegionsInBuffer(
* enumerate and count all executable sections for the file.
*/
*Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, ModuleSize + sizeof(INTEGRITY_CHECK_HEADER), POOL_TAG_INTEGRITY);
buffer_size = ModuleSize + sizeof(INTEGRITY_CHECK_HEADER);
*BytesWritten = 0;
*Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, buffer_size, POOL_TAG_INTEGRITY);
if (*Buffer == NULL)
return STATUS_MEMORY_NOT_ALLOCATED;
@ -338,9 +341,9 @@ STATIC
NTSTATUS
MapDiskImageIntoVirtualAddressSpace(
_Inout_ PHANDLE SectionHandle,
_Inout_ PVOID* Section,
_Outptr_result_bytebuffer_(*Size) PVOID* Section,
_In_ PUNICODE_STRING Path,
_Inout_ PSIZE_T Size
_Out_ _Deref_out_range_(>,0) PSIZE_T Size
)
{
PAGED_CODE();
@ -351,6 +354,9 @@ MapDiskImageIntoVirtualAddressSpace(
PIO_STATUS_BLOCK pio_block;
UNICODE_STRING path;
*Section = NULL;
*Size = 0;
RtlInitUnicodeString(&path, Path->Buffer);
InitializeObjectAttributes(
@ -373,7 +379,6 @@ MapDiskImageIntoVirtualAddressSpace(
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("ZwOpenFile failed with statsu %x", status);
//TerminateProtectedProcessOnViolation();
return status;
}
@ -398,7 +403,6 @@ MapDiskImageIntoVirtualAddressSpace(
DEBUG_ERROR("ZwCreateSection failed with status %x", status);
ZwClose(file_handle);
*SectionHandle = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -432,10 +436,12 @@ MapDiskImageIntoVirtualAddressSpace(
* and will cause a double free.
*/
DEBUG_ERROR("ZwMapViewOfSection failed with status %x", status);
ZwClose(file_handle);
ZwClose(*SectionHandle);
*SectionHandle = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -448,8 +454,8 @@ NTSTATUS
ComputeHashOfBuffer(
_In_ PVOID Buffer,
_In_ ULONG BufferSize,
_Inout_ PVOID* HashResult,
_Inout_ PULONG HashResultSize
_Outptr_result_bytebuffer_(*HashResultSize) PVOID* HashResult,
_Out_ _Deref_out_range_(>,0) PULONG HashResultSize
)
{
PAGED_CODE();
@ -477,6 +483,9 @@ ComputeHashOfBuffer(
PCHAR hash_object = NULL;
PCHAR resulting_hash = NULL;
*HashResult = NULL;
*HashResultSize = 0;
status = BCryptOpenAlgorithmProvider(
&algo_handle,
BCRYPT_SHA256_ALGORITHM,
@ -633,6 +642,8 @@ VerifyInMemoryImageVsDiskImage(
//_In_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
UNICODE_STRING path = { 0 };
HANDLE section_handle = NULL;
@ -811,6 +822,8 @@ RetrieveInMemoryModuleExecutableSections(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
SIZE_T bytes_written = NULL;
PVOID buffer = NULL;
@ -957,6 +970,8 @@ ParseSMBIOSTable(
_In_ SIZE_T ConfigMotherboardSerialNumberMaxSize
)
{
PAGED_CODE();
NTSTATUS status;
PVOID firmware_table_buffer;
ULONG firmware_table_buffer_size = NULL;
@ -1378,6 +1393,8 @@ ScanForSignature(
_In_ SIZE_T SignatureLength
)
{
PAGED_CODE();
CHAR current_char = 0;
CHAR current_sig_char = 0;
@ -1467,7 +1484,7 @@ STATIC
NTSTATUS
GetAverageReadTimeAtRoutine(
_In_ PVOID RoutineAddress,
_Inout_ PUINT64 AverageTime
_Out_ PUINT64 AverageTime
)
{
if (!RoutineAddress || !AverageTime)
@ -1526,6 +1543,8 @@ STATIC
NTSTATUS
InitiateEptFunctionAddressArrays()
{
PAGED_CODE();
UNICODE_STRING current_function;
for (INT index = 0; index < EPT_CONTROL_FUNCTIONS_COUNT; index++)
@ -1552,6 +1571,8 @@ InitiateEptFunctionAddressArrays()
NTSTATUS
DetectEptHooksInKeyFunctions()
{
PAGED_CODE();
NTSTATUS status;
UINT32 control_fails = 0;
UINT64 instruction_time = 0;
@ -1640,6 +1661,8 @@ RegistryPathQueryTestSigningCallback(
IN PVOID EntryContext
)
{
PAGED_CODE();
PSYSTEM_START_OPTIONS context = (PSYSTEM_START_OPTIONS)Context;
UNICODE_STRING flag = RTL_CONSTANT_STRING(L"TESTSIGNING");
UNICODE_STRING key = RTL_CONSTANT_STRING(L"SystemStartOptions");
@ -1668,6 +1691,8 @@ DetermineIfTestSigningIsEnabled(
_Inout_ PBOOLEAN Result
)
{
PAGED_CODE();
NTSTATUS status;
SYSTEM_START_OPTIONS start_options = { 0 };
RTL_QUERY_REGISTRY_TABLE query_table[2] = { 0 };

View file

@ -36,9 +36,6 @@ ParseSMBIOSTable(
_In_ SIZE_T ConfigMotherboardSerialNumberMaxSize
);
VOID
EnumeratePciDevices();
NTSTATUS
DetectEptHooksInKeyFunctions();

View file

@ -72,6 +72,7 @@ DispatchApcOperation(
return status;
}
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
@ -367,12 +368,15 @@ end:
return status;
}
_Dispatch_type_(IRP_MJ_CLOSE)
NTSTATUS
DeviceClose(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(DeviceObject);
DEBUG_LOG("Handle closed to DonnaAC");
@ -391,6 +395,7 @@ DeviceClose(
return Irp->IoStatus.Status;
}
_Dispatch_type_(IRP_MJ_CREATE)
NTSTATUS
DeviceCreate(
_In_ PDEVICE_OBJECT DeviceObject,

View file

@ -12,18 +12,21 @@ typedef struct _DRIVER_INITIATION_INFORMATION
} DRIVER_INITIATION_INFORMATION, * PDRIVER_INITIATION_INFORMATION;
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
NTSTATUS
DeviceControl(
_In_ PDRIVER_OBJECT DriverObject,
_Inout_ PIRP Irp
);
_Dispatch_type_(IRP_MJ_CLOSE)
NTSTATUS
DeviceClose(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp
);
_Dispatch_type_(IRP_MJ_CREATE)
NTSTATUS
DeviceCreate(
_In_ PDEVICE_OBJECT DeviceObject,

View file

@ -152,6 +152,9 @@ ValidateDriverObjectHasBackingModule(
_In_ PDRIVER_OBJECT DriverObject,
_Out_ PBOOLEAN Result);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_critical_section_)
_Releases_lock_(_Lock_kind_critical_section_)
STATIC
NTSTATUS
ValidateDriverObjects(
@ -170,11 +173,13 @@ NTSTATUS
LaunchNonMaskableInterrupt(
_Inout_ PNMI_CONTEXT NmiContext);
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcRundownRoutine(
_In_ PRKAPC Apc);
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcKernelRoutine(
@ -184,6 +189,7 @@ ApcKernelRoutine(
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument1,
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument2);
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcNormalRoutine(
@ -191,7 +197,7 @@ ApcNormalRoutine(
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2);
_IRQL_always_function_min_(DISPATCH_LEVEL)
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ValidateThreadViaKernelApcCallback(
@ -219,6 +225,7 @@ ValidateThreadViaKernelApcCallback(
#pragma alloc_text(PAGE, ApcNormalRoutine)
#pragma alloc_text(PAGE, FlipKThreadMiscFlagsFlag)
#pragma alloc_text(PAGE, ValidateThreadsViaKernelApc)
#pragma alloc_text(PAGE, ValidateThreadViaKernelApcCallback)
#endif
/*
@ -366,6 +373,8 @@ InitDriverList(
_Inout_ PINVALID_DRIVERS_HEAD ListHead
)
{
PAGED_CODE();
ListHead->count = 0;
ListHead->first_entry = NULL;
}
@ -378,6 +387,8 @@ AddDriverToList(
_In_ INT Reason
)
{
PAGED_CODE();
PINVALID_DRIVER new_entry = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
sizeof(INVALID_DRIVER),
@ -434,6 +445,8 @@ ValidateDriverObjectHasBackingModule(
_Out_ PBOOLEAN Result
)
{
PAGED_CODE();
if (!ModuleInformation || !DriverObject || !Result)
return STATUS_INVALID_PARAMETER;
@ -461,6 +474,8 @@ GetSystemModuleInformation(
_Inout_ PSYSTEM_MODULES ModuleInformation
)
{
PAGED_CODE();
if (!ModuleInformation)
return STATUS_INVALID_PARAMETER;
@ -511,6 +526,9 @@ GetSystemModuleInformation(
return STATUS_SUCCESS;
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_critical_section_)
_Releases_lock_(_Lock_kind_critical_section_)
STATIC
NTSTATUS
ValidateDriverObjects(
@ -518,6 +536,8 @@ ValidateDriverObjects(
_Inout_ PINVALID_DRIVERS_HEAD InvalidDriverListHead
)
{
PAGED_CODE();
if (!SystemModules || !InvalidDriverListHead)
return STATUS_INVALID_PARAMETER;
@ -675,6 +695,8 @@ HandleValidateDriversIOCTL(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
SYSTEM_MODULES system_modules = { 0 };
@ -806,6 +828,8 @@ IsInstructionPointerInInvalidRegion(
_Out_ PBOOLEAN Result
)
{
PAGED_CODE();
if (!RIP || !SystemModules || !Result)
return STATUS_INVALID_PARAMETER;
@ -837,6 +861,8 @@ AnalyseNmiData(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
if (!NmiContext || !SystemModules)
return STATUS_INVALID_PARAMETER;
@ -916,6 +942,7 @@ AnalyseNmiData(
return STATUS_SUCCESS;
}
_IRQL_requires_max_(HIGH_LEVEL)
STATIC
BOOLEAN
NmiCallback(
@ -977,6 +1004,8 @@ LaunchNonMaskableInterrupt(
_Inout_ PNMI_CONTEXT NmiContext
)
{
PAGED_CODE();
if (!NmiContext)
return STATUS_INVALID_PARAMETER;
@ -1032,6 +1061,8 @@ HandleNmiIOCTL(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
NTSTATUS status;
SYSTEM_MODULES system_modules = { 0 };
NMI_CONTEXT nmi_context = { 0 };
@ -1105,12 +1136,15 @@ HandleNmiIOCTL(
* The RundownRoutine is executed if the thread terminates before the APC was delivered to
* user mode.
*/
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcRundownRoutine(
_In_ PRKAPC Apc
)
{
PAGED_CODE();
FreeApcAndDecrementApcCount(Apc, APC_CONTEXT_ID_STACKWALK);
}
@ -1118,6 +1152,7 @@ ApcRundownRoutine(
* The KernelRoutine is executed in kernel mode at APC_LEVEL before the APC is delivered. This
* is also where we want to free our APC object.
*/
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcKernelRoutine(
@ -1128,6 +1163,8 @@ ApcKernelRoutine(
_Inout_ _Deref_pre_maybenull_ PVOID* SystemArgument2
)
{
PAGED_CODE();
PVOID buffer = NULL;
INT frames_captured = 0;
UINT64 stack_frame = 0;
@ -1214,6 +1251,7 @@ free:
/*
* The NormalRoutine is executed in user mode when the APC is delivered.
*/
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ApcNormalRoutine(
@ -1222,7 +1260,7 @@ ApcNormalRoutine(
_In_opt_ PVOID SystemArgument2
)
{
PAGED_CODE();
}
VOID
@ -1232,6 +1270,8 @@ FlipKThreadMiscFlagsFlag(
_In_ BOOLEAN NewValue
)
{
PAGED_CODE();
PLONG misc_flags = (PLONG)((UINT64)Thread + KTHREAD_MISC_FLAGS_OFFSET);
LONG mask = 1U << FlagIndex;
@ -1245,7 +1285,7 @@ FlipKThreadMiscFlagsFlag(
#define THREAD_STATE_WAIT 5
#define THREAD_STATE_INIT 0
_IRQL_always_function_min_(DISPATCH_LEVEL)
_IRQL_requires_max_(APC_LEVEL)
STATIC
VOID
ValidateThreadViaKernelApcCallback(
@ -1253,6 +1293,8 @@ ValidateThreadViaKernelApcCallback(
_Inout_opt_ PVOID Context
)
{
PAGED_CODE();
PKAPC apc = NULL;
BOOLEAN apc_status = FALSE;
PLONG misc_flags = NULL;
@ -1376,6 +1418,8 @@ ValidateThreadViaKernelApcCallback(
NTSTATUS
ValidateThreadsViaKernelApc()
{
PAGED_CODE();
NTSTATUS status;
PAPC_STACKWALK_CONTEXT context = NULL;

View file

@ -99,11 +99,6 @@ CheckIfProcessAllocationIsInProcessList(
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, GetGlobalDebuggerData)
#pragma alloc_text(PAGE, GetPsActiveProcessHead)
#pragma alloc_text(PAGE, ValidateIfAddressIsProcessStructure)
#pragma alloc_text(PAGE, ScanPageForKernelObjectAllocation)
#pragma alloc_text(PAGE, IsPhysicalAddressInPhysicalMemoryRange)
#pragma alloc_text(PAGE, EnumerateKernelLargePages)
#pragma alloc_text(PAGE, WalkKernelPageTables)
#pragma alloc_text(PAGE, IncrementProcessCounter)
#pragma alloc_text(PAGE, CheckIfProcessAllocationIsInProcessList)
#pragma alloc_text(PAGE, FindUnlinkedProcesses)
@ -161,8 +156,13 @@ GetPsActiveProcessHead(
{
PAGED_CODE();
*Address = NULL;
PKDDEBUGGER_DATA64 debugger_data = GetGlobalDebuggerData();
if (!debugger_data)
return;
*Address = *(UINT64*)(debugger_data->PsActiveProcessHead);
ExFreePoolWithTag(debugger_data, POOL_DEBUGGER_DATA_TAG);
}
@ -209,8 +209,6 @@ ValidateIfAddressIsProcessStructure(
_In_ PPOOL_HEADER PoolHeader
)
{
PAGED_CODE();
UINT64 peak_virtual_size = NULL;
UINT64 dir_table_base = NULL;
UINT64 allocation_size = NULL;
@ -370,8 +368,6 @@ IsPhysicalAddressInPhysicalMemoryRange(
_In_ PPHYSICAL_MEMORY_RANGE PhysicalMemoryRanges
)
{
PAGED_CODE();
ULONG page_index = 0;
UINT64 start_address = 0;
UINT64 end_address = 0;
@ -399,8 +395,6 @@ EnumerateKernelLargePages(
_In_ ULONG ObjectIndex
)
{
PAGED_CODE();
/*
* Split the large pages up into blocks of 0x1000 and scan each block
*/
@ -627,6 +621,8 @@ IncrementProcessCounter(
_Inout_opt_ PVOID Context
)
{
PAGED_CODE();
PPROCESS_SCAN_CONTEXT context = (PPROCESS_SCAN_CONTEXT)Context;
if (!context)
@ -642,6 +638,8 @@ CheckIfProcessAllocationIsInProcessList(
_Inout_opt_ PVOID Context
)
{
PAGED_CODE();
PUINT64 allocation_address;
PPROCESS_SCAN_CONTEXT context = (PPROCESS_SCAN_CONTEXT)Context;
@ -665,6 +663,8 @@ FindUnlinkedProcesses(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
PUINT64 allocation_address;
PROCESS_SCAN_CONTEXT context = { 0 };
PINVALID_PROCESS_ALLOCATION_REPORT report_buffer = NULL;

View file

@ -57,10 +57,8 @@ InitialiseGlobalReportQueue(
// return head;
//}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
QueuePush(
_Inout_ PQUEUE_HEAD Head,
@ -91,10 +89,8 @@ end:
KeReleaseSpinLock(&Head->lock, irql);
}
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Acquires_lock_(Head->lock)
_Releases_lock_(Head->lock)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
PVOID
QueuePop(
_Inout_ PQUEUE_HEAD Head
@ -124,10 +120,9 @@ end:
return data;
}
_IRQL_raises_(APC_LEVEL)
_Acquires_lock_(&report_queue_config.lock)
_Releases_lock_(&report_queue_config.lock)
_IRQL_restores_global_(irql, GuardedMutex)
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
InsertReportToQueue(
_In_ PVOID Report
@ -138,6 +133,9 @@ InsertReportToQueue(
KeReleaseGuardedMutex(&report_queue_config.lock);
}
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
FreeGlobalReportQueueObjects()
{
@ -163,13 +161,14 @@ end:
* reports as a result of a single usermode request and hence it makes dealing with
* reports generated from ObRegisterCallbacks for example much easier.
*/
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
HandlePeriodicGlobalReportQueueQuery(
_Inout_ PIRP Irp
)
{
PAGED_CODE();
PVOID report = NULL;
INT count = 0;
GLOBAL_REPORT_QUEUE_HEADER header;
@ -307,10 +306,8 @@ ListInit(
Head->Next = NULL;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
ListInsert(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -329,10 +326,8 @@ ListInsert(
KeReleaseSpinLock(Lock, irql);
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
BOOLEAN
ListFreeFirstEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -355,10 +350,8 @@ ListFreeFirstEntry(
return result;
}
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
ListRemoveEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,

View file

@ -36,20 +36,16 @@ 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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
PVOID
QueuePop(
_Inout_ PQUEUE_HEAD Head
@ -60,20 +56,25 @@ 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)
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
InsertReportToQueue(
_In_ PVOID Report
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
NTSTATUS
HandlePeriodicGlobalReportQueueQuery(
_Inout_ PIRP Irp
);
_IRQL_requires_max_(APC_LEVEL)
_Acquires_lock_(_Lock_kind_mutex_)
_Releases_lock_(_Lock_kind_mutex_)
VOID
FreeGlobalReportQueueObjects();
@ -83,10 +84,8 @@ ListInit(
_Inout_ PKSPIN_LOCK Lock
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
ListInsert(
_Inout_ PSINGLE_LIST_ENTRY Head,
@ -94,20 +93,16 @@ ListInsert(
_In_ PKSPIN_LOCK Lock
);
_IRQL_raises_(DISPATCH_LEVEL)
_Acquires_lock_(Lock)
_Releases_lock_(Lock)
_IRQL_restores_global_(SpinLock, irql)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
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)
_Acquires_lock_(_Lock_kind_spin_lock_)
_Releases_lock_(_Lock_kind_spin_lock_)
VOID
ListRemoveEntry(
_Inout_ PSINGLE_LIST_ENTRY Head,