#pragma once #include "Imports.h" //#ifdef DBG #define DPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__) //#else //#define DPRINT(...) //#endif #define BB_POOL_TAG 'enoB' #define ObpAccessProtectCloseBit 0x2000000 // // PTE protection values // #define MM_ZERO_ACCESS 0 #define MM_READONLY 1 #define MM_EXECUTE 2 #define MM_EXECUTE_READ 3 #define MM_READWRITE 4 #define MM_WRITECOPY 5 #define MM_EXECUTE_READWRITE 6 #define MM_EXECUTE_WRITECOPY 7 #define MM_PTE_VALID_MASK 0x1 #define MM_PTE_WRITE_MASK 0x800 #define MM_PTE_OWNER_MASK 0x4 #define MM_PTE_WRITE_THROUGH_MASK 0x8 #define MM_PTE_CACHE_DISABLE_MASK 0x10 #define MM_PTE_ACCESS_MASK 0x20 #define MM_PTE_DIRTY_MASK 0x42 #define MM_PTE_LARGE_PAGE_MASK 0x80 #define MM_PTE_GLOBAL_MASK 0x100 #define MM_PTE_COPY_ON_WRITE_MASK 0x200 #define MM_PTE_PROTOTYPE_MASK 0x400 #define MM_PTE_TRANSITION_MASK 0x800 #define VIRTUAL_ADDRESS_BITS 48 #define VIRTUAL_ADDRESS_MASK ((((ULONG_PTR)1) << VIRTUAL_ADDRESS_BITS) - 1) #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 #define MI_SYSTEM_RANGE_START (ULONG_PTR)(0xFFFF080000000000) // start of system space #define EX_ADDITIONAL_INFO_SIGNATURE (ULONG_PTR)(-2) #define KI_USER_SHARED_DATA 0xFFFFF78000000000UI64 #define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA) #ifndef PTE_SHIFT #define PTE_SHIFT 3 #endif #ifndef PTI_SHIFT #define PTI_SHIFT 12 #endif #ifndef PDI_SHIFT #define PDI_SHIFT 21 #endif #ifndef PPI_SHIFT #define PPI_SHIFT 30 #endif #ifndef PXI_SHIFT #define PXI_SHIFT 39 #endif #ifndef PXE_BASE #define PXE_BASE 0xFFFFF6FB7DBED000UI64 #endif #ifndef PXE_SELFMAP #define PXE_SELFMAP 0xFFFFF6FB7DBEDF68UI64 #endif #ifndef PPE_BASE #define PPE_BASE 0xFFFFF6FB7DA00000UI64 #endif #ifndef PDE_BASE #define PDE_BASE 0xFFFFF6FB40000000UI64 #endif #ifndef PTE_BASE #define PTE_BASE 0xFFFFF68000000000UI64 #endif #ifndef _WIN64 #define KDDEBUGGER_DATA_OFFSET 0x1068 #else #define KDDEBUGGER_DATA_OFFSET 0x2080 #endif #ifndef _WIN64 #define DUMP_BLOCK_SIZE 0x20000 #else #define DUMP_BLOCK_SIZE 0x40000 #endif #define PHYSICAL_ADDRESS_BITS 40 #define ObpDecodeGrantedAccess( Access ) \ ((Access)& ~ObpAccessProtectCloseBit) #define ObpDecodeObject( Object ) (PVOID)(((LONG_PTR)Object >> 0x10) & ~(ULONG_PTR)0xF) #define PTE_PER_PAGE 512 #define PDE_PER_PAGE 512 #define PPE_PER_PAGE 512 #define PXE_PER_PAGE 512 #define PPI_MASK (PPE_PER_PAGE - 1) #define PXI_MASK (PXE_PER_PAGE - 1) #define MiGetPxeOffset(va) \ ((ULONG)(((ULONG_PTR)(va) >> PXI_SHIFT) & PXI_MASK)) #define MiGetPxeAddress(va) \ ((PMMPTE)PXE_BASE + MiGetPxeOffset(va)) #define MiGetPpeAddress(va) \ ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) << PTE_SHIFT) + PPE_BASE)) #define MiGetPdeAddress(va) \ ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) << PTE_SHIFT) + PDE_BASE)) #define MiGetPteAddress(va) \ ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + PTE_BASE)) #define VA_SHIFT (63 - 47) // address sign extend shift count #define MiGetVirtualAddressMappedByPte(PTE) \ ((PVOID)((LONG_PTR)(((LONG_PTR)(PTE) - PTE_BASE) << (PAGE_SHIFT + VA_SHIFT - PTE_SHIFT)) >> VA_SHIFT)) #define MI_IS_PHYSICAL_ADDRESS(Va) \ ((MiGetPxeAddress(Va)->u.Hard.Valid == 1) && \ (MiGetPpeAddress(Va)->u.Hard.Valid == 1) && \ ((MiGetPdeAddress(Va)->u.Long & 0x81) == 0x81) || (MiGetPteAddress(Va)->u.Hard.Valid == 1)) #define ExpIsValidObjectEntry(Entry) \ ( (Entry != NULL) && (Entry->LowValue != 0) && (Entry->HighValue != EX_ADDITIONAL_INFO_SIGNATURE) ) // Workaround for compiler warning #define FN_CAST(T, p) (T)(ULONG_PTR)p #define FN_CAST_V(p) (PVOID)(ULONG_PTR)p // Get SSDT index from function pointer #define SSDTIndex(pfn) *(PULONG)((ULONG_PTR)pfn + 0x15) typedef ULONG WIN32_PROTECTION_MASK; typedef PULONG PWIN32_PROTECTION_MASK; typedef enum _WinVer { WINVER_7 = 0x0610, WINVER_7_SP1 = 0x0611, WINVER_8 = 0x0620, WINVER_81 = 0x0630, WINVER_10 = 0x0A00, WINVER_10_RS1 = 0x0A01, // Anniversary update WINVER_10_RS2 = 0x0A02, // Creators update WINVER_10_RS3 = 0x0A03, // Fall creators update WINVER_10_RS4 = 0x0A04, // Spring creators update WINVER_10_RS5 = 0x0A05, // October 2018 update } WinVer; extern PLIST_ENTRY PsLoadedModuleList; extern MMPTE ValidKernelPte; /// /// OS-dependent stuff /// typedef struct _DYNAMIC_DATA { WinVer ver; // OS version ULONG buildNo; // OS build revision BOOLEAN correctBuild; // OS kernel build number is correct and supported ULONG KExecOpt; // KPROCESS::ExecuteOptions ULONG Protection; // EPROCESS::Protection ULONG EProcessFlags2; // EPROCESS::Flags2 ULONG ObjTable; // EPROCESS::ObjectTable ULONG VadRoot; // EPROCESS::VadRoot ULONG NtProtectIndex; // NtProtectVirtualMemory SSDT index ULONG NtCreateThdIndex; // NtCreateThreadEx SSDT index ULONG NtTermThdIndex; // NtTerminateThread SSDT index ULONG PrevMode; // KTHREAD::PreviousMode ULONG ExitStatus; // ETHREAD::ExitStatus ULONG MiAllocPage; // MiAllocateDriverPage offset ULONG ExRemoveTable; // Ex(p)RemoveHandleTable offset ULONG_PTR DYN_PDE_BASE; // Win10 AU+ relocated PDE base VA ULONG_PTR DYN_PTE_BASE; // Win10 AU+ relocated PTE base VA } DYNAMIC_DATA, *PDYNAMIC_DATA; typedef struct _NOPPROCINFO { KDPC DpcTraps[MAXIMUM_PROCESSORS]; LONG ActiveCores; LONG DPCCount; ULONG Cores; KIRQL SavedIrql; KPRIORITY SavedPriority; LONG IsCodeExecuted; }NOPPROCINFO, *PNOPPROCINFO; typedef NTSTATUS( NTAPI* fnNtCreateThreadEx ) ( OUT PHANDLE hThread, IN ACCESS_MASK DesiredAccess, IN PVOID ObjectAttributes, IN HANDLE ProcessHandle, IN PVOID lpStartAddress, IN PVOID lpParameter, IN ULONG Flags, IN SIZE_T StackZeroBits, IN SIZE_T SizeOfStackCommit, IN SIZE_T SizeOfStackReserve, OUT PVOID lpBytesBuffer ); typedef PFN_NUMBER( NTAPI* fnMiAllocateDriverPage )(IN PMMPTE pPTE); typedef NTSTATUS( NTAPI* fnNtTerminateThread)( IN HANDLE ThreadHandle, IN NTSTATUS ExitStatus ); typedef NTSTATUS( NTAPI* fnExRemoveHandleTable )(IN PHANDLE_TABLE pTable); #if defined(_WIN8_) || defined (_WIN7_) typedef NTSTATUS( NTAPI* fnNtProtectVirtualMemory ) ( IN HANDLE ProcessHandle, IN PVOID* BaseAddress, IN SIZE_T* NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection ); NTSTATUS NTAPI ZwProtectVirtualMemory( IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN OUT SIZE_T* NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection ); #else NTSYSAPI NTSTATUS NTAPI ZwProtectVirtualMemory( IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN OUT SIZE_T* NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection ); #endif #ifdef _WIN81_ NTSYSAPI PVOID NTAPI RtlAvlRemoveNode( IN PRTL_AVL_TREE pTree, IN PMMADDRESS_NODE pNode ); #endif ULONG NTAPI KeCapturePersistentThreadState( IN PCONTEXT Context, IN PKTHREAD Thread, IN ULONG BugCheckCode, IN ULONG BugCheckParameter1, IN ULONG BugCheckParameter2, IN ULONG BugCheckParameter3, IN ULONG BugCheckParameter4, OUT PVOID VirtualAddress ); /// /// Initialize debugger block g_KdBlock /// VOID InitializeDebuggerBlock(); /// /// Lookup handle in the process handle table /// /// Handle table /// Handle to search for /// Found entry, NULL if nothing found PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry( IN PHANDLE_TABLE HandleTable, IN EXHANDLE tHandle ); /// /// Get ntoskrnl base address /// /// Size of module /// Found address, NULL if not found PVOID GetKernelBase( OUT PULONG pSize ); /// /// Gets SSDT base - KiSystemServiceTable /// /// SSDT base, NULL if not found PSYSTEM_SERVICE_DESCRIPTOR_TABLE GetSSDTBase(); /// /// Gets the SSDT entry address by index. /// /// Service index /// Found service address, NULL if not found PVOID GetSSDTEntry( IN ULONG index ); /// /// Get page hardware PTE /// Address must be valid, otherwise bug check is imminent /// /// Target address /// Found PTE PMMPTE GetPTEForVA( IN PVOID pAddress ); /// /// Initialize structure for processor start/stop /// /// >Processors data VOID InitializeStopProcessors( OUT NOPPROCINFO* Info ); /// /// Stall all but current active processors /// /// Processors data VOID StopProcessors( IN NOPPROCINFO* Info ); /// /// Resume all stopped active processors /// /// Processors data VOID StartProcessors( IN NOPPROCINFO* Info ); /// /// Allocate memory in one of the ntoskrnl discarded section /// /// Block size to allocate /// Allocated address /// Status code NTSTATUS AllocateInDiscardedMemory( IN ULONG size, OUT PVOID* ppFoundBase );