mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
e
This commit is contained in:
parent
5e8eeb4bf0
commit
af45bc923f
30 changed files with 902 additions and 955 deletions
|
@ -6,7 +6,7 @@
|
|||
#include "pool.h"
|
||||
#include "thread.h"
|
||||
|
||||
CALLBACK_CONFIGURATION configuration;
|
||||
CALLBACK_CONFIGURATION configuration = { 0 };
|
||||
|
||||
VOID ObPostOpCallbackRoutine(
|
||||
_In_ PVOID RegistrationContext,
|
||||
|
|
|
@ -6,13 +6,8 @@
|
|||
#include <wdf.h>
|
||||
#include "common.h"
|
||||
|
||||
#define REPORT_ILLEGAL_HANDLE_OPERATION 70
|
||||
|
||||
#define HANDLE_REPORT_PROCESS_NAME_MAX_LENGTH 64
|
||||
|
||||
|
||||
VOID UnregisterCallbacksOnProcessTermination();
|
||||
|
||||
typedef struct _OPEN_HANDLE_FAILURE_REPORT
|
||||
{
|
||||
INT report_code;
|
||||
|
@ -90,4 +85,6 @@ NTSTATUS InitiateDriverCallbacks();
|
|||
|
||||
VOID UnregisterCallbacksOnProcessTermination();
|
||||
|
||||
VOID UnregisterCallbacksOnProcessTermination();
|
||||
|
||||
#endif
|
||||
|
|
640
driver/common.h
640
driver/common.h
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <ntifs.h>
|
||||
#include <wdftypes.h>
|
||||
#include <wdf.h>
|
||||
|
||||
#define DEBUG_LOG(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[+] " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG_ERROR(fmt, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[-] " fmt "\n", ##__VA_ARGS__)
|
||||
|
@ -16,6 +15,16 @@
|
|||
#define THREAD_DATA_POOL 'doof'
|
||||
#define PROC_AFFINITY_POOL 'eeee'
|
||||
#define TEMP_BUFFER_POOL 'ffff'
|
||||
#define DRIVER_PATH_POOL_TAG 'path'
|
||||
#define POOL_TAG_INTEGRITY 'intg'
|
||||
#define POOL_DUMP_BLOCK_TAG 'dump'
|
||||
#define POOL_DEBUGGER_DATA_TAG 'data'
|
||||
#define PROCESS_ADDRESS_LIST_TAG 'addr'
|
||||
#define ANALYSE_PROCESS_TAG 'anls'
|
||||
#define INVALID_PROCESS_REPORT_TAG 'invd'
|
||||
#define QUEUE_POOL_TAG 'qqqq'
|
||||
#define REPORT_QUEUE_TEMP_BUFFER_TAG 'temp'
|
||||
#define REPORT_POOL_TAG 'repo'
|
||||
|
||||
#define ERROR -1
|
||||
#define STACK_FRAME_POOL_SIZE 0x200
|
||||
|
@ -23,8 +32,49 @@
|
|||
|
||||
#define KTHREAD_STACK_BASE_OFFSET 0x030
|
||||
#define KTHREAD_STACK_LIMIT_OFFSET 0x038
|
||||
#define KTHREAD_THREADLIST_OFFSET 0x2f8
|
||||
#define KTHREAD_APC_STATE_OFFSET 0x258
|
||||
#define KTHREAD_START_ADDRESS_OFFSET 0x450
|
||||
|
||||
#define EPROCESS_VIRTUAL_SIZE_OFFSET 0x498
|
||||
#define EPROCESS_IMAGE_NAME_OFFSET 0x5a8
|
||||
|
||||
#define KPROCESS_THREADLIST_OFFSET 0x030
|
||||
|
||||
#define KPCRB_CURRENT_THREAD 0x8
|
||||
|
||||
#define IA32_GS_BASE 0xc0000101
|
||||
#define KPRCB_OFFSET_FROM_GS_BASE 0x180
|
||||
|
||||
#define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20
|
||||
#define REPORT_NMI_CALLBACK_FAILURE 50
|
||||
#define REPORT_MODULE_VALIDATION_FAILURE 60
|
||||
#define REPORT_ILLEGAL_HANDLE_OPERATION 70
|
||||
#define REPORT_INVALID_PROCESS_ALLOCATION 80
|
||||
#define REPORT_HIDDEN_SYSTEM_THREAD 90
|
||||
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
|
||||
|
||||
/*
|
||||
* Generic macros that allow you to quickly determine whether
|
||||
* or not a page table entry is present or may forward to a
|
||||
* large page of data, rather than another page table (applies
|
||||
* only to PDPTEs and PDEs)
|
||||
*
|
||||
* Some nice macros courtesy of:
|
||||
* https://www.unknowncheats.me/forum/general-programming-and-reversing/523359-introduction-physical-memory.html
|
||||
*/
|
||||
#define IS_LARGE_PAGE(x) ( (BOOLEAN)((x >> 7) & 1) )
|
||||
#define IS_PAGE_PRESENT(x) ( (BOOLEAN)(x & 1) )
|
||||
|
||||
#define PAGE_1GB_SHIFT 30
|
||||
#define PAGE_1GB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_1GB_SHIFT)) )
|
||||
|
||||
#define PAGE_2MB_SHIFT 21
|
||||
#define PAGE_2MB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_2MB_SHIFT)) )
|
||||
|
||||
#define PAGE_4KB_SHIFT 12
|
||||
#define PAGE_4KB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_4KB_SHIFT)) )
|
||||
|
||||
typedef struct _KAFFINITY_EX
|
||||
{
|
||||
USHORT Count;
|
||||
|
@ -72,27 +122,6 @@ typedef struct _RTL_MODULE_EXTENDED_INFO
|
|||
|
||||
} RTL_MODULE_EXTENDED_INFO, * PRTL_MODULE_EXTENDED_INFO;
|
||||
|
||||
/* undocumented functions */
|
||||
|
||||
EXTERN_C VOID KeInitializeAffinityEx(
|
||||
PKAFFINITY_EX affinity
|
||||
);
|
||||
|
||||
EXTERN_C VOID KeAddProcessorAffinityEx(
|
||||
PKAFFINITY_EX affinity,
|
||||
INT num
|
||||
);
|
||||
|
||||
EXTERN_C VOID HalSendNMI(
|
||||
PKAFFINITY_EX affinity
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
RtlQueryModuleInformation(
|
||||
ULONG* InformationLength,
|
||||
ULONG SizePerModule,
|
||||
PVOID InformationBuffer );
|
||||
|
||||
/*
|
||||
Thread Information Block: (GS register)
|
||||
|
||||
|
@ -116,11 +145,6 @@ Thread Information Block: (GS register)
|
|||
...
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <wdftypes.h>
|
||||
|
||||
typedef struct _OBJECT_TYPE
|
||||
{
|
||||
LIST_ENTRY TypeList;
|
||||
|
@ -326,8 +350,6 @@ typedef struct _HANDLE_TRACE_DB_ENTRY
|
|||
|
||||
} HANDLE_TRACE_DB_ENTRY, * PHANDLE_TRACE_DB_ENTRY;
|
||||
|
||||
|
||||
|
||||
typedef struct _HANDLE_TRACE_DEBUG_INFO
|
||||
{
|
||||
LONG RefCount;
|
||||
|
@ -427,6 +449,494 @@ typedef struct _OBJECT_HEADER
|
|||
QUAD Body;
|
||||
} OBJECT_HEADER, * POBJECT_HEADER;
|
||||
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
typedef struct _IMAGE_SECTION_HEADER {
|
||||
unsigned char Name[ IMAGE_SIZEOF_SHORT_NAME ];
|
||||
union {
|
||||
unsigned long PhysicalAddress;
|
||||
unsigned long VirtualSize;
|
||||
} Misc;
|
||||
unsigned long VirtualAddress;
|
||||
unsigned long SizeOfRawData;
|
||||
unsigned long PointerToRawData;
|
||||
unsigned long PointerToRelocations;
|
||||
unsigned long PointerToLinenumbers;
|
||||
unsigned short NumberOfRelocations;
|
||||
unsigned short NumberOfLinenumbers;
|
||||
unsigned long Characteristics;
|
||||
} IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER;
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER {
|
||||
unsigned short Machine;
|
||||
unsigned short NumberOfSections;
|
||||
unsigned long TimeDateStamp;
|
||||
unsigned long PointerToSymbolTable;
|
||||
unsigned long NumberOfSymbols;
|
||||
unsigned short SizeOfOptionalHeader;
|
||||
unsigned short Characteristics;
|
||||
} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER;
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||
unsigned long VirtualAddress;
|
||||
unsigned long Size;
|
||||
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER64 {
|
||||
unsigned short Magic;
|
||||
unsigned char MajorLinkerVersion;
|
||||
unsigned char MinorLinkerVersion;
|
||||
unsigned long SizeOfCode;
|
||||
unsigned long SizeOfInitializedData;
|
||||
unsigned long SizeOfUninitializedData;
|
||||
unsigned long AddressOfEntryPoint;
|
||||
unsigned long BaseOfCode;
|
||||
ULONGLONG ImageBase;
|
||||
unsigned long SectionAlignment;
|
||||
unsigned long FileAlignment;
|
||||
unsigned short MajorOperatingSystemVersion;
|
||||
unsigned short MinorOperatingSystemVersion;
|
||||
unsigned short MajorImageVersion;
|
||||
unsigned short MinorImageVersion;
|
||||
unsigned short MajorSubsystemVersion;
|
||||
unsigned short MinorSubsystemVersion;
|
||||
unsigned long Win32VersionValue;
|
||||
unsigned long SizeOfImage;
|
||||
unsigned long SizeOfHeaders;
|
||||
unsigned long CheckSum;
|
||||
unsigned short Subsystem;
|
||||
unsigned short DllCharacteristics;
|
||||
ULONGLONG SizeOfStackReserve;
|
||||
ULONGLONG SizeOfStackCommit;
|
||||
ULONGLONG SizeOfHeapReserve;
|
||||
ULONGLONG SizeOfHeapCommit;
|
||||
unsigned long LoaderFlags;
|
||||
unsigned long NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[ IMAGE_NUMBEROF_DIRECTORY_ENTRIES ];
|
||||
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64;
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||
unsigned short e_magic; // Magic number
|
||||
unsigned short e_cblp; // Bytes on last page of file
|
||||
unsigned short e_cp; // Pages in file
|
||||
unsigned short e_crlc; // Relocations
|
||||
unsigned short e_cparhdr; // Size of header in paragraphs
|
||||
unsigned short e_minalloc; // Minimum extra paragraphs needed
|
||||
unsigned short e_maxalloc; // Maximum extra paragraphs needed
|
||||
unsigned short e_ss; // Initial (relative) SS value
|
||||
unsigned short e_sp; // Initial SP value
|
||||
unsigned short e_csum; // Checksum
|
||||
unsigned short e_ip; // Initial IP value
|
||||
unsigned short e_cs; // Initial (relative) CS value
|
||||
unsigned short e_lfarlc; // File address of relocation table
|
||||
unsigned short e_ovno; // Overlay number
|
||||
unsigned short e_res[ 4 ]; // Reserved words
|
||||
unsigned short e_oemid; // OEM identifier (for e_oeminfo)
|
||||
unsigned short e_oeminfo; // OEM information; e_oemid specific
|
||||
unsigned short e_res2[ 10 ]; // Reserved words
|
||||
LONG e_lfanew; // File address of new exe header
|
||||
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER;
|
||||
|
||||
typedef struct _LOCAL_NT_HEADER {
|
||||
unsigned long Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||||
} LOCAL_NT_HEADER, * PLOCAL_NT_HEADER;
|
||||
|
||||
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
|
||||
((ULONG_PTR)(ntheader) + \
|
||||
FIELD_OFFSET( LOCAL_NT_HEADER, OptionalHeader ) + \
|
||||
((ntheader))->FileHeader.SizeOfOptionalHeader \
|
||||
))
|
||||
|
||||
/* creds: https://www.unknowncheats.me/forum/2602838-post2.html */
|
||||
|
||||
typedef struct _DBGKD_DEBUG_DATA_HEADER64
|
||||
{
|
||||
LIST_ENTRY64 List;
|
||||
ULONG OwnerTag;
|
||||
ULONG Size;
|
||||
} DBGKD_DEBUG_DATA_HEADER64, * PDBGKD_DEBUG_DATA_HEADER64;
|
||||
|
||||
typedef struct _KDDEBUGGER_DATA64
|
||||
{
|
||||
DBGKD_DEBUG_DATA_HEADER64 Header;
|
||||
ULONG64 KernBase;
|
||||
ULONG64 BreakpointWithStatus;
|
||||
ULONG64 SavedContext;
|
||||
USHORT ThCallbackStack;
|
||||
USHORT NextCallback;
|
||||
USHORT FramePointer;
|
||||
USHORT PaeEnabled;
|
||||
ULONG64 KiCallUserMode;
|
||||
ULONG64 KeUserCallbackDispatcher;
|
||||
ULONG64 PsLoadedModuleList;
|
||||
ULONG64 PsActiveProcessHead;
|
||||
ULONG64 PspCidTable;
|
||||
ULONG64 ExpSystemResourcesList;
|
||||
ULONG64 ExpPagedPoolDescriptor;
|
||||
ULONG64 ExpNumberOfPagedPools;
|
||||
ULONG64 KeTimeIncrement;
|
||||
ULONG64 KeBugCheckCallbackListHead;
|
||||
ULONG64 KiBugcheckData;
|
||||
ULONG64 IopErrorLogListHead;
|
||||
ULONG64 ObpRootDirectoryObject;
|
||||
ULONG64 ObpTypeObjectType;
|
||||
ULONG64 MmSystemCacheStart;
|
||||
ULONG64 MmSystemCacheEnd;
|
||||
ULONG64 MmSystemCacheWs;
|
||||
ULONG64 MmPfnDatabase;
|
||||
ULONG64 MmSystemPtesStart;
|
||||
ULONG64 MmSystemPtesEnd;
|
||||
ULONG64 MmSubsectionBase;
|
||||
ULONG64 MmNumberOfPagingFiles;
|
||||
ULONG64 MmLowestPhysicalPage;
|
||||
ULONG64 MmHighestPhysicalPage;
|
||||
ULONG64 MmNumberOfPhysicalPages;
|
||||
ULONG64 MmMaximumNonPagedPoolInBytes;
|
||||
ULONG64 MmNonPagedSystemStart;
|
||||
ULONG64 MmNonPagedPoolStart;
|
||||
ULONG64 MmNonPagedPoolEnd;
|
||||
ULONG64 MmPagedPoolStart;
|
||||
ULONG64 MmPagedPoolEnd;
|
||||
ULONG64 MmPagedPoolInformation;
|
||||
ULONG64 MmPageSize;
|
||||
ULONG64 MmSizeOfPagedPoolInBytes;
|
||||
ULONG64 MmTotalCommitLimit;
|
||||
ULONG64 MmTotalCommittedPages;
|
||||
ULONG64 MmSharedCommit;
|
||||
ULONG64 MmDriverCommit;
|
||||
ULONG64 MmProcessCommit;
|
||||
ULONG64 MmPagedPoolCommit;
|
||||
ULONG64 MmExtendedCommit;
|
||||
ULONG64 MmZeroedPageListHead;
|
||||
ULONG64 MmFreePageListHead;
|
||||
ULONG64 MmStandbyPageListHead;
|
||||
ULONG64 MmModifiedPageListHead;
|
||||
ULONG64 MmModifiedNoWritePageListHead;
|
||||
ULONG64 MmAvailablePages;
|
||||
ULONG64 MmResidentAvailablePages;
|
||||
ULONG64 PoolTrackTable;
|
||||
ULONG64 NonPagedPoolDescriptor;
|
||||
ULONG64 MmHighestUserAddress;
|
||||
ULONG64 MmSystemRangeStart;
|
||||
ULONG64 MmUserProbeAddress;
|
||||
ULONG64 KdPrintCircularBuffer;
|
||||
ULONG64 KdPrintCircularBufferEnd;
|
||||
ULONG64 KdPrintWritePointer;
|
||||
ULONG64 KdPrintRolloverCount;
|
||||
ULONG64 MmLoadedUserImageList;
|
||||
ULONG64 NtBuildLab;
|
||||
ULONG64 KiNormalSystemCall;
|
||||
ULONG64 KiProcessorBlock;
|
||||
ULONG64 MmUnloadedDrivers;
|
||||
ULONG64 MmLastUnloadedDriver;
|
||||
ULONG64 MmTriageActionTaken;
|
||||
ULONG64 MmSpecialPoolTag;
|
||||
ULONG64 KernelVerifier;
|
||||
ULONG64 MmVerifierData;
|
||||
ULONG64 MmAllocatedNonPagedPool;
|
||||
ULONG64 MmPeakCommitment;
|
||||
ULONG64 MmTotalCommitLimitMaximum;
|
||||
ULONG64 CmNtCSDVersion;
|
||||
ULONG64 MmPhysicalMemoryBlock;
|
||||
ULONG64 MmSessionBase;
|
||||
ULONG64 MmSessionSize;
|
||||
ULONG64 MmSystemParentTablePage;
|
||||
ULONG64 MmVirtualTranslationBase;
|
||||
USHORT OffsetKThreadNextProcessor;
|
||||
USHORT OffsetKThreadTeb;
|
||||
USHORT OffsetKThreadKernelStack;
|
||||
USHORT OffsetKThreadInitialStack;
|
||||
USHORT OffsetKThreadApcProcess;
|
||||
USHORT OffsetKThreadState;
|
||||
USHORT OffsetKThreadBStore;
|
||||
USHORT OffsetKThreadBStoreLimit;
|
||||
USHORT SizeEProcess;
|
||||
USHORT OffsetEprocessPeb;
|
||||
USHORT OffsetEprocessParentCID;
|
||||
USHORT OffsetEprocessDirectoryTableBase;
|
||||
USHORT SizePrcb;
|
||||
USHORT OffsetPrcbDpcRoutine;
|
||||
USHORT OffsetPrcbCurrentThread;
|
||||
USHORT OffsetPrcbMhz;
|
||||
USHORT OffsetPrcbCpuType;
|
||||
USHORT OffsetPrcbVendorString;
|
||||
USHORT OffsetPrcbProcStateContext;
|
||||
USHORT OffsetPrcbNumber;
|
||||
USHORT SizeEThread;
|
||||
ULONG64 KdPrintCircularBufferPtr;
|
||||
ULONG64 KdPrintBufferSize;
|
||||
ULONG64 KeLoaderBlock;
|
||||
USHORT SizePcr;
|
||||
USHORT OffsetPcrSelfPcr;
|
||||
USHORT OffsetPcrCurrentPrcb;
|
||||
USHORT OffsetPcrContainedPrcb;
|
||||
USHORT OffsetPcrInitialBStore;
|
||||
USHORT OffsetPcrBStoreLimit;
|
||||
USHORT OffsetPcrInitialStack;
|
||||
USHORT OffsetPcrStackLimit;
|
||||
USHORT OffsetPrcbPcrPage;
|
||||
USHORT OffsetPrcbProcStateSpecialReg;
|
||||
USHORT GdtR0Code;
|
||||
USHORT GdtR0Data;
|
||||
USHORT GdtR0Pcr;
|
||||
USHORT GdtR3Code;
|
||||
USHORT GdtR3Data;
|
||||
USHORT GdtR3Teb;
|
||||
USHORT GdtLdt;
|
||||
USHORT GdtTss;
|
||||
USHORT Gdt64R3CmCode;
|
||||
USHORT Gdt64R3CmTeb;
|
||||
ULONG64 IopNumTriageDumpDataBlocks;
|
||||
ULONG64 IopTriageDumpDataBlocks;
|
||||
} KDDEBUGGER_DATA64, * PKDDEBUGGER_DATA64;
|
||||
|
||||
typedef struct _KDDEBUGGER_DATA_ADDITION64
|
||||
{
|
||||
ULONG64 VfCrashDataBlock;
|
||||
ULONG64 MmBadPagesDetected;
|
||||
ULONG64 MmZeroedPageSingleBitErrorsDetected;
|
||||
ULONG64 EtwpDebuggerData;
|
||||
USHORT OffsetPrcbContext;
|
||||
USHORT OffsetPrcbMaxBreakpoints;
|
||||
USHORT OffsetPrcbMaxWatchpoints;
|
||||
ULONG OffsetKThreadStackLimit;
|
||||
ULONG OffsetKThreadStackBase;
|
||||
ULONG OffsetKThreadQueueListEntry;
|
||||
ULONG OffsetEThreadIrpList;
|
||||
USHORT OffsetPrcbIdleThread;
|
||||
USHORT OffsetPrcbNormalDpcState;
|
||||
USHORT OffsetPrcbDpcStack;
|
||||
USHORT OffsetPrcbIsrStack;
|
||||
USHORT SizeKDPC_STACK_FRAME;
|
||||
USHORT OffsetKPriQueueThreadListHead;
|
||||
USHORT OffsetKThreadWaitReason;
|
||||
USHORT Padding;
|
||||
ULONG64 PteBase;
|
||||
ULONG64 RetpolineStubFunctionTable;
|
||||
ULONG RetpolineStubFunctionTableSize;
|
||||
ULONG RetpolineStubOffset;
|
||||
ULONG RetpolineStubSize;
|
||||
}KDDEBUGGER_DATA_ADDITION64, * PKDDEBUGGER_DATA_ADDITION64;
|
||||
|
||||
|
||||
typedef struct _DUMP_HEADER
|
||||
{
|
||||
ULONG Signature;
|
||||
ULONG ValidDump;
|
||||
ULONG MajorVersion;
|
||||
ULONG MinorVersion;
|
||||
ULONG_PTR DirectoryTableBase;
|
||||
ULONG_PTR PfnDataBase;
|
||||
PLIST_ENTRY PsLoadedModuleList;
|
||||
PLIST_ENTRY PsActiveProcessHead;
|
||||
ULONG MachineImageType;
|
||||
ULONG NumberProcessors;
|
||||
ULONG BugCheckCode;
|
||||
ULONG_PTR BugCheckParameter1;
|
||||
ULONG_PTR BugCheckParameter2;
|
||||
ULONG_PTR BugCheckParameter3;
|
||||
ULONG_PTR BugCheckParameter4;
|
||||
CHAR VersionUser[ 32 ];
|
||||
struct _KDDEBUGGER_DATA64* KdDebuggerDataBlock;
|
||||
} DUMP_HEADER, * PDUMP_HEADER;
|
||||
|
||||
typedef union _DIRECTORY_TABLE_BASE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Ignored0 : 3; /* 2:0 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 _Ignored1 : 7; /* 11:5 */
|
||||
UINT64 PhysicalAddress : 36; /* 47:12 */
|
||||
UINT64 _Reserved0 : 16; /* 63:48 */
|
||||
|
||||
} Bits;
|
||||
|
||||
UINT64 BitAddress;
|
||||
|
||||
} CR3, DIR_TABLE_BASE;
|
||||
|
||||
typedef union _VIRTUAL_MEMORY_ADDRESS
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 PageIndex : 12; /* 0:11 */
|
||||
UINT64 PtIndex : 9; /* 12:20 */
|
||||
UINT64 PdIndex : 9; /* 21:29 */
|
||||
UINT64 PdptIndex : 9; /* 30:38 */
|
||||
UINT64 Pml4Index : 9; /* 39:47 */
|
||||
UINT64 Unused : 16; /* 48:63 */
|
||||
|
||||
} Bits;
|
||||
|
||||
UINT64 BitAddress;
|
||||
|
||||
} VIRTUAL_ADDRESS, * PVIRTUAL_ADDRESS;
|
||||
|
||||
typedef union _PML4_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 _Reserved0 : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 40; /* 51:12 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PML4E;
|
||||
|
||||
typedef union _PDPT_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 40; /* 51:12 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDPTE;
|
||||
|
||||
typedef union _PD_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 38; /* 49:12 */
|
||||
UINT64 _Reserved0 : 2; /* 51:50 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDE;
|
||||
|
||||
typedef union _PT_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageAttributeTable : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PhysicalAddress : 38; /* 49:12 */
|
||||
UINT64 _Reserved0 : 2; /* 51:50 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PTE;
|
||||
|
||||
typedef union _PDPT_ENTRY_LARGE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PageAttributeTable : 1; /* 12 */
|
||||
UINT64 _Reserved0 : 17; /* 29:13 */
|
||||
UINT64 PhysicalAddress : 22; /* 51:30 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDPTE_LARGE;
|
||||
|
||||
typedef union _PD_ENTRY_LARGE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PageAttributeTalbe : 1; /* 12 */
|
||||
UINT64 _Reserved0 : 8; /* 20:13 */
|
||||
UINT64 PhysicalAddress : 29; /* 49:21 */
|
||||
UINT64 _Reserved1 : 2; /* 51:50 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDE_LARGE;
|
||||
|
||||
//typedef struct _KAPC_STATE
|
||||
//{
|
||||
// LIST_ENTRY ApcListHead[ MaximumMode ];
|
||||
// struct _KPROCESS* Process;
|
||||
// union {
|
||||
// UCHAR InProgressFlags;
|
||||
// struct
|
||||
// {
|
||||
// BOOLEAN KernelApcInProgress : 1;
|
||||
// BOOLEAN SpecialApcInProgress : 1;
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// BOOLEAN KernelApcPending;
|
||||
// union {
|
||||
// BOOLEAN UserApcPendingAll;
|
||||
// struct
|
||||
// {
|
||||
// BOOLEAN SpecialUserApcPending : 1;
|
||||
// BOOLEAN UserApcPending : 1;
|
||||
// };
|
||||
// };
|
||||
//} KAPC_STATE, * PKAPC_STATE, * PRKAPC_STATE;
|
||||
|
||||
NTKERNELAPI
|
||||
BOOLEAN
|
||||
ExEnumHandleTable(
|
||||
|
@ -460,4 +970,76 @@ PsGetProcessImageFileName(
|
|||
PEPROCESS Process
|
||||
);
|
||||
|
||||
EXTERN_C VOID KeInitializeAffinityEx(
|
||||
PKAFFINITY_EX affinity
|
||||
);
|
||||
|
||||
EXTERN_C VOID KeAddProcessorAffinityEx(
|
||||
PKAFFINITY_EX affinity,
|
||||
INT num
|
||||
);
|
||||
|
||||
EXTERN_C VOID HalSendNMI(
|
||||
PKAFFINITY_EX affinity
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
RtlQueryModuleInformation(
|
||||
ULONG* InformationLength,
|
||||
ULONG SizePerModule,
|
||||
PVOID InformationBuffer
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtSetInformationProcess(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
_In_ PVOID ProcessInformation,
|
||||
_In_ ULONG ProcessInformationLength
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
KeCapturePersistentThreadState(
|
||||
__in PCONTEXT Context,
|
||||
__in_opt PKTHREAD Thread,
|
||||
__in ULONG BugCheckCode,
|
||||
__in ULONG_PTR BugCheckParameter1,
|
||||
__in ULONG_PTR BugCheckParameter2,
|
||||
__in ULONG_PTR BugCheckParameter3,
|
||||
__in ULONG_PTR BugCheckParameter4,
|
||||
__in PDUMP_HEADER DumpHeader
|
||||
);
|
||||
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, Signature ) == 0 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, ValidDump ) == 4 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MajorVersion ) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MinorVersion ) == 0xc );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, DirectoryTableBase ) == 0x10 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PfnDataBase ) == 0x18 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PsLoadedModuleList ) == 0x20 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PsActiveProcessHead ) == 0x28 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MachineImageType ) == 0x30 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, NumberProcessors ) == 0x34 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckCode ) == 0x38 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter1 ) == 0x40 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter2 ) == 0x48 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter3 ) == 0x50 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter4 ) == 0x58 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, KdDebuggerDataBlock ) == 0x80 );
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
#include <ntifs.h>
|
||||
#include <wdftypes.h>
|
||||
#include <wdf.h>
|
||||
#include "common.h"
|
||||
|
||||
#define DRIVER_PATH_MAX_LENGTH 512
|
||||
#define DRIVER_PATH_POOL_TAG 'path'
|
||||
|
||||
/*
|
||||
* This structure is strictly for driver related stuff
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define HV_H
|
||||
|
||||
#include <ntifs.h>
|
||||
#include "common.h"
|
||||
|
||||
typedef struct _HYPERVISOR_DETECTION_REPORT
|
||||
{
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#define INTEGRITY_H
|
||||
|
||||
#include <ntifs.h>
|
||||
|
||||
#define POOL_TAG_INTEGRITY 'intg'
|
||||
#include "common.h"
|
||||
|
||||
NTSTATUS CopyDriverExecutableRegions(
|
||||
_In_ PIRP Irp
|
||||
|
@ -21,118 +20,4 @@ NTSTATUS RetrieveInMemoryModuleExecutableSections(
|
|||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtSetInformationProcess(
|
||||
_In_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
_In_ PVOID ProcessInformation,
|
||||
_In_ ULONG ProcessInformationLength
|
||||
);
|
||||
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
|
||||
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
typedef struct _IMAGE_SECTION_HEADER {
|
||||
unsigned char Name[ IMAGE_SIZEOF_SHORT_NAME ];
|
||||
union {
|
||||
unsigned long PhysicalAddress;
|
||||
unsigned long VirtualSize;
|
||||
} Misc;
|
||||
unsigned long VirtualAddress;
|
||||
unsigned long SizeOfRawData;
|
||||
unsigned long PointerToRawData;
|
||||
unsigned long PointerToRelocations;
|
||||
unsigned long PointerToLinenumbers;
|
||||
unsigned short NumberOfRelocations;
|
||||
unsigned short NumberOfLinenumbers;
|
||||
unsigned long Characteristics;
|
||||
} IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER;
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER {
|
||||
unsigned short Machine;
|
||||
unsigned short NumberOfSections;
|
||||
unsigned long TimeDateStamp;
|
||||
unsigned long PointerToSymbolTable;
|
||||
unsigned long NumberOfSymbols;
|
||||
unsigned short SizeOfOptionalHeader;
|
||||
unsigned short Characteristics;
|
||||
} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER;
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||
unsigned long VirtualAddress;
|
||||
unsigned long Size;
|
||||
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER64 {
|
||||
unsigned short Magic;
|
||||
unsigned char MajorLinkerVersion;
|
||||
unsigned char MinorLinkerVersion;
|
||||
unsigned long SizeOfCode;
|
||||
unsigned long SizeOfInitializedData;
|
||||
unsigned long SizeOfUninitializedData;
|
||||
unsigned long AddressOfEntryPoint;
|
||||
unsigned long BaseOfCode;
|
||||
ULONGLONG ImageBase;
|
||||
unsigned long SectionAlignment;
|
||||
unsigned long FileAlignment;
|
||||
unsigned short MajorOperatingSystemVersion;
|
||||
unsigned short MinorOperatingSystemVersion;
|
||||
unsigned short MajorImageVersion;
|
||||
unsigned short MinorImageVersion;
|
||||
unsigned short MajorSubsystemVersion;
|
||||
unsigned short MinorSubsystemVersion;
|
||||
unsigned long Win32VersionValue;
|
||||
unsigned long SizeOfImage;
|
||||
unsigned long SizeOfHeaders;
|
||||
unsigned long CheckSum;
|
||||
unsigned short Subsystem;
|
||||
unsigned short DllCharacteristics;
|
||||
ULONGLONG SizeOfStackReserve;
|
||||
ULONGLONG SizeOfStackCommit;
|
||||
ULONGLONG SizeOfHeapReserve;
|
||||
ULONGLONG SizeOfHeapCommit;
|
||||
unsigned long LoaderFlags;
|
||||
unsigned long NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[ IMAGE_NUMBEROF_DIRECTORY_ENTRIES ];
|
||||
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64;
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||
unsigned short e_magic; // Magic number
|
||||
unsigned short e_cblp; // Bytes on last page of file
|
||||
unsigned short e_cp; // Pages in file
|
||||
unsigned short e_crlc; // Relocations
|
||||
unsigned short e_cparhdr; // Size of header in paragraphs
|
||||
unsigned short e_minalloc; // Minimum extra paragraphs needed
|
||||
unsigned short e_maxalloc; // Maximum extra paragraphs needed
|
||||
unsigned short e_ss; // Initial (relative) SS value
|
||||
unsigned short e_sp; // Initial SP value
|
||||
unsigned short e_csum; // Checksum
|
||||
unsigned short e_ip; // Initial IP value
|
||||
unsigned short e_cs; // Initial (relative) CS value
|
||||
unsigned short e_lfarlc; // File address of relocation table
|
||||
unsigned short e_ovno; // Overlay number
|
||||
unsigned short e_res[ 4 ]; // Reserved words
|
||||
unsigned short e_oemid; // OEM identifier (for e_oeminfo)
|
||||
unsigned short e_oeminfo; // OEM information; e_oemid specific
|
||||
unsigned short e_res2[ 10 ]; // Reserved words
|
||||
LONG e_lfanew; // File address of new exe header
|
||||
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER;
|
||||
|
||||
typedef struct _LOCAL_NT_HEADER {
|
||||
unsigned long Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||||
} LOCAL_NT_HEADER, * PLOCAL_NT_HEADER;
|
||||
|
||||
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
|
||||
((ULONG_PTR)(ntheader) + \
|
||||
FIELD_OFFSET( LOCAL_NT_HEADER, OptionalHeader ) + \
|
||||
((ntheader))->FileHeader.SizeOfOptionalHeader \
|
||||
))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -235,6 +235,12 @@ NTSTATUS DeviceControl(
|
|||
|
||||
break;
|
||||
|
||||
case IOCTL_DETECT_ATTACHED_THREADS:
|
||||
|
||||
DetectThreadsAttachedToProtectedProcess();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
||||
break;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <ntifs.h>
|
||||
#include <wdftypes.h>
|
||||
#include <wdf.h>
|
||||
#include "common.h"
|
||||
|
||||
#define IOCCTL_RUN_NMI_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2001, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_VALIDATE_DRIVER_OBJECTS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2002, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
@ -17,6 +18,7 @@
|
|||
#define IOCTL_SCAN_FOR_UNLINKED_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2011, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_VALIDATE_KPRCB_CURRENT_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2012, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _DRIVER_INITIATION_INFORMATION
|
||||
{
|
||||
|
|
|
@ -5,20 +5,11 @@
|
|||
#include <intrin.h>
|
||||
#include "common.h"
|
||||
|
||||
#define REPORT_MODULE_VALIDATION_FAILURE 60
|
||||
#define MODULE_VALIDATION_FAILURE_MAX_REPORT_COUNT 20
|
||||
|
||||
#define MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE 128
|
||||
|
||||
#define REASON_NO_BACKING_MODULE 1
|
||||
#define REASON_INVALID_IOCTL_DISPATCH 2
|
||||
|
||||
#define REPORT_NMI_CALLBACK_FAILURE 50
|
||||
|
||||
NTSTATUS HandleNmiIOCTL(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
typedef struct _WHITELISTED_REGIONS
|
||||
{
|
||||
UINT64 base;
|
||||
|
@ -115,4 +106,8 @@ PRTL_MODULE_EXTENDED_INFO FindSystemModuleByName(
|
|||
_In_ PSYSTEM_MODULES SystemModules
|
||||
);
|
||||
|
||||
NTSTATUS HandleNmiIOCTL(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
441
driver/pool.h
441
driver/pool.h
|
@ -2,29 +2,20 @@
|
|||
#define POOL_H
|
||||
|
||||
#include <ntifs.h>
|
||||
#include "common.h"
|
||||
|
||||
#define REPORT_INVALID_PROCESS_ALLOCATION 80
|
||||
#define REPORT_INVALID_PROCESS_BUFFER_SIZE 4096
|
||||
|
||||
#define POOL_DUMP_BLOCK_TAG 'dump'
|
||||
#define POOL_DEBUGGER_DATA_TAG 'data'
|
||||
#define PROCESS_ADDRESS_LIST_TAG 'addr'
|
||||
#define ANALYSE_PROCESS_TAG 'anls'
|
||||
#define INVALID_PROCESS_REPORT_TAG 'invd'
|
||||
#define PAGE_BASE_SIZE 0x1000
|
||||
#define POOL_TAG_SIZE 0x004
|
||||
|
||||
#define PML4_ENTRY_COUNT 512
|
||||
#define PDPT_ENTRY_COUNT 512
|
||||
#define PD_ENTRY_COUNT 512
|
||||
#define PT_ENTRY_COUNT 512
|
||||
|
||||
#define PAGE_BASE_SIZE 0x1000
|
||||
#define POOL_TAG_SIZE 0x004
|
||||
|
||||
#define PROCESS_OBJECT_ALLOCATION_MARGIN 0x90
|
||||
|
||||
#define EPROCESS_VIRTUAL_SIZE_OFFSET 0x498
|
||||
#define EPROCESS_IMAGE_NAME_OFFSET 0x5a8
|
||||
|
||||
/* SIZE_2 = first alloc + 0x10 */
|
||||
#define WIN_PROCESS_ALLOCATION_SIZE 0xcf0
|
||||
#define WIN_PROCESS_ALLOCATION_SIZE_2 0xd00
|
||||
|
@ -46,432 +37,6 @@ VOID GetPsActiveProcessHead(
|
|||
_In_ PUINT64 Address
|
||||
);
|
||||
|
||||
/* creds: https://www.unknowncheats.me/forum/2602838-post2.html */
|
||||
|
||||
typedef struct _DBGKD_DEBUG_DATA_HEADER64
|
||||
{
|
||||
LIST_ENTRY64 List;
|
||||
ULONG OwnerTag;
|
||||
ULONG Size;
|
||||
} DBGKD_DEBUG_DATA_HEADER64, * PDBGKD_DEBUG_DATA_HEADER64;
|
||||
|
||||
typedef struct _KDDEBUGGER_DATA64
|
||||
{
|
||||
DBGKD_DEBUG_DATA_HEADER64 Header;
|
||||
ULONG64 KernBase;
|
||||
ULONG64 BreakpointWithStatus;
|
||||
ULONG64 SavedContext;
|
||||
USHORT ThCallbackStack;
|
||||
USHORT NextCallback;
|
||||
USHORT FramePointer;
|
||||
USHORT PaeEnabled;
|
||||
ULONG64 KiCallUserMode;
|
||||
ULONG64 KeUserCallbackDispatcher;
|
||||
ULONG64 PsLoadedModuleList;
|
||||
ULONG64 PsActiveProcessHead;
|
||||
ULONG64 PspCidTable;
|
||||
ULONG64 ExpSystemResourcesList;
|
||||
ULONG64 ExpPagedPoolDescriptor;
|
||||
ULONG64 ExpNumberOfPagedPools;
|
||||
ULONG64 KeTimeIncrement;
|
||||
ULONG64 KeBugCheckCallbackListHead;
|
||||
ULONG64 KiBugcheckData;
|
||||
ULONG64 IopErrorLogListHead;
|
||||
ULONG64 ObpRootDirectoryObject;
|
||||
ULONG64 ObpTypeObjectType;
|
||||
ULONG64 MmSystemCacheStart;
|
||||
ULONG64 MmSystemCacheEnd;
|
||||
ULONG64 MmSystemCacheWs;
|
||||
ULONG64 MmPfnDatabase;
|
||||
ULONG64 MmSystemPtesStart;
|
||||
ULONG64 MmSystemPtesEnd;
|
||||
ULONG64 MmSubsectionBase;
|
||||
ULONG64 MmNumberOfPagingFiles;
|
||||
ULONG64 MmLowestPhysicalPage;
|
||||
ULONG64 MmHighestPhysicalPage;
|
||||
ULONG64 MmNumberOfPhysicalPages;
|
||||
ULONG64 MmMaximumNonPagedPoolInBytes;
|
||||
ULONG64 MmNonPagedSystemStart;
|
||||
ULONG64 MmNonPagedPoolStart;
|
||||
ULONG64 MmNonPagedPoolEnd;
|
||||
ULONG64 MmPagedPoolStart;
|
||||
ULONG64 MmPagedPoolEnd;
|
||||
ULONG64 MmPagedPoolInformation;
|
||||
ULONG64 MmPageSize;
|
||||
ULONG64 MmSizeOfPagedPoolInBytes;
|
||||
ULONG64 MmTotalCommitLimit;
|
||||
ULONG64 MmTotalCommittedPages;
|
||||
ULONG64 MmSharedCommit;
|
||||
ULONG64 MmDriverCommit;
|
||||
ULONG64 MmProcessCommit;
|
||||
ULONG64 MmPagedPoolCommit;
|
||||
ULONG64 MmExtendedCommit;
|
||||
ULONG64 MmZeroedPageListHead;
|
||||
ULONG64 MmFreePageListHead;
|
||||
ULONG64 MmStandbyPageListHead;
|
||||
ULONG64 MmModifiedPageListHead;
|
||||
ULONG64 MmModifiedNoWritePageListHead;
|
||||
ULONG64 MmAvailablePages;
|
||||
ULONG64 MmResidentAvailablePages;
|
||||
ULONG64 PoolTrackTable;
|
||||
ULONG64 NonPagedPoolDescriptor;
|
||||
ULONG64 MmHighestUserAddress;
|
||||
ULONG64 MmSystemRangeStart;
|
||||
ULONG64 MmUserProbeAddress;
|
||||
ULONG64 KdPrintCircularBuffer;
|
||||
ULONG64 KdPrintCircularBufferEnd;
|
||||
ULONG64 KdPrintWritePointer;
|
||||
ULONG64 KdPrintRolloverCount;
|
||||
ULONG64 MmLoadedUserImageList;
|
||||
ULONG64 NtBuildLab;
|
||||
ULONG64 KiNormalSystemCall;
|
||||
ULONG64 KiProcessorBlock;
|
||||
ULONG64 MmUnloadedDrivers;
|
||||
ULONG64 MmLastUnloadedDriver;
|
||||
ULONG64 MmTriageActionTaken;
|
||||
ULONG64 MmSpecialPoolTag;
|
||||
ULONG64 KernelVerifier;
|
||||
ULONG64 MmVerifierData;
|
||||
ULONG64 MmAllocatedNonPagedPool;
|
||||
ULONG64 MmPeakCommitment;
|
||||
ULONG64 MmTotalCommitLimitMaximum;
|
||||
ULONG64 CmNtCSDVersion;
|
||||
ULONG64 MmPhysicalMemoryBlock;
|
||||
ULONG64 MmSessionBase;
|
||||
ULONG64 MmSessionSize;
|
||||
ULONG64 MmSystemParentTablePage;
|
||||
ULONG64 MmVirtualTranslationBase;
|
||||
USHORT OffsetKThreadNextProcessor;
|
||||
USHORT OffsetKThreadTeb;
|
||||
USHORT OffsetKThreadKernelStack;
|
||||
USHORT OffsetKThreadInitialStack;
|
||||
USHORT OffsetKThreadApcProcess;
|
||||
USHORT OffsetKThreadState;
|
||||
USHORT OffsetKThreadBStore;
|
||||
USHORT OffsetKThreadBStoreLimit;
|
||||
USHORT SizeEProcess;
|
||||
USHORT OffsetEprocessPeb;
|
||||
USHORT OffsetEprocessParentCID;
|
||||
USHORT OffsetEprocessDirectoryTableBase;
|
||||
USHORT SizePrcb;
|
||||
USHORT OffsetPrcbDpcRoutine;
|
||||
USHORT OffsetPrcbCurrentThread;
|
||||
USHORT OffsetPrcbMhz;
|
||||
USHORT OffsetPrcbCpuType;
|
||||
USHORT OffsetPrcbVendorString;
|
||||
USHORT OffsetPrcbProcStateContext;
|
||||
USHORT OffsetPrcbNumber;
|
||||
USHORT SizeEThread;
|
||||
ULONG64 KdPrintCircularBufferPtr;
|
||||
ULONG64 KdPrintBufferSize;
|
||||
ULONG64 KeLoaderBlock;
|
||||
USHORT SizePcr;
|
||||
USHORT OffsetPcrSelfPcr;
|
||||
USHORT OffsetPcrCurrentPrcb;
|
||||
USHORT OffsetPcrContainedPrcb;
|
||||
USHORT OffsetPcrInitialBStore;
|
||||
USHORT OffsetPcrBStoreLimit;
|
||||
USHORT OffsetPcrInitialStack;
|
||||
USHORT OffsetPcrStackLimit;
|
||||
USHORT OffsetPrcbPcrPage;
|
||||
USHORT OffsetPrcbProcStateSpecialReg;
|
||||
USHORT GdtR0Code;
|
||||
USHORT GdtR0Data;
|
||||
USHORT GdtR0Pcr;
|
||||
USHORT GdtR3Code;
|
||||
USHORT GdtR3Data;
|
||||
USHORT GdtR3Teb;
|
||||
USHORT GdtLdt;
|
||||
USHORT GdtTss;
|
||||
USHORT Gdt64R3CmCode;
|
||||
USHORT Gdt64R3CmTeb;
|
||||
ULONG64 IopNumTriageDumpDataBlocks;
|
||||
ULONG64 IopTriageDumpDataBlocks;
|
||||
} KDDEBUGGER_DATA64, * PKDDEBUGGER_DATA64;
|
||||
|
||||
typedef struct _KDDEBUGGER_DATA_ADDITION64
|
||||
{
|
||||
ULONG64 VfCrashDataBlock;
|
||||
ULONG64 MmBadPagesDetected;
|
||||
ULONG64 MmZeroedPageSingleBitErrorsDetected;
|
||||
ULONG64 EtwpDebuggerData;
|
||||
USHORT OffsetPrcbContext;
|
||||
USHORT OffsetPrcbMaxBreakpoints;
|
||||
USHORT OffsetPrcbMaxWatchpoints;
|
||||
ULONG OffsetKThreadStackLimit;
|
||||
ULONG OffsetKThreadStackBase;
|
||||
ULONG OffsetKThreadQueueListEntry;
|
||||
ULONG OffsetEThreadIrpList;
|
||||
USHORT OffsetPrcbIdleThread;
|
||||
USHORT OffsetPrcbNormalDpcState;
|
||||
USHORT OffsetPrcbDpcStack;
|
||||
USHORT OffsetPrcbIsrStack;
|
||||
USHORT SizeKDPC_STACK_FRAME;
|
||||
USHORT OffsetKPriQueueThreadListHead;
|
||||
USHORT OffsetKThreadWaitReason;
|
||||
USHORT Padding;
|
||||
ULONG64 PteBase;
|
||||
ULONG64 RetpolineStubFunctionTable;
|
||||
ULONG RetpolineStubFunctionTableSize;
|
||||
ULONG RetpolineStubOffset;
|
||||
ULONG RetpolineStubSize;
|
||||
}KDDEBUGGER_DATA_ADDITION64, * PKDDEBUGGER_DATA_ADDITION64;
|
||||
|
||||
|
||||
typedef struct _DUMP_HEADER
|
||||
{
|
||||
ULONG Signature;
|
||||
ULONG ValidDump;
|
||||
ULONG MajorVersion;
|
||||
ULONG MinorVersion;
|
||||
ULONG_PTR DirectoryTableBase;
|
||||
ULONG_PTR PfnDataBase;
|
||||
PLIST_ENTRY PsLoadedModuleList;
|
||||
PLIST_ENTRY PsActiveProcessHead;
|
||||
ULONG MachineImageType;
|
||||
ULONG NumberProcessors;
|
||||
ULONG BugCheckCode;
|
||||
ULONG_PTR BugCheckParameter1;
|
||||
ULONG_PTR BugCheckParameter2;
|
||||
ULONG_PTR BugCheckParameter3;
|
||||
ULONG_PTR BugCheckParameter4;
|
||||
CHAR VersionUser[ 32 ];
|
||||
struct _KDDEBUGGER_DATA64* KdDebuggerDataBlock;
|
||||
} DUMP_HEADER, * PDUMP_HEADER;
|
||||
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, Signature ) == 0 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, ValidDump ) == 4 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MajorVersion ) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MinorVersion ) == 0xc );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, DirectoryTableBase ) == 0x10 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PfnDataBase ) == 0x18 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PsLoadedModuleList ) == 0x20 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, PsActiveProcessHead ) == 0x28 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, MachineImageType ) == 0x30 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, NumberProcessors ) == 0x34 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckCode ) == 0x38 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter1 ) == 0x40 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter2 ) == 0x48 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter3 ) == 0x50 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, BugCheckParameter4 ) == 0x58 );
|
||||
C_ASSERT( FIELD_OFFSET( DUMP_HEADER, KdDebuggerDataBlock ) == 0x80 );
|
||||
|
||||
#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
|
||||
|
||||
NTSYSAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
KeCapturePersistentThreadState(
|
||||
__in PCONTEXT Context,
|
||||
__in_opt PKTHREAD Thread,
|
||||
__in ULONG BugCheckCode,
|
||||
__in ULONG_PTR BugCheckParameter1,
|
||||
__in ULONG_PTR BugCheckParameter2,
|
||||
__in ULONG_PTR BugCheckParameter3,
|
||||
__in ULONG_PTR BugCheckParameter4,
|
||||
__in PDUMP_HEADER DumpHeader
|
||||
);
|
||||
|
||||
VOID ScanNonPagedPoolForProcessTags();
|
||||
|
||||
typedef union _DIRECTORY_TABLE_BASE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Ignored0 : 3; /* 2:0 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 _Ignored1 : 7; /* 11:5 */
|
||||
UINT64 PhysicalAddress : 36; /* 47:12 */
|
||||
UINT64 _Reserved0 : 16; /* 63:48 */
|
||||
|
||||
} Bits;
|
||||
|
||||
UINT64 BitAddress;
|
||||
|
||||
} CR3, DIR_TABLE_BASE;
|
||||
|
||||
typedef union _VIRTUAL_MEMORY_ADDRESS
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 PageIndex : 12; /* 0:11 */
|
||||
UINT64 PtIndex : 9; /* 12:20 */
|
||||
UINT64 PdIndex : 9; /* 21:29 */
|
||||
UINT64 PdptIndex : 9; /* 30:38 */
|
||||
UINT64 Pml4Index : 9; /* 39:47 */
|
||||
UINT64 Unused : 16; /* 48:63 */
|
||||
|
||||
} Bits;
|
||||
|
||||
UINT64 BitAddress;
|
||||
|
||||
} VIRTUAL_ADDRESS, * PVIRTUAL_ADDRESS;
|
||||
|
||||
typedef union _PML4_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 _Reserved0 : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 40; /* 51:12 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PML4E;
|
||||
|
||||
typedef union _PDPT_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 40; /* 51:12 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDPTE;
|
||||
|
||||
typedef union _PD_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 _Ignored0 : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 _Ignored1 : 4; /* 11:8 */
|
||||
UINT64 PhysicalAddress : 38; /* 49:12 */
|
||||
UINT64 _Reserved0 : 2; /* 51:50 */
|
||||
UINT64 _Ignored2 : 11; /* 62:52 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDE;
|
||||
|
||||
typedef union _PT_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageAttributeTable : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PhysicalAddress : 38; /* 49:12 */
|
||||
UINT64 _Reserved0 : 2; /* 51:50 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PTE;
|
||||
|
||||
typedef union _PDPT_ENTRY_LARGE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PageAttributeTable : 1; /* 12 */
|
||||
UINT64 _Reserved0 : 17; /* 29:13 */
|
||||
UINT64 PhysicalAddress : 22; /* 51:30 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDPTE_LARGE;
|
||||
|
||||
typedef union _PD_ENTRY_LARGE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT64 Present : 1; /* 0 */
|
||||
UINT64 ReadWrite : 1; /* 1 */
|
||||
UINT64 UserSupervisor : 1; /* 2 */
|
||||
UINT64 PageWriteThrough : 1; /* 3 */
|
||||
UINT64 PageCacheDisable : 1; /* 4 */
|
||||
UINT64 Accessed : 1; /* 5 */
|
||||
UINT64 Dirty : 1; /* 6 */
|
||||
UINT64 PageSize : 1; /* 7 */
|
||||
UINT64 Global : 1; /* 8 */
|
||||
UINT64 _Ignored0 : 3; /* 11:9 */
|
||||
UINT64 PageAttributeTalbe : 1; /* 12 */
|
||||
UINT64 _Reserved0 : 8; /* 20:13 */
|
||||
UINT64 PhysicalAddress : 29; /* 49:21 */
|
||||
UINT64 _Reserved1 : 2; /* 51:50 */
|
||||
UINT64 _Ignored1 : 7; /* 58:52 */
|
||||
UINT64 ProtectionKey : 4; /* 62:59 */
|
||||
UINT64 ExecuteDisable : 1; /* 63 */
|
||||
} Bits;
|
||||
UINT64 BitAddress;
|
||||
} PDE_LARGE;
|
||||
|
||||
/*
|
||||
* Generic macros that allow you to quickly determine whether
|
||||
* or not a page table entry is present or may forward to a
|
||||
* large page of data, rather than another page table (applies
|
||||
* only to PDPTEs and PDEs)
|
||||
*
|
||||
* Some nice macros courtesy of:
|
||||
* https://www.unknowncheats.me/forum/general-programming-and-reversing/523359-introduction-physical-memory.html
|
||||
*/
|
||||
#define IS_LARGE_PAGE(x) ( (BOOLEAN)((x >> 7) & 1) )
|
||||
#define IS_PAGE_PRESENT(x) ( (BOOLEAN)(x & 1) )
|
||||
|
||||
#define PAGE_1GB_SHIFT 30
|
||||
#define PAGE_1GB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_1GB_SHIFT)) )
|
||||
|
||||
#define PAGE_2MB_SHIFT 21
|
||||
#define PAGE_2MB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_2MB_SHIFT)) )
|
||||
|
||||
#define PAGE_4KB_SHIFT 12
|
||||
#define PAGE_4KB_OFFSET(x) ( x & (~(MAXUINT64 << PAGE_4KB_SHIFT)) )
|
||||
|
||||
PKDDEBUGGER_DATA64 GetGlobalDebuggerData();
|
||||
|
||||
#endif
|
|
@ -9,12 +9,6 @@
|
|||
#include "thread.h"
|
||||
#include "common.h"
|
||||
|
||||
typedef struct _REPORT_HEADER
|
||||
{
|
||||
INT report_id;
|
||||
|
||||
}REPORT_HEADER, * PREPORT_HEADER;
|
||||
|
||||
/*
|
||||
* This mutex is to prevent a new item being pushed to the queue
|
||||
* while the HandlePeriodicCallbackReportQueue is iterating through
|
||||
|
@ -23,7 +17,6 @@ typedef struct _REPORT_HEADER
|
|||
* can be pushed into the queue before the next iteration can take ownership
|
||||
* of the spinlock.
|
||||
*/
|
||||
|
||||
typedef struct _REPORT_QUEUE_CONFIGURATION
|
||||
{
|
||||
QUEUE_HEAD head;
|
||||
|
@ -200,7 +193,6 @@ NTSTATUS HandlePeriodicGlobalReportQueueQuery(
|
|||
);
|
||||
|
||||
total_size += sizeof( OPEN_HANDLE_FAILURE_REPORT );
|
||||
|
||||
break;
|
||||
|
||||
case REPORT_ILLEGAL_ATTACH_PROCESS:
|
||||
|
@ -212,7 +204,6 @@ NTSTATUS HandlePeriodicGlobalReportQueueQuery(
|
|||
);
|
||||
|
||||
total_size += sizeof( ATTACH_PROCESS_REPORT );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,7 @@
|
|||
#define QUEUE_H
|
||||
|
||||
#include <ntifs.h>
|
||||
|
||||
#define QUEUE_POOL_TAG 'qqqq'
|
||||
#define REPORT_QUEUE_TEMP_BUFFER_TAG 'temp'
|
||||
|
||||
#define REPORT_POOL_TAG 'repo'
|
||||
#include "common.h"
|
||||
|
||||
#define MAX_REPORTS_PER_IRP 20
|
||||
|
||||
|
@ -32,6 +28,12 @@ typedef struct _GLOBAL_REPORT_QUEUE_HEADER
|
|||
|
||||
}GLOBAL_REPORT_QUEUE_HEADER, * PGLOBAL_REPORT_QUEUE_HEADER;
|
||||
|
||||
typedef struct _REPORT_HEADER
|
||||
{
|
||||
INT report_id;
|
||||
|
||||
}REPORT_HEADER, * PREPORT_HEADER;
|
||||
|
||||
VOID QueuePush(
|
||||
_In_ PQUEUE_HEAD Head,
|
||||
_In_ PVOID Data
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "pool.h"
|
||||
#include "callbacks.h"
|
||||
#include "driver.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
|
@ -131,8 +133,12 @@ VOID DetectAttachedThreadsProcessCallback(
|
|||
PLIST_ENTRY thread_list_entry;
|
||||
PETHREAD current_thread;
|
||||
UINT32 thread_id;
|
||||
PKAPC_STATE apc_state;
|
||||
PEPROCESS protected_process = NULL;
|
||||
|
||||
if ( finished == TRUE )
|
||||
GetProtectedProcessEProcess( &protected_process );
|
||||
|
||||
if ( protected_process == NULL )
|
||||
return;
|
||||
|
||||
thread_list_head = ( PLIST_ENTRY )( ( UINT64 )Process + KPROCESS_THREADLIST_OFFSET );
|
||||
|
@ -142,7 +148,23 @@ VOID DetectAttachedThreadsProcessCallback(
|
|||
{
|
||||
current_thread = ( PETHREAD )( ( UINT64 )thread_list_entry - KTHREAD_THREADLIST_OFFSET );
|
||||
|
||||
apc_state = ( PKAPC_STATE )( ( UINT64 )current_thread + KTHREAD_APC_STATE_OFFSET );
|
||||
|
||||
if ( apc_state->Process == protected_process )
|
||||
{
|
||||
DEBUG_LOG( "Program attached to notepad: %llx", ( UINT64 )current_thread );
|
||||
|
||||
PATTACH_PROCESS_REPORT report = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( ATTACH_PROCESS_REPORT ), REPORT_POOL_TAG );
|
||||
|
||||
if ( !report )
|
||||
return;
|
||||
|
||||
report->report_code = REPORT_ILLEGAL_ATTACH_PROCESS;
|
||||
report->thread_id = PsGetThreadId( current_thread );
|
||||
report->thread_address = current_thread;
|
||||
|
||||
InsertReportToQueue( report );
|
||||
}
|
||||
|
||||
thread_list_entry = thread_list_entry->Flink;
|
||||
}
|
||||
|
@ -155,16 +177,16 @@ VOID DetectAttachedThreadsProcessCallback(
|
|||
* https://github.com/KANKOSHEV/Detect-KeAttachProcess/tree/main
|
||||
* https://doxygen.reactos.org/d0/dc9/procobj_8c.html#adec6dc539d4a5c0ee7d0f48e24ef0933
|
||||
*
|
||||
* Then from here you can see that the _KAPC_STATE structure in the KTHREAD stores the
|
||||
* APC state for the thread. The Process field in this structure is the offset referred to
|
||||
* in KANKOSHEV's proof of concept. This the field that is updated by KiAttachProcess when
|
||||
* calling KeStackAttachProcess.
|
||||
* To expand on his writeup a little, the offset that he provides is equivalent to PKAPC_STATE->Process.
|
||||
* This is where KiAttachProcess writes the process that thread is attaching to when it's called.
|
||||
* The APC_STATE structure holds relevant information about the thread's APC state and is quite
|
||||
* important during context switch scenarios as it's how the thread determines if it has any APC's
|
||||
* queued.
|
||||
*/
|
||||
VOID DetectThreadsAttachedToProtectedProcess(
|
||||
_In_ PIRP Irp
|
||||
)
|
||||
VOID DetectThreadsAttachedToProtectedProcess()
|
||||
{
|
||||
EnumerateProcessListWithCallbackFunction(
|
||||
DetectAttachedThreadsProcessCallback
|
||||
);
|
||||
}
|
||||
|
|
@ -5,20 +5,6 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define IA32_GS_BASE 0xc0000101
|
||||
#define KPRCB_OFFSET_FROM_GS_BASE 0x180
|
||||
#define KPCRB_CURRENT_THREAD 0x8
|
||||
#define KPROCESS_THREADLIST_OFFSET 0x030
|
||||
#define KTHREAD_THREADLIST_OFFSET 0x2f8
|
||||
|
||||
#define REPORT_HIDDEN_SYSTEM_THREAD 90
|
||||
|
||||
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
|
||||
|
||||
VOID ValidateKPCRBThreads(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
typedef struct _HIDDEN_SYSTEM_THREAD_REPORT
|
||||
{
|
||||
INT report_code;
|
||||
|
@ -33,7 +19,15 @@ typedef struct _HIDDEN_SYSTEM_THREAD_REPORT
|
|||
typedef struct _ATTACH_PROCESS_REPORT
|
||||
{
|
||||
INT report_code;
|
||||
UINT32 thread_id;
|
||||
UINT64 thread_address;
|
||||
|
||||
}ATTACH_PROCESS_REPORT, *PATTACH_PROCESS_REPORT;
|
||||
|
||||
VOID ValidateKPCRBThreads(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
VOID DetectThreadsAttachedToProtectedProcess();
|
||||
|
||||
#endif
|
30
server/Dispatch.cs
Normal file
30
server/Dispatch.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace server
|
||||
{
|
||||
public class Dispatch
|
||||
{
|
||||
private TcpClient _client;
|
||||
private NetworkStream _stream;
|
||||
private byte[] _buffer;
|
||||
|
||||
public Dispatch(TcpClient client, NetworkStream stream)
|
||||
{
|
||||
_client = client;
|
||||
_stream = stream;
|
||||
_buffer = new byte[1024];
|
||||
|
||||
this.AcceptMessage();
|
||||
}
|
||||
|
||||
private void AcceptMessage()
|
||||
{
|
||||
_stream.BeginRead(_buffer, 0, 1024, null, null);
|
||||
}
|
||||
}
|
||||
}
|
67
server/Message.cs
Normal file
67
server/Message.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
|
||||
namespace server
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private int _bufferSize;
|
||||
private int _messageType;
|
||||
|
||||
private enum MESSAGE_TYPE
|
||||
{
|
||||
MESSAGE_TYPE_REPORT = 1,
|
||||
MESSAGE_TYPE_SEND = 2,
|
||||
MESSAGE_TYPE_RECEIVE = 3
|
||||
}
|
||||
|
||||
struct PACKET_HEADER
|
||||
{
|
||||
int messageType;
|
||||
}
|
||||
|
||||
struct REPORT_PACKET_HEADER
|
||||
{
|
||||
int reportId;
|
||||
}
|
||||
|
||||
public Message(byte[] buffer, int bufferSize)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_bufferSize = bufferSize;
|
||||
|
||||
this.GetMessageType();
|
||||
|
||||
switch (_messageType)
|
||||
{
|
||||
case (int)MESSAGE_TYPE.MESSAGE_TYPE_REPORT:
|
||||
this.HandleReportMessage(this.GetReportType());
|
||||
break;
|
||||
default:
|
||||
Log.Logger.Information("This message type is not accepted at the moment.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetMessageType()
|
||||
{
|
||||
_messageType = BitConverter.ToInt32(_buffer, 0);
|
||||
}
|
||||
|
||||
private int GetReportType()
|
||||
{
|
||||
return BitConverter.ToInt32(_buffer, sizeof(int));
|
||||
}
|
||||
|
||||
private void HandleReportMessage(int reportId)
|
||||
{
|
||||
Log.Logger.Information("Report id: {0}", reportId);
|
||||
}
|
||||
}
|
||||
}
|
30
server/Server.cs
Normal file
30
server/Server.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text;
|
||||
using server;
|
||||
|
||||
namespace server
|
||||
{
|
||||
public class Server
|
||||
{
|
||||
private IPEndPoint _ipEndPoint;
|
||||
private TcpListener _tcpListener;
|
||||
|
||||
public Server()
|
||||
{
|
||||
_ipEndPoint = new IPEndPoint(IPAddress.Any, 8888);
|
||||
_tcpListener = new TcpListener(_ipEndPoint);
|
||||
}
|
||||
|
||||
public async Task Listen()
|
||||
{
|
||||
_tcpListener.Start();
|
||||
|
||||
using TcpClient _client = await _tcpListener.AcceptTcpClientAsync();
|
||||
|
||||
Thread dispatchThread = new Thread(() => new Dispatch(_client, _client.GetStream()));
|
||||
dispatchThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
@ -7,4 +7,8 @@
|
|||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog" Version="3.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -3,39 +3,30 @@ using System.Net;
|
|||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Serilog;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace service
|
||||
{
|
||||
public class Client
|
||||
{
|
||||
public static async Task SendToServer()
|
||||
private IPEndPoint _ipEndPoint;
|
||||
private TcpClient _tcpClient;
|
||||
private byte[] _buffer;
|
||||
private int _bufferSize;
|
||||
|
||||
public Client(byte[] buffer, int bufferSize)
|
||||
{
|
||||
var ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
|
||||
|
||||
using TcpClient client = new();
|
||||
|
||||
await client.ConnectAsync(ipEndPoint);
|
||||
await using NetworkStream stream = client.GetStream();
|
||||
|
||||
var testMessage = "Hello from client";
|
||||
|
||||
stream.BeginWrite(Encoding.UTF8.GetBytes(testMessage), 0, testMessage.Length, Callback, null);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int received = await stream.ReadAsync(buffer);
|
||||
|
||||
var message = Encoding.UTF8.GetString(buffer, 0, received);
|
||||
Console.WriteLine($"Message received: \"{message}\"");
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
}
|
||||
_ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
|
||||
_tcpClient = new TcpClient();
|
||||
_buffer = buffer;
|
||||
_bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
private static void Callback(IAsyncResult ar)
|
||||
public void SendMessageToServer()
|
||||
{
|
||||
Log.Information("Sent message lolz");
|
||||
_tcpClient.Connect(_ipEndPoint);
|
||||
NetworkStream stream = _tcpClient.GetStream();
|
||||
stream.BeginWrite(_buffer, 0, _bufferSize, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
40
service/Message.cs
Normal file
40
service/Message.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO.Pipes;
|
||||
using service;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace service
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
private NamedPipeServerStream _pipeServer;
|
||||
private byte[] _buffer;
|
||||
private int _bufferSize;
|
||||
public Message(NamedPipeServerStream pipeServer)
|
||||
{
|
||||
_pipeServer = pipeServer;
|
||||
_bufferSize = _pipeServer.InBufferSize;
|
||||
_buffer = new byte[_bufferSize];
|
||||
}
|
||||
|
||||
public async Task ReadPipeBuffer()
|
||||
{
|
||||
await _pipeServer.ReadAsync(_buffer, 0, _bufferSize);
|
||||
}
|
||||
|
||||
public void SendMessageToServer()
|
||||
{
|
||||
Client client = new Client(_buffer, _bufferSize);
|
||||
client.SendMessageToServer();
|
||||
}
|
||||
|
||||
public T GetPacketHeader<T>(ref byte[] buffer)
|
||||
{
|
||||
return Helper.BytesToStructure<T>(ref buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ using System.IO.Pipes;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using service.Types;
|
||||
using service.messages;
|
||||
using System;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
#pragma warning disable CS8600
|
||||
|
@ -57,24 +57,13 @@ namespace service
|
|||
{
|
||||
try
|
||||
{
|
||||
if (_pipeServer.Read(_header, 0, _headerSize) > 0)
|
||||
if (_pipeServer.InBufferSize > 0)
|
||||
{
|
||||
// for now the header is only an int... LOL
|
||||
int header = BitConverter.ToInt32(_header, 0);
|
||||
_logger.LogInformation("Message received at pipe server");
|
||||
|
||||
_logger.LogInformation("Message received with id: {0}", header);
|
||||
|
||||
switch (header)
|
||||
{
|
||||
case (int)MESSAGE_TYPE.MESSAGE_TYPE_REPORT:
|
||||
_logger.LogDebug("We are inside the message report case");
|
||||
Report report = new Report(_pipeServer, _headerSize);
|
||||
break;
|
||||
|
||||
case (int)MESSAGE_TYPE.MESSAGE_TYPE_RECEIVE:
|
||||
Receive receive = new Receive(_pipeServer, _headerSize);
|
||||
break;
|
||||
}
|
||||
Message message = new Message(_pipeServer);
|
||||
await message.ReadPipeBuffer();
|
||||
message.SendMessageToServer();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace service.messages
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
private NamedPipeServerStream _pipeServer;
|
||||
private int _packetHeaderSize;
|
||||
public Message(NamedPipeServerStream pipeServer, int packetHeaderSize)
|
||||
{
|
||||
_pipeServer = pipeServer;
|
||||
_packetHeaderSize = packetHeaderSize;
|
||||
}
|
||||
|
||||
public void ReadPipeBuffer(ref byte[] buffer, int bufferSize )
|
||||
{
|
||||
_pipeServer.Read(buffer, 0, bufferSize - _packetHeaderSize);
|
||||
}
|
||||
|
||||
public T GetPacketHeader<T>(ref byte[] buffer)
|
||||
{
|
||||
return Helper.BytesToStructure<T>(ref buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace service.messages
|
||||
{
|
||||
public class Receive : Message
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private static int RECEIVE_BUFFER_SIZE = 8192;
|
||||
|
||||
private enum RECEIVE_TYPE
|
||||
{
|
||||
SERVER_SEND_MODULE_INTEGRITY_CHECK = 10
|
||||
}
|
||||
|
||||
public Receive(NamedPipeServerStream pipeServer, int pipePacketHeaderSize)
|
||||
: base(pipeServer, pipePacketHeaderSize)
|
||||
{
|
||||
_buffer = new byte[RECEIVE_BUFFER_SIZE];
|
||||
|
||||
StoreMessage();
|
||||
}
|
||||
|
||||
public void StoreMessage()
|
||||
{
|
||||
ReadPipeBuffer(ref _buffer, RECEIVE_BUFFER_SIZE);
|
||||
|
||||
Types.Receive.PIPE_PACKET_SEND_EXTENSION_HEADER header =
|
||||
GetPacketHeader<Types.Receive.PIPE_PACKET_SEND_EXTENSION_HEADER>(ref _buffer);
|
||||
|
||||
PrintPacketInformation(header);
|
||||
}
|
||||
|
||||
private void PrintPacketInformation(Types.Receive.PIPE_PACKET_SEND_EXTENSION_HEADER header)
|
||||
{
|
||||
Log.Information("Incoming packet count: {0:x}, current packet num: {1:x}, current packet size: {2:x}, total packet size: {3:x}",
|
||||
header.total_incoming_packet_count,
|
||||
header.current_packet_number,
|
||||
header.packet_size,
|
||||
header.total_incoming_packet_size);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using service;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using service.Types.Reports;
|
||||
using Serilog;
|
||||
|
||||
namespace service.messages
|
||||
{
|
||||
public class Report : Message
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private static int REPORT_BUFFER_SIZE = 1024;
|
||||
|
||||
private enum REPORT_TYPE
|
||||
{
|
||||
REPORT_PROCESS_MODULE_FAILURE = 10,
|
||||
REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE = 20,
|
||||
REPORT_PAGE_PROTECTION_VERIFICATION = 30,
|
||||
REPORT_PATTERN_SCAN_FAILURE = 40,
|
||||
REPORT_NMI_CALLBACK_FAILURE = 50,
|
||||
REPORT_KERNEL_MODULE_FAILURE = 60,
|
||||
REPORT_OPEN_HANDLE_FAILURE_REPORT = 70
|
||||
}
|
||||
|
||||
public Report(NamedPipeServerStream pipeServer, int pipePacketHeaderSize)
|
||||
: base(pipeServer, pipePacketHeaderSize)
|
||||
{
|
||||
_buffer = new byte[REPORT_BUFFER_SIZE];
|
||||
|
||||
ReadPipeBuffer(ref _buffer, REPORT_BUFFER_SIZE);
|
||||
|
||||
ConvertByteReportIntoStructure();
|
||||
}
|
||||
|
||||
// This is fine for now as the report header is only an int
|
||||
private int GetReportType()
|
||||
{
|
||||
return BitConverter.ToInt32( _buffer, 0 );
|
||||
}
|
||||
private Task ConvertByteReportIntoStructure()
|
||||
{
|
||||
int reportType = GetReportType();
|
||||
|
||||
Log.Information("REport type: {0}", reportType);
|
||||
|
||||
if (!Enum.IsDefined(typeof(REPORT_TYPE), reportType))
|
||||
{
|
||||
Log.Error("Enum value of {0} is invalid.", reportType);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
switch(reportType)
|
||||
{
|
||||
case (int)REPORT_TYPE.REPORT_PROCESS_MODULE_FAILURE:
|
||||
PrintProcessModuleFailureReport();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE:
|
||||
PrintStartAddressFailure();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_PAGE_PROTECTION_VERIFICATION:
|
||||
PrintPageProtectionFailure();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_PATTERN_SCAN_FAILURE:
|
||||
PrintPatternScanFailure();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_NMI_CALLBACK_FAILURE:
|
||||
PrintNmiCallbackFailure();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_KERNEL_MODULE_FAILURE:
|
||||
PrintKernelModuleFailure();
|
||||
break;
|
||||
case (int)REPORT_TYPE.REPORT_OPEN_HANDLE_FAILURE_REPORT:
|
||||
PrintOpenHandleFailure();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void PrintProcessModuleFailureReport()
|
||||
{
|
||||
MODULE_VERIFICATION_CHECKSUM_FAILURE report = Helper.BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, Base address: {1:x}, Size: {2:x}, Name: ",
|
||||
report.ReportCode,
|
||||
report.ModuleBaseAddress,
|
||||
report.ModuleSize);
|
||||
}
|
||||
|
||||
private void PrintStartAddressFailure()
|
||||
{
|
||||
PROCESS_THREAD_START_FAILURE report = Helper.BytesToStructure<PROCESS_THREAD_START_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, Thread Id: {1:x}, Start Address: {2:x}",
|
||||
report.ReportCode,
|
||||
report.ThreadId,
|
||||
report.StartAddress);
|
||||
}
|
||||
|
||||
private void PrintPageProtectionFailure()
|
||||
{
|
||||
PAGE_PROTECTION_FAILURE report = Helper.BytesToStructure<PAGE_PROTECTION_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, page base address: {1:x}, allocation protection {2:x}, allocation state: {3:x}, allocation type: {4:x}",
|
||||
report.ReportCode,
|
||||
report.PageBaseAddress,
|
||||
report.AllocationProtection,
|
||||
report.AllocationState,
|
||||
report.AllocationType);
|
||||
}
|
||||
|
||||
private void PrintPatternScanFailure()
|
||||
{
|
||||
PATTERN_SCAN_FAILURE report = Helper.BytesToStructure<PATTERN_SCAN_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, signature id: {1:x}, Address: {2:x}",
|
||||
report.ReportCode,
|
||||
report.SignatureId,
|
||||
report.Address);
|
||||
}
|
||||
|
||||
private void PrintNmiCallbackFailure()
|
||||
{
|
||||
NMI_CALLBACK_FAILURE report = Helper.BytesToStructure<NMI_CALLBACK_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, WereNmisDisabled: {1:x}, KThreadAddress: {2:x}, InvalidRip: {3:x}",
|
||||
report.ReportCode,
|
||||
report.WereNmisDisabled,
|
||||
report.KThreadAddress,
|
||||
report.InvalidRip);
|
||||
}
|
||||
|
||||
private void PrintKernelModuleFailure()
|
||||
{
|
||||
MODULE_VALIDATION_FAILURE report = Helper.BytesToStructure<MODULE_VALIDATION_FAILURE>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, REportType: {1:x}, DriverBaseAddress: {2:x}, DriverSize: {3:x}",
|
||||
report.ReportCode,
|
||||
report.ReportType,
|
||||
report.DriverBaseAddress,
|
||||
report.DriverSize);
|
||||
}
|
||||
|
||||
private void PrintOpenHandleFailure()
|
||||
{
|
||||
OPEN_HANDLE_FAILURE_REPORT report = Helper.BytesToStructure<OPEN_HANDLE_FAILURE_REPORT>(ref _buffer);
|
||||
|
||||
Log.Information("Report code: {0}, ProcessID: {1:x}, ThreadId: {2:x}, DesiredAccess{3:x}",
|
||||
report.ReportCode,
|
||||
report.ProcessId,
|
||||
report.ThreadId,
|
||||
report.DesiredAccess);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace service.messages
|
||||
{
|
||||
public class Send : Message
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private static int SEND_BUFFER_SIZE = 8192;
|
||||
|
||||
private enum SEND_TYPE
|
||||
{
|
||||
SEND_SIGNATURES_TO_SCAN = 10
|
||||
}
|
||||
|
||||
public Send(NamedPipeServerStream pipeServer, int pipePacketHeaderSize)
|
||||
: base(pipeServer, pipePacketHeaderSize)
|
||||
{
|
||||
_buffer = new byte[SEND_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -174,6 +174,8 @@ namespace global
|
|||
struct ATTACH_PROCESS_REPORT
|
||||
{
|
||||
INT report_code;
|
||||
UINT32 thread_id;
|
||||
UINT64 thread_address;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,13 +201,10 @@ VOID kernelmode::Driver::QueryReportQueue()
|
|||
if ( header->count == 0 )
|
||||
goto end;
|
||||
|
||||
LOG_INFO( "report count: %i", header->count );
|
||||
|
||||
for ( int i = 0; i < header->count; i++ )
|
||||
for ( INT i = 0; i < header->count; i++ )
|
||||
{
|
||||
report_header = (REPORT_ID*)( ( UINT64 )buffer + sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) + total_size );
|
||||
|
||||
LOG_INFO( "REport id: %i", report_header->report_id );
|
||||
report_header = (REPORT_ID*)( ( UINT64 )buffer +
|
||||
sizeof( global::report_structures::OPEN_HANDLE_FAILURE_REPORT_HEADER ) + total_size );
|
||||
|
||||
switch ( report_header->report_id )
|
||||
{
|
||||
|
@ -484,6 +481,25 @@ VOID kernelmode::Driver::ValidateKPRCBThreads()
|
|||
this->report_interface->ServerSend( &report, bytes_returned, SERVER_SEND_MODULE_INTEGRITY_CHECK );
|
||||
}
|
||||
|
||||
VOID kernelmode::Driver::CheckForAttachedThreads()
|
||||
{
|
||||
BOOLEAN status;
|
||||
|
||||
status = DeviceIoControl(
|
||||
this->driver_handle,
|
||||
IOCTL_DETECT_ATTACHED_THREADS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( status == NULL )
|
||||
LOG_ERROR( "failed to check for attached threads %x", GetLastError() );
|
||||
}
|
||||
|
||||
VOID kernelmode::Driver::CheckDriverHeartbeat()
|
||||
{
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define IOCTL_SCAN_FOR_UNLINKED_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2011, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_VALIDATE_KPRCB_CURRENT_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2012, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define MAX_REPORTS_PER_IRP 20
|
||||
|
||||
|
@ -49,6 +50,7 @@ namespace kernelmode
|
|||
VOID RequestModuleExecutableRegions();
|
||||
VOID ScanForUnlinkedProcess();
|
||||
VOID PerformIntegrityCheck();
|
||||
VOID CheckForAttachedThreads();
|
||||
};
|
||||
|
||||
struct DRIVER_INITIATION_INFORMATION
|
||||
|
|
|
@ -45,3 +45,8 @@ VOID kernelmode::KManager::PerformIntegrityCheck()
|
|||
{
|
||||
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->PerformIntegrityCheck(); } );
|
||||
}
|
||||
|
||||
VOID kernelmode::KManager::CheckForAttachedThreads()
|
||||
{
|
||||
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->CheckForAttachedThreads(); } );
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace kernelmode
|
|||
VOID RequestModuleExecutableRegionsForIntegrityCheck();
|
||||
VOID ScanPoolsForUnlinkedProcesses();
|
||||
VOID PerformIntegrityCheck();
|
||||
VOID CheckForAttachedThreads();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue