*******************************************************************************
nt!DbgBreakPointWithStatus:
fffff805`7affd0b0 cc int 3
kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF
kd> ed nt!Kd_IHVDRIVER_Mask 0xFFFFFFFF
kd> g
[+] [DriverEntry] 驱动加载开始
[+] [DriverEntry] 驱动加载成功
[+] [ProcessNotifyCallback] 目标进程 oxygen.exe 创建 (PID: 7424)
[+] [ProcessNotifyCallback] 工作线程已创建
[+] Worker thread started for hook installation on PID: 7424
Break instruction exception - code 80000003 (first chance)
obpcallback!InstallHook+0x50:
fffff805`802b12f0 cc int 3
kd> g
[+] [InstallHook] 找到目标函数地址: FFFFF8057B2EFB60
KDTARGET: Refreshing KD connection
*** Fatal System Error: 0x0000001a
(0x0000000000001240,0xFFFFBD046C12D640,0xFFFFE20000000000,0x0000000000000000)
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
For analysis of this file, run !analyze -v
nt!DbgBreakPointWithStatus:
fffff805`7affd0b0 cc int 3
kd> !analyze -v
Connected to Windows 10 19041 x64 target at (Wed Jul 9 22:53:25.414 2025 (UTC + 8:00)), ptr64 TRUE
Loading Kernel Symbols
...................................
Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long.
Run !sym noisy before .reload to track down problems loading symbols.
............................
................................................................
.....................................................
Loading User Symbols
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
Loading unloaded module list
......
ERROR: FindPlugIns 8007007b
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
MEMORY_MANAGEMENT (1a)
# Any other values for parameter 1 must be individually examined.
Arguments:
Arg1: 0000000000001240, The subtype of the BugCheck.
Arg2: ffffbd046c12d640
Arg3: ffffe20000000000
Arg4: 0000000000000000
Debugging Details:
------------------
Press ctrl-c (cdb, kd, ntsd) or ctrl-break (windbg) to abort symbol loads that take too long.
Run !sym noisy before .reload to track down problems loading symbols.
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 00000000`003f2018). Type ".hh dbgerr001" for details
KEY_VALUES_STRING: 1
Key : Analysis.CPU.mSec
Value: 4609
Key : Analysis.Elapsed.mSec
Value: 41822
Key : Analysis.IO.Other.Mb
Value: 0
Key : Analysis.IO.Read.Mb
Value: 3
Key : Analysis.IO.Write.Mb
Value: 1
Key : Analysis.Init.CPU.mSec
Value: 3375
Key : Analysis.Init.Elapsed.mSec
Value: 52339
Key : Analysis.Memory.CommitPeak.Mb
Value: 66
Key : Analysis.Version.DbgEng
Value: 10.0.27829.1001
Key : Analysis.Version.Description
Value: 10.2503.24.01 amd64fre
Key : Analysis.Version.Ext
Value: 1.2503.24.1
Key : Bugcheck.Code.KiBugCheckData
Value: 0x1a
Key : Bugcheck.Code.LegacyAPI
Value: 0x1a
Key : Bugcheck.Code.TargetModel
Value: 0x1a
Key : Failure.Bucket
Value: 0x1a_1240_obpcallback!PteHookManager::fn_pa_to_va
Key : Failure.Hash
Value: {8b1bf815-3433-a8c2-3b59-c418f61f9c76}
Key : Hypervisor.Enlightenments.Value
Value: 12576
Key : Hypervisor.Enlightenments.ValueHex
Value: 0x3120
Key : Hypervisor.Flags.AnyHypervisorPresent
Value: 1
Key : Hypervisor.Flags.ApicEnlightened
Value: 0
Key : Hypervisor.Flags.ApicVirtualizationAvailable
Value: 0
Key : Hypervisor.Flags.AsyncMemoryHint
Value: 0
Key : Hypervisor.Flags.CoreSchedulerRequested
Value: 0
Key : Hypervisor.Flags.CpuManager
Value: 0
Key : Hypervisor.Flags.DeprecateAutoEoi
Value: 1
Key : Hypervisor.Flags.DynamicCpuDisabled
Value: 0
Key : Hypervisor.Flags.Epf
Value: 0
Key : Hypervisor.Flags.ExtendedProcessorMasks
Value: 0
Key : Hypervisor.Flags.HardwareMbecAvailable
Value: 0
Key : Hypervisor.Flags.MaxBankNumber
Value: 0
Key : Hypervisor.Flags.MemoryZeroingControl
Value: 0
Key : Hypervisor.Flags.NoExtendedRangeFlush
Value: 1
Key : Hypervisor.Flags.NoNonArchCoreSharing
Value: 0
Key : Hypervisor.Flags.Phase0InitDone
Value: 1
Key : Hypervisor.Flags.PowerSchedulerQos
Value: 0
Key : Hypervisor.Flags.RootScheduler
Value: 0
Key : Hypervisor.Flags.SynicAvailable
Value: 1
Key : Hypervisor.Flags.UseQpcBias
Value: 0
Key : Hypervisor.Flags.Value
Value: 536632
Key : Hypervisor.Flags.ValueHex
Value: 0x83038
Key : Hypervisor.Flags.VpAssistPage
Value: 1
Key : Hypervisor.Flags.VsmAvailable
Value: 0
Key : Hypervisor.RootFlags.AccessStats
Value: 0
Key : Hypervisor.RootFlags.CrashdumpEnlightened
Value: 0
Key : Hypervisor.RootFlags.CreateVirtualProcessor
Value: 0
Key : Hypervisor.RootFlags.DisableHyperthreading
Value: 0
Key : Hypervisor.RootFlags.HostTimelineSync
Value: 0
Key : Hypervisor.RootFlags.HypervisorDebuggingEnabled
Value: 0
Key : Hypervisor.RootFlags.IsHyperV
Value: 0
Key : Hypervisor.RootFlags.LivedumpEnlightened
Value: 0
Key : Hypervisor.RootFlags.MapDeviceInterrupt
Value: 0
Key : Hypervisor.RootFlags.MceEnlightened
Value: 0
Key : Hypervisor.RootFlags.Nested
Value: 0
Key : Hypervisor.RootFlags.StartLogicalProcessor
Value: 0
Key : Hypervisor.RootFlags.Value
Value: 0
Key : Hypervisor.RootFlags.ValueHex
Value: 0x0
Key : SecureKernel.HalpHvciEnabled
Value: 0
Key : WER.OS.Branch
Value: vb_release
Key : WER.OS.Version
Value: 10.0.19041.1
BUGCHECK_CODE: 1a
BUGCHECK_P1: 1240
BUGCHECK_P2: ffffbd046c12d640
BUGCHECK_P3: ffffe20000000000
BUGCHECK_P4: 0
FAULTING_THREAD: ffffbd046c162080
PROCESS_NAME: oxygen.exe
STACK_TEXT:
fffffc89`cd605028 fffff805`7b111882 : fffffc89`cd605190 fffff805`7af7c940 00000000`00000000 00000000`00000000 : nt!DbgBreakPointWithStatus
fffffc89`cd605030 fffff805`7b110e66 : 00000000`00000003 fffffc89`cd605190 fffff805`7b00a0c0 00000000`0000001a : nt!KiBugCheckDebugBreak+0x12
fffffc89`cd605090 fffff805`7aff5317 : 00000000`00000000 00000000`00001000 00000000`00000000 00000000`00000000 : nt!KeBugCheck2+0x946
fffffc89`cd6057a0 fffff805`7b02e1b6 : 00000000`0000001a 00000000`00001240 ffffbd04`6c12d640 ffffe200`00000000 : nt!KeBugCheckEx+0x107
fffffc89`cd6057e0 fffff805`802b2048 : 00000000`00000000 ffffbd04`6545f1c0 00000000`00000000 ffffe200`00000008 : nt!MmBuildMdlForNonPagedPool+0x1e4d16
fffffc89`cd6058a0 fffff805`802b28ae : ffffbd04`64f74000 00000001`747f8000 00000000`00450000 fffff805`7b2ac96b : obpcallback!PteHookManager::fn_pa_to_va+0x138 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 486]
fffffc89`cd605910 fffff805`802b1a6c : ffffbd04`64f74000 00000001`747f8000 fffffc89`cd605a20 fffff805`7de94000 : obpcallback!PteHookManager::get_page_table+0x9e [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 539]
fffffc89`cd6059b0 fffff805`802b21ff : ffffbd04`64f74000 00000000`00001d00 fffff805`7b2efb60 00000000`00000035 : obpcallback!PteHookManager::fn_isolation_pages+0x10c [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 875]
fffffc89`cd605ad0 fffff805`802b1344 : ffffbd04`64f74000 00000000`00001d00 fffffc89`cd605bb0 fffff805`802b1500 : obpcallback!PteHookManager::fn_pte_inline_hook_bp_pg+0x4f [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 1015]
fffffc89`cd605b90 fffff805`802b13d4 : fffff805`802b3d20 00000000`00001d00 00000000`00000000 fffff805`75eaf180 : obpcallback!InstallHook+0xa4 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 1343]
fffffc89`cd605be0 fffff805`7aea29a5 : 00000000`00001d00 fffff805`802b13a0 00000000`00001d00 ffffb90d`00000001 : obpcallback!InstallHookWorker+0x34 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 1371]
fffffc89`cd605c10 fffff805`7affc868 : fffff805`75eaf180 ffffbd04`6c162080 fffff805`7aea2950 fffff805`00000000 : nt!PspSystemThreadStartup+0x55
fffffc89`cd605c60 00000000`00000000 : fffffc89`cd606000 fffffc89`cd600000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x28
FAULTING_SOURCE_LINE: C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp
FAULTING_SOURCE_FILE: C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp
FAULTING_SOURCE_LINE_NUMBER: 486
FAULTING_SOURCE_CODE:
482:
483: PVOID va = nullptr;
484: __try {
485: MmBuildMdlForNonPagedPool(pMdl);
> 486: MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
487: va = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);
488:
489: if (va) {
490: // ?¨ª????MDL????
491: if (m_MdlCount < MAX_MDL_CACHE) {
SYMBOL_NAME: obpcallback!PteHookManager::fn_pa_to_va+138
MODULE_NAME: obpcallback
IMAGE_NAME: obpcallback.sys
STACK_COMMAND: .process /r /p 0xffffbd046545f1c0; .thread 0xffffbd046c162080 ; kb
BUCKET_ID_FUNC_OFFSET: 138
FAILURE_BUCKET_ID: 0x1a_1240_obpcallback!PteHookManager::fn_pa_to_va
OS_VERSION: 10.0.19041.1
BUILDLAB_STR: vb_release
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
FAILURE_ID_HASH: {8b1bf815-3433-a8c2-3b59-c418f61f9c76}
Followup: MachineOwner
---------
改为又出问题了,你找找问题。一直是访问有问题。应该是代码有流程出问题了。代码如下:#include <ntifs.h>
#include <ntddk.h>
#include <intrin.h>
#include "ptehook.h"
#define CR0_WP (1 << 16)
// 在类定义前添加以下常量定义
#define DIRECT_MAPPING_BASE 0xFFFF000000000000ULL
// 页表标志位
#define PTE_GLOBAL_FLAG (1ULL << 8)
#define PDE_GLOBAL_FLAG (1ULL << 8)
#define PDPTE_GLOBAL_FLAG (1ULL << 8)
#define PTE_WRITABLE_FLAG (1ULL << 1)
#define PTE_NOEXECUTE_FLAG (1ULL << 63)
#define PDE_2MB_PAGE_FLAG (1ULL << 7)
#define PDPTE_1GB_PAGE_FLAG (1ULL << 7)
HANDLE targetProcessId = NULL;
typedef INT(*LDE_DISASM)(PVOID address, INT bits);
typedef unsigned long DWORD;
typedef unsigned __int64 ULONG64;
// 使用WDK标准类型
typedef unsigned char BYTE;
typedef LONG NTSTATUS;
// 修正后的跳转指令结构
#pragma pack(push, 1)
typedef struct _JMP_ABS {
BYTE opcode[6]; // FF 25 00 00 00 00
ULONG64 address; // 8字节绝对地址
} JMP_ABS, * PJMP_ABS;
#pragma pack(pop)
LDE_DISASM lde_disasm;
// 初始化引擎
VOID lde_init()
{
lde_disasm = (LDE_DISASM)ExAllocatePool(NonPagedPool, 12800);
memcpy(lde_disasm, szShellCode, 12800);
}
// 得到完整指令长度,避免截断
ULONG GetFullPatchSize(PUCHAR Address)
{
ULONG LenCount = 0, Len = 0;
// 至少需要14字节
while (LenCount <= 14)
{
Len = lde_disasm(Address, 64);
Address = Address + Len;
LenCount = LenCount + Len;
}
return LenCount;
}
#define PROCESS_NAME_LENGTH 16
#define DRIVER_TAG 'HKOB'
EXTERN_C char* PsGetProcessImageFileName(PEPROCESS process);
char target_process_name[] = "oxygen.exe";
typedef NTSTATUS(*fn_ObReferenceObjectByHandleWithTag)(
HANDLE Handle,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
ULONG Tag,
PVOID* Object,
POBJECT_HANDLE_INFORMATION HandleInformation
);
fn_ObReferenceObjectByHandleWithTag g_OriginalObReferenceObjectByHandleWithTag = NULL;
// PTE Hook Framework
#define MAX_G_BIT_RECORDS 128
#define MAX_HOOK_COUNT 64
#define PAGE_ALIGN(va) ((PVOID)((ULONG_PTR)(va) & ~0xFFF))
#define PDPTE_PS_BIT (1 << 7)
#define PDE_PS_BIT (1 << 7)
#define PTE_NX_BIT (1ULL << 63)
#define CACHE_WB (6ULL << 3)
// 页表结构定义
typedef struct _PAGE_TABLE {
UINT64 LineAddress;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 pat : 1;
UINT64 global : 1;
UINT64 ignored_1 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_2 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*PteAddress;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 large_page : 1;
UINT64 global : 1;
UINT64 ignored_2 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_3 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*PdeAddress;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 ignored_1 : 1;
UINT64 page_size : 1;
UINT64 ignored_2 : 4;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_3 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*PdpteAddress;
UINT64* Pml4Address;
BOOLEAN IsLargePage;
BOOLEAN Is1GBPage;
UINT64 OriginalPte;
UINT64 OriginalPde;
UINT64 OriginalPdpte;
UINT64 OriginalPml4e;
HANDLE ProcessId;
} PAGE_TABLE, * PPAGE_TABLE;
// G位信息记录结构体
typedef struct _G_BIT_INFO {
void* AlignAddress;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 large_page : 1;
UINT64 global : 1;
UINT64 ignored_2 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_3 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*PdeAddress;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 pat : 1;
UINT64 global : 1;
UINT64 ignored_1 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_2 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*PteAddress;
BOOLEAN IsLargePage;
} G_BIT_INFO, * PG_BIT_INFO;
typedef struct _HOOK_INFO {
void* OriginalAddress;
void* HookAddress;
UINT8 OriginalBytes[20];
UINT8 HookBytes[20];
UINT32 HookLength;
BOOLEAN IsHooked;
HANDLE ProcessId;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 pat : 1;
UINT64 global : 1;
UINT64 ignored_1 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_2 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*HookedPte;
union {
struct {
UINT64 present : 1;
UINT64 write : 1;
UINT64 user : 1;
UINT64 write_through : 1;
UINT64 cache_disable : 1;
UINT64 accessed : 1;
UINT64 dirty : 1;
UINT64 large_page : 1;
UINT64 global : 1;
UINT64 ignored_2 : 3;
UINT64 page_frame_number : 36;
UINT64 reserved_1 : 4;
UINT64 ignored_3 : 7;
UINT64 protection_key : 4;
UINT64 execute_disable : 1;
} flags;
UINT64 value;
}*HookedPde;
} HOOK_INFO;
class PteHookManager {
public:
bool fn_pte_inline_hook_bp_pg(HANDLE process_id, _Inout_ void** ori_addr, void* hk_addr);
bool fn_remove_hook(HANDLE process_id, void* hook_addr);
static PteHookManager* GetInstance();
HOOK_INFO* GetHookInfo() { return m_HookInfo; }
char* GetTrampLinePool() { return m_TrampLinePool; }
UINT32 GetHookCount() { return m_HookCount; }
bool fn_resume_global_bits(void* align_addr);
~PteHookManager(); // 添加析构函数声明
bool fn_modify_pte_permission(HANDLE process_id, void* addr, bool make_writable);
UINT64 get_process_cr3(PEPROCESS process);
private:
bool WriteTrampolineInstruction(void* trampoline, const JMP_ABS& jmpCmd);
void fn_add_g_bit_info(void* align_addr, void* pde_address, void* pte_address);
bool fn_isolation_pagetable(UINT64 cr3_val, void* replace_align_addr, void* split_pde);
bool fn_isolation_pages(HANDLE process_id, void* ori_addr);
bool fn_split_large_pages(void* in_pde, void* out_pde);
NTSTATUS get_page_table(UINT64 cr3, PAGE_TABLE& table);
void* fn_pa_to_va(UINT64 pa);
UINT64 fn_va_to_pa(void* va);
__forceinline KIRQL DisableWriteProtection();
__forceinline void EnableWriteProtection(KIRQL oldIrql);
void logger(const char* info, bool is_err, LONG err_code = 0);
void PrintPageTableInfo(const PAGE_TABLE& table);
void PrintHookInfo(const HOOK_INFO& hookInfo);
void PrintGBitInfo(const G_BIT_INFO& gbitInfo);
UINT64 m_OriginalPermissions;
struct MdlEntry {
PVOID va;
PMDL mdl;
};
static constexpr UINT32 MAX_MDL_CACHE = 16; // 添加常量定义
MdlEntry m_MdlCache[MAX_MDL_CACHE]; // MDL 缓存数组
UINT32 m_MdlCount = 0; // 当前缓存数量
// 添加 fn_unmap_pa 声明
void fn_unmap_pa(PVOID va);
static constexpr SIZE_T MAX_HOOKS = 256; // 根据需求调整
G_BIT_INFO m_GbitRecords[MAX_G_BIT_RECORDS];
UINT32 m_GbitCount = 0;
void* m_PteBase = 0;
HOOK_INFO m_HookInfo[MAX_HOOK_COUNT] = { 0 };
DWORD m_HookCount = 0;
char* m_TrampLinePool = nullptr; // 合并为一个声明
UINT32 m_PoolUsed = 0;
static PteHookManager* m_Instance;
};
PteHookManager* PteHookManager::m_Instance = nullptr;
void PteHookManager::fn_unmap_pa(PVOID va) {
if (!va) return;
// 查找 MDL 映射
for (UINT32 i = 0; i < m_MdlCount; i++) {
if (m_MdlCache[i].va == va) {
MmUnmapLockedPages(va, m_MdlCache[i].mdl);
IoFreeMdl(m_MdlCache[i].mdl);
// 从缓存中移除
if (i < m_MdlCount - 1) {
RtlMoveMemory(&m_MdlCache[i], &m_MdlCache[i + 1],
(m_MdlCount - i - 1) * sizeof(MdlEntry));
}
m_MdlCount--;
return;
}
}
// 尝试释放 MmMapIoSpace 映射
PHYSICAL_ADDRESS physAddr = MmGetPhysicalAddress(va);
if (physAddr.QuadPart != 0) {
MmUnmapIoSpace(va, PAGE_SIZE);
}
}
UINT64 PteHookManager::get_process_cr3(PEPROCESS process) {
#if defined(_AMD64_)
// Windows 10/11 的CR3偏移通常是0x28
return *(UINT64*)((PUCHAR)process + 0x28);
#elif defined(_X86_)
return *(UINT64*)((PUCHAR)process + 0x18);
#endif
}
// 修改析构函数释放所有 MDL 资源
PteHookManager::~PteHookManager() {
// 清理 MDL 缓存
for (UINT32 i = 0; i < m_MdlCount; i++) {
if (m_MdlCache[i].va) {
MmUnmapLockedPages(m_MdlCache[i].va, m_MdlCache[i].mdl);
IoFreeMdl(m_MdlCache[i].mdl);
}
}
m_MdlCount = 0;
// 清理其他资源
if (m_TrampLinePool) {
MmFreeContiguousMemory(m_TrampLinePool);
m_TrampLinePool = nullptr;
}
}
// 实现部分
__forceinline KIRQL PteHookManager::DisableWriteProtection() {
KIRQL oldIrql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
__writecr0(cr0 & ~0x10000); // 清除CR0.WP位
_mm_mfence();
return oldIrql;
}
__forceinline void PteHookManager::EnableWriteProtection(KIRQL oldIrql) {
_mm_mfence();
UINT64 cr0 = __readcr0();
__writecr0(cr0 | 0x10000); // 设置CR0.WP位
KeLowerIrql(oldIrql);
}
void PteHookManager::logger(const char* info, bool is_err, LONG err_code) {
if (is_err) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] ERROR: %s (0x%X)\n", info, err_code);
}
else {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] INFO: %s\n", info);
}
}
void PteHookManager::PrintPageTableInfo(const PAGE_TABLE& table) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] Page Table Info for VA: 0x%p\n", (void*)table.LineAddress);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PML4E: 0x%llx (Address: 0x%p)\n", table.OriginalPml4e, table.Pml4Address);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PDPTE: 0x%llx (Address: 0x%p), Is1GBPage: %d\n",
table.OriginalPdpte, table.PdpteAddress, table.Is1GBPage);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PDE: 0x%llx (Address: 0x%p), IsLargePage: %d\n",
table.OriginalPde, table.PdeAddress, table.IsLargePage);
if (!table.IsLargePage && !table.Is1GBPage) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PTE: 0x%llx (Address: 0x%p)\n", table.OriginalPte, table.PteAddress);
}
}
void PteHookManager::PrintHookInfo(const HOOK_INFO& hookInfo) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] Hook Info:\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" Original Address: 0x%p\n", hookInfo.OriginalAddress);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" Hook Address: 0x%p\n", hookInfo.HookAddress);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" Hook Length: %d\n", hookInfo.HookLength);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" Is Hooked: %d\n", hookInfo.IsHooked);
// 打印原始字节
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, " Original Bytes: ");
for (UINT32 i = 0; i < sizeof(hookInfo.OriginalBytes); i++) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%02X ", hookInfo.OriginalBytes[i]);
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "\n");
// 打印Hook字节
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, " Hook Bytes: ");
for (UINT32 i = 0; i < sizeof(hookInfo.HookBytes); i++) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%02X ", hookInfo.HookBytes[i]);
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "\n");
}
void PteHookManager::PrintGBitInfo(const G_BIT_INFO& gbitInfo) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] G-Bit Info:\n");
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" Align Address: 0x%p\n", gbitInfo.AlignAddress);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" IsLargePage: %d\n", gbitInfo.IsLargePage);
if (gbitInfo.PdeAddress) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PDE: 0x%llx (Address: 0x%p)\n", gbitInfo.PdeAddress->value, gbitInfo.PdeAddress);
}
if (gbitInfo.PteAddress) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
" PTE: 0x%llx (Address: 0x%p)\n", gbitInfo.PteAddress->value, gbitInfo.PteAddress);
}
}
void* PteHookManager::fn_pa_to_va(UINT64 pa) {
PHYSICAL_ADDRESS physAddr;
physAddr.QuadPart = pa;
PVOID mappedVa = MmMapIoSpace(physAddr, PAGE_SIZE, MmNonCached);
if (mappedVa) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PA] MmMapIoSpace映射成功: PA=0x%llx -> VA=0x%p\n", pa, mappedVa);
return mappedVa;
}
// 3. 低4GB直接映射
if (physAddr.QuadPart < 0x100000000) {
PVOID directVa = (PVOID)(physAddr.QuadPart + DIRECT_MAPPING_BASE);
if (MmIsAddressValid(directVa)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PA] 低4GB直接映射成功: PA=0x%llx -> VA=0x%p\n", pa, directVa);
return directVa;
}
}
// 4. 使用MDL映射
PMDL pMdl = IoAllocateMdl(nullptr, PAGE_SIZE, FALSE, FALSE, NULL);
if (!pMdl) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PA] MDL分配失败: PA=0x%llx\n", pa);
return nullptr;
}
PVOID va = nullptr;
__try {
MmBuildMdlForNonPagedPool(pMdl);
MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
va = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority);
if (va) {
// 添加到MDL缓存
if (m_MdlCount < MAX_MDL_CACHE) {
m_MdlCache[m_MdlCount].va = va;
m_MdlCache[m_MdlCount].mdl = pMdl;
m_MdlCount++;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PA] MDL映射缓存成功: PA=0x%llx -> VA=0x%p (缓存索引: %d)\n",
pa, va, m_MdlCount - 1);
}
else {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL,
"[PA] MDL缓存已满,临时映射: PA=0x%llx -> VA=0x%p\n", pa, va);
return va; // 临时映射,调用者需负责释放
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PA] 物理地址转换异常: PA=0x%llx, 代码: 0x%X\n",
pa, GetExceptionCode());
IoFreeMdl(pMdl);
return nullptr;
}
if (!va) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PA] MDL映射失败: PA=0x%llx\n", pa);
IoFreeMdl(pMdl);
}
return va;
}
UINT64 PteHookManager::fn_va_to_pa(void* va) {
PHYSICAL_ADDRESS physAddr = MmGetPhysicalAddress(va);
return physAddr.QuadPart;
}
NTSTATUS PteHookManager::get_page_table(UINT64 cr3_val, PAGE_TABLE& table) {
UINT64 va = table.LineAddress;
UINT64 pml4e_index = (va >> 39) & 0x1FF;
UINT64 pdpte_index = (va >> 30) & 0x1FF;
UINT64 pde_index = (va >> 21) & 0x1FF;
UINT64 pte_index = (va >> 12) & 0x1FF;
// PML4
UINT64 pml4_pa = cr3_val & ~0xFFF;
UINT64* pml4_va = (UINT64*)fn_pa_to_va(pml4_pa);
if (!pml4_va) return STATUS_INVALID_ADDRESS;
table.Pml4Address = &pml4_va[pml4e_index];
table.OriginalPml4e = *table.Pml4Address;
if (!(table.OriginalPml4e & 1)) return STATUS_ACCESS_VIOLATION;
// PDPTE
UINT64 pdpte_pa = table.OriginalPml4e & ~0xFFF;
UINT64* pdpte_va = (UINT64*)fn_pa_to_va(pdpte_pa);
if (!pdpte_va) return STATUS_INVALID_ADDRESS;
table.PdpteAddress = (decltype(table.PdpteAddress))&pdpte_va[pdpte_index];
table.OriginalPdpte = table.PdpteAddress->value;
table.Is1GBPage = (table.OriginalPdpte & PDPTE_1GB_PAGE_FLAG) ? TRUE : FALSE;
if (!(table.OriginalPdpte & 1)) return STATUS_ACCESS_VIOLATION;
if (table.Is1GBPage) return STATUS_SUCCESS;
// PDE
UINT64 pde_pa = table.OriginalPdpte & ~0xFFF;
UINT64* pde_va = (UINT64*)fn_pa_to_va(pde_pa);
if (!pde_va) return STATUS_INVALID_ADDRESS;
table.PdeAddress = (decltype(table.PdeAddress))&pde_va[pde_index];
table.OriginalPde = table.PdeAddress->value;
table.IsLargePage = (table.OriginalPde & PDE_2MB_PAGE_FLAG) ? TRUE : FALSE;
if (!(table.OriginalPde & 1)) return STATUS_ACCESS_VIOLATION;
if (table.IsLargePage) return STATUS_SUCCESS;
// PTE
UINT64 pte_pa = table.OriginalPde & ~0xFFF;
UINT64* pte_va = (UINT64*)fn_pa_to_va(pte_pa);
if (!pte_va) return STATUS_INVALID_ADDRESS;
table.PteAddress = (decltype(table.PteAddress))&pte_va[pte_index];
table.OriginalPte = table.PteAddress->value;
if (!(table.OriginalPte & 1)) return STATUS_ACCESS_VIOLATION;
// 打印页表信息
PrintPageTableInfo(table);
return STATUS_SUCCESS;
}
bool PteHookManager::fn_split_large_pages(void* in_pde_ptr, void* out_pde_ptr) {
auto in_pde = (decltype(PAGE_TABLE::PdeAddress))in_pde_ptr;
auto out_pde = (decltype(PAGE_TABLE::PdeAddress))out_pde_ptr;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 正在拆分大页: 输入PDE=0x%llx, 输出PDE=0x%p\n",
in_pde->value, out_pde);
PHYSICAL_ADDRESS LowAddr = { 0 }, HighAddr = { 0 };
HighAddr.QuadPart = MAXULONG64;
auto pt = (decltype(PAGE_TABLE::PteAddress))MmAllocateContiguousMemorySpecifyCache(
PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmNonCached);
if (!pt) {
logger("分配连续内存失败 (用于拆分大页)", true);
return false;
}
UINT64 start_pfn = in_pde->flags.page_frame_number;
for (int i = 0; i < 512; i++) {
pt[i].value = 0;
pt[i].flags.present = 1;
pt[i].flags.write = in_pde->flags.write;
pt[i].flags.user = in_pde->flags.user;
pt[i].flags.write_through = in_pde->flags.write_through;
pt[i].flags.cache_disable = in_pde->flags.cache_disable;
pt[i].flags.accessed = in_pde->flags.accessed;
pt[i].flags.dirty = in_pde->flags.dirty;
pt[i].flags.global = 0;
pt[i].flags.page_frame_number = start_pfn + i;
}
out_pde->value = in_pde->value;
out_pde->flags.large_page = 0;
out_pde->flags.page_frame_number = fn_va_to_pa(pt) >> 12;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 大页拆分完成: 新PTE表物理地址=0x%llx\n", fn_va_to_pa(pt));
return true;
}
bool PteHookManager::fn_isolation_pagetable(UINT64 cr3_val, void* replace_align_addr, void* split_pde_ptr) {
PHYSICAL_ADDRESS LowAddr = { 0 }, HighAddr = { 0 };
HighAddr.QuadPart = MAXULONG64;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 开始隔离页表: CR3=0x%llx, 地址=0x%p\n",
cr3_val, replace_align_addr);
// 分配连续内存用于新页表
auto Va4kb = (UINT64*)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmNonCached);
auto VaPt = (UINT64*)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmNonCached);
auto VaPdt = (UINT64*)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmNonCached);
auto VaPdpt = (UINT64*)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmNonCached);
if (!VaPt || !Va4kb || !VaPdt || !VaPdpt) {
if (VaPt) MmFreeContiguousMemory(VaPt);
if (Va4kb) MmFreeContiguousMemory(Va4kb);
if (VaPdt) MmFreeContiguousMemory(VaPdt);
if (VaPdpt) MmFreeContiguousMemory(VaPdpt);
logger("分配连续内存失败 (用于隔离页表)", true);
return false;
}
// 获取原始页表信息(只保存值)
PAGE_TABLE Table = { 0 };
Table.LineAddress = (UINT64)replace_align_addr;
NTSTATUS status = get_page_table(cr3_val, Table);
if (!NT_SUCCESS(status)) {
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
logger("获取页表信息失败", true, status);
return false;
}
UINT64 pte_index = (Table.LineAddress >> 12) & 0x1FF;
UINT64 pde_index = (Table.LineAddress >> 21) & 0x1FF;
UINT64 pdpte_index = (Table.LineAddress >> 30) & 0x1FF;
UINT64 pml4e_index = (Table.LineAddress >> 39) & 0x1FF;
// 复制原始页面内容
memcpy(Va4kb, replace_align_addr, PAGE_SIZE);
// 物理地址转虚拟地址的辅助函数(增强版)
auto get_va_from_pfn = [this](UINT64 pfn) -> void* {
if (pfn == 0) return nullptr;
PHYSICAL_ADDRESS physAddr;
physAddr.QuadPart = pfn << 12;
// 优先使用 MmMapIoSpace
PVOID mappedVa = MmMapIoSpace(physAddr, PAGE_SIZE, MmNonCached);
if (mappedVa) {
return mappedVa;
}
// 低4GB直接映射
if (physAddr.QuadPart < 0x100000000) {
return (PVOID)(physAddr.QuadPart + 0xFFFF000000000000);
}
// 回退到MDL方式
PMDL pMdl = IoAllocateMdl(nullptr, PAGE_SIZE, FALSE, FALSE, NULL);
if (!pMdl) return nullptr;
MmBuildMdlForNonPagedPool(pMdl);
PVOID va = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);
if (va) {
// 添加到MDL缓存
if (m_MdlCount < MAX_MDL_CACHE) {
m_MdlCache[m_MdlCount++] = { va, pMdl };
}
return va;
}
IoFreeMdl(pMdl);
return nullptr;
};
// 安全获取PT源地址
void* pt_source_va = nullptr;
if (Table.IsLargePage && split_pde_ptr) {
auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr;
pt_source_va = get_va_from_pfn(split_pde->flags.page_frame_number);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 大页模式: 源PFN=0x%llx, 源VA=%p\n",
split_pde->flags.page_frame_number, pt_source_va);
}
else {
UINT64 pt_pfn = (Table.OriginalPde & ~0xFFF) >> 12;
pt_source_va = get_va_from_pfn(pt_pfn);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 常规模式: 源PFN=0x%llx, 源VA=%p\n",
pt_pfn, pt_source_va);
}
if (!pt_source_va) {
logger("无法获取PT源虚拟地址", true);
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
return false;
}
// 复制PT数据(带异常处理)
__try {
memcpy(VaPt, pt_source_va, PAGE_SIZE);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
logger("复制PT数据时发生异常", true, GetExceptionCode());
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
fn_unmap_pa(pt_source_va);
return false;
}
fn_unmap_pa(pt_source_va); // 释放映射
// 安全获取PDT源地址
UINT64 pdt_pfn = (Table.OriginalPdpte & ~0xFFF) >> 12;
void* pdt_source_va = get_va_from_pfn(pdt_pfn);
if (!pdt_source_va) {
logger("无法获取PDT源虚拟地址", true);
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
return false;
}
__try {
memcpy(VaPdt, pdt_source_va, PAGE_SIZE);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
logger("复制PDT数据时发生异常", true, GetExceptionCode());
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
fn_unmap_pa(pdt_source_va);
return false;
}
fn_unmap_pa(pdt_source_va);
// 安全获取PDPT源地址
UINT64 pdpt_pfn = (Table.OriginalPml4e & ~0xFFF) >> 12;
void* pdpt_source_va = get_va_from_pfn(pdpt_pfn);
if (!pdpt_source_va) {
logger("无法获取PDPT源虚拟地址", true);
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
return false;
}
__try {
memcpy(VaPdpt, pdpt_source_va, PAGE_SIZE);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
logger("复制PDPT数据时发生异常", true, GetExceptionCode());
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
fn_unmap_pa(pdpt_source_va);
return false;
}
fn_unmap_pa(pdpt_source_va);
// 设置新PTE
auto new_pte = (decltype(PAGE_TABLE::PteAddress))VaPt;
new_pte[pte_index].flags.page_frame_number = fn_va_to_pa(Va4kb) >> 12;
// 设置新PDE
auto new_pde = (decltype(PAGE_TABLE::PdeAddress))VaPdt;
new_pde[pde_index].value = Table.OriginalPde;
new_pde[pde_index].flags.large_page = 0;
new_pde[pde_index].flags.page_frame_number = fn_va_to_pa(VaPt) >> 12;
// 设置新PDPTE
auto new_pdpte = (decltype(PAGE_TABLE::PdpteAddress))VaPdpt;
new_pdpte[pdpte_index].flags.page_frame_number = fn_va_to_pa(VaPdt) >> 12;
// 设置新PML4E(安全方式)
PHYSICAL_ADDRESS pml4_phys;
pml4_phys.QuadPart = cr3_val & ~0xFFF;
UINT64* new_pml4 = (UINT64*)fn_pa_to_va(pml4_phys.QuadPart);
if (!new_pml4) {
logger("无法获取PML4虚拟地址", true);
MmFreeContiguousMemory(VaPt);
MmFreeContiguousMemory(Va4kb);
MmFreeContiguousMemory(VaPdt);
MmFreeContiguousMemory(VaPdpt);
return false;
}
// 保存原始PML4E值
UINT64 original_pml4e = new_pml4[pml4e_index];
UINT64 new_pml4e = (original_pml4e & 0xFFF) | (fn_va_to_pa(VaPdpt) & ~0xFFF);
// 原子更新PML4E
KIRQL oldIrql = DisableWriteProtection();
new_pml4[pml4e_index] = new_pml4e;
EnableWriteProtection(oldIrql);
// 刷新TLB (多核安全)
KeIpiGenericCall([](ULONG_PTR Context) -> ULONG_PTR {
__invlpg((void*)Context);
return 0;
}, (ULONG_PTR)replace_align_addr);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 页表隔离完成: 新PFN=0x%llx\n", fn_va_to_pa(Va4kb) >> 12);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] PML4E更新: 0x%llx -> 0x%llx\n", original_pml4e, new_pml4e);
return true;
}
bool PteHookManager::fn_isolation_pages(HANDLE process_id, void* ori_addr) {
PEPROCESS Process;
NTSTATUS status = PsLookupProcessByProcessId(process_id, &Process);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[ISOL] 查找进程失败: PID=%d\n", HandleToULong(process_id));
return false;
}
KAPC_STATE ApcState;
KeStackAttachProcess(Process, &ApcState);
void* AlignAddr = PAGE_ALIGN(ori_addr);
PAGE_TABLE Table = { 0 };
Table.LineAddress = (UINT64)AlignAddr;
// 获取目标进程CR3
UINT64 target_cr3 = get_process_cr3(Process);
if (target_cr3 == 0) {
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
return false;
}
// 获取页表项
status = get_page_table(target_cr3, Table);
if (!NT_SUCCESS(status)) {
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[ISOL] 获取页表失败: VA=0x%p\n", AlignAddr);
return false;
}
// 检查是否已隔离(G位为0)
UINT64* pteEntry = nullptr;
UINT64 globalFlag = 0;
if (Table.PteAddress) {
pteEntry = &Table.PteAddress->value;
globalFlag = PTE_GLOBAL_FLAG;
}
else if (Table.PdeAddress && Table.IsLargePage) {
pteEntry = &Table.PdeAddress->value;
globalFlag = PDE_GLOBAL_FLAG;
}
else if (Table.PdpteAddress && Table.Is1GBPage) {
pteEntry = &Table.PdpteAddress->value;
globalFlag = PDPTE_GLOBAL_FLAG;
}
else {
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[ISOL] 无法确定页表级别\n");
return false;
}
UINT64 currentValue = *pteEntry;
if ((currentValue & globalFlag) == 0) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[ISOL] 页面已隔离: VA=0x%p\n", AlignAddr);
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
return true;
}
// 清除G位(Global标志)
UINT64 newValue = currentValue & ~globalFlag;
InterlockedExchange64((LONG64*)pteEntry, newValue);
// 刷新TLB
__invlpg(AlignAddr);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[ISOL] 页面隔离成功: VA=0x%p, 原始值=0x%llx, 新值=0x%llx\n",
AlignAddr, currentValue, newValue);
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
return true;
}
bool PteHookManager::WriteTrampolineInstruction(void* trampoline, const JMP_ABS& jmpCmd)
{
if (!MmIsAddressValid(trampoline)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 错误: 内存地址无效 (VA=%p)\n", trampoline);
return false;
}
PHYSICAL_ADDRESS physAddr = MmGetPhysicalAddress(trampoline);
if (physAddr.QuadPart == 0) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 错误: 无法获取物理地址 (VA=%p)\n", trampoline);
return false;
}
KIRQL oldIrql = KeRaiseIrqlToDpcLevel();
BOOLEAN wpEnabled = (__readcr0() & CR0_WP);
if (wpEnabled) {
__writecr0(__readcr0() & ~CR0_WP);
_mm_mfence();
}
PMDL pMdl = IoAllocateMdl(trampoline, sizeof(JMP_ABS), FALSE, FALSE, NULL);
if (!pMdl) {
if (wpEnabled) __writecr0(__readcr0() | CR0_WP);
KeLowerIrql(oldIrql);
return false;
}
NTSTATUS status = STATUS_SUCCESS;
__try {
MmBuildMdlForNonPagedPool(pMdl);
MmProtectMdlSystemAddress(pMdl, PAGE_READWRITE);
// 正确写入 FF25 00000000 和 8字节地址
memcpy(trampoline, jmpCmd.opcode, 6); // FF25 00000000
*(ULONG64*)((BYTE*)trampoline + 6) = jmpCmd.address; // 地址写入 RIP+0 的位置
_mm_sfence();
_mm_clflush(trampoline);
_mm_clflush((BYTE*)trampoline + 8);
__invlpg(trampoline);
_mm_mfence();
}
__except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 异常: 写入跳板失败 (代码: 0x%X)\n", status);
}
IoFreeMdl(pMdl);
if (wpEnabled) {
__writecr0(__readcr0() | CR0_WP);
_mm_mfence();
}
KeLowerIrql(oldIrql);
if (!NT_SUCCESS(status)) return false;
// 验证写入结果
if (*(USHORT*)trampoline != 0x25FF ||
*(ULONG64*)((BYTE*)trampoline + 6) != jmpCmd.address)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 验证失败: 跳板内容不匹配\n"
" 预期: FF25 [%p]\n"
" 实际: %02X%02X %02X%02X%02X%02X [%p]\n",
jmpCmd.address,
((BYTE*)trampoline)[0], ((BYTE*)trampoline)[1],
((BYTE*)trampoline)[2], ((BYTE*)trampoline)[3],
((BYTE*)trampoline)[4], ((BYTE*)trampoline)[5],
*(ULONG64*)((BYTE*)trampoline + 6));
return false;
}
return true;
}
bool PteHookManager::fn_pte_inline_hook_bp_pg(HANDLE process_id, _Inout_ void** ori_addr, void* hk_addr) {
// [1] 页表隔离
if (!fn_isolation_pages(process_id, *ori_addr)) {
return false;
}
// [2] 修改PTE权限为可写
if (!fn_modify_pte_permission(process_id, *ori_addr, true)) {
return false;
}
// [3] 获取目标进程上下文
PEPROCESS targetProcess;
if (!NT_SUCCESS(PsLookupProcessByProcessId(process_id, &targetProcess))) {
return false;
}
KAPC_STATE apcState;
KeStackAttachProcess(targetProcess, &apcState);
// [4] 构造跳转指令
JMP_ABS jmpCmd = {};
memcpy(jmpCmd.opcode, "\xFF\x25\x00\x00\x00\x00", 6); // FF25 00000000
jmpCmd.address = reinterpret_cast<ULONG64>(hk_addr);
// [5] 直接写入被隔离页
void* targetFunc = *ori_addr;
bool success = false;
// 禁用写保护
KIRQL oldIrql = DisableWriteProtection();
__try {
// 保存原始指令 (用于卸载)
RtlCopyMemory(m_HookInfo[m_HookCount].OriginalBytes, targetFunc, sizeof(jmpCmd));
// 写入跳转指令到隔离页
memcpy(targetFunc, &jmpCmd, 6);
*(ULONG64*)((BYTE*)targetFunc + 6) = jmpCmd.address;
// 刷新缓存
_mm_sfence();
_mm_clflush(targetFunc);
__invlpg(targetFunc);
_mm_mfence();
success = true;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 直接写入隔离页成功: VA=%p -> Hook=%p\n",
targetFunc, hk_addr);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 写入隔离页异常: 0x%X\n", GetExceptionCode());
}
// 恢复写保护
EnableWriteProtection(oldIrql);
// [6] 恢复原始权限
fn_modify_pte_permission(process_id, *ori_addr, false);
// [7] 记录Hook信息
if (success) {
m_HookInfo[m_HookCount].OriginalAddress = targetFunc;
m_HookInfo[m_HookCount].HookAddress = hk_addr;
m_HookInfo[m_HookCount].ProcessId = process_id;
m_HookInfo[m_HookCount].IsHooked = TRUE;
m_HookCount++;
}
// [8] 清理
KeUnstackDetachProcess(&apcState);
ObDereferenceObject(targetProcess);
return success;
}
bool PteHookManager::fn_modify_pte_permission(HANDLE process_id, void* addr, bool make_writable) {
PEPROCESS Process;
NTSTATUS status = PsLookupProcessByProcessId(process_id, &Process);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PERM] 查找进程失败: PID=%d\n", HandleToULong(process_id));
return false;
}
KAPC_STATE ApcState;
KeStackAttachProcess(Process, &ApcState);
void* AlignAddr = PAGE_ALIGN(addr);
PAGE_TABLE Table = { 0 };
Table.LineAddress = (UINT64)AlignAddr;
// 获取目标进程CR3
UINT64 target_cr3 = get_process_cr3(Process);
if (target_cr3 == 0) {
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
return false;
}
// 获取页表项
status = get_page_table(target_cr3, Table);
if (!NT_SUCCESS(status) || !Table.PteAddress) {
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[PERM] 获取页表失败: VA=0x%p\n", AlignAddr);
return false;
}
UINT64 pteValue = Table.PteAddress->value;
UINT64 newPte;
UINT64 permMask = PTE_WRITABLE_FLAG | PTE_NOEXECUTE_FLAG;
if (make_writable) {
// 保存原始权限
m_OriginalPermissions = pteValue & permMask;
// 设置可写位并清除NX位
newPte = (pteValue & ~permMask) | PTE_WRITABLE_FLAG;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PERM] 修改权限为可写: VA=0x%p, 原始PTE=0x%llx, 新PTE=0x%llx\n",
addr, pteValue, newPte);
}
else {
// 恢复原始权限
newPte = (pteValue & ~permMask) | (m_OriginalPermissions & permMask);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PERM] 恢复原始权限: VA=0x%p, 原始PTE=0x%llx, 新PTE=0x%llx\n",
addr, pteValue, newPte);
}
// 原子修改PTE
InterlockedExchange64((LONG64*)&Table.PteAddress->value, newPte);
// 刷新TLB
__invlpg(addr);
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(Process);
return true;
}
bool PteHookManager::fn_remove_hook(HANDLE process_id, void* hook_addr) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 尝试移除Hook: Hook地址=0x%p\n", hook_addr);
for (UINT32 i = 0; i < m_HookCount; i++) {
if (m_HookInfo[i].HookAddress == hook_addr && m_HookInfo[i].IsHooked) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 找到匹配的Hook: 原始地址=0x%p\n", m_HookInfo[i].OriginalAddress);
KIRQL oldIrql = DisableWriteProtection();
memcpy(m_HookInfo[i].OriginalAddress, m_HookInfo[i].OriginalBytes,
sizeof(m_HookInfo[i].OriginalBytes));
EnableWriteProtection(oldIrql);
m_HookInfo[i].IsHooked = FALSE;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] Hook已成功移除\n");
return true;
}
}
logger("未找到匹配的Hook", true);
return false;
}
void PteHookManager::fn_add_g_bit_info(void* align_addr, void* pde_address, void* pte_address) {
if (m_GbitCount >= MAX_G_BIT_RECORDS) {
logger("达到最大G位记录数量限制", true);
return;
}
PG_BIT_INFO record = &m_GbitRecords[m_GbitCount++];
record->AlignAddress = align_addr;
record->PdeAddress = (decltype(G_BIT_INFO::PdeAddress))pde_address;
record->PteAddress = (decltype(G_BIT_INFO::PteAddress))pte_address;
record->IsLargePage = (pde_address && ((decltype(PAGE_TABLE::PdeAddress))pde_address)->flags.large_page);
// 打印G位信息
PrintGBitInfo(*record);
}
bool PteHookManager::fn_resume_global_bits(void* align_addr) {
KIRQL oldIrql = DisableWriteProtection();
bool found = false;
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] 开始恢复G位: 对齐地址=0x%p\n", align_addr);
for (UINT32 i = 0; i < m_GbitCount; i++) {
PG_BIT_INFO record = &m_GbitRecords[i];
if (align_addr && record->AlignAddress != align_addr) continue;
if (record->PteAddress) {
record->PteAddress->flags.global = 1;
__invlpg(record->AlignAddress);
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_INFO_LEVEL,
" 恢复PTE G位: PTE=0x%llx, 地址=0x%p\n",
record->PteAddress->value, record->AlignAddress);
}
if (record->PdeAddress) {
record->PdeAddress->flags.global = 1;
if (record->IsLargePage) {
__invlpg(record->AlignAddress);
}
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_INFO_LEVEL,
" 恢复PDE G位: PDE=0x%llx, 地址=0x%p, 大页=%d\n",
record->PdeAddress->value, record->AlignAddress, record->IsLargePage);
}
found = true;
if (align_addr) break;
}
EnableWriteProtection(oldIrql);
if (found) {
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] G位恢复完成\n");
}
else {
logger("未找到匹配的G位记录", true);
}
return found;
}
PteHookManager* PteHookManager::GetInstance() {
if (!m_Instance) {
m_Instance = static_cast<PteHookManager*>(
ExAllocatePoolWithTag(NonPagedPool, sizeof(PteHookManager), 'tpHk'));
if (m_Instance) {
RtlZeroMemory(m_Instance, sizeof(PteHookManager));
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_INFO_LEVEL,
"[PTE_HOOK] PTE Hook管理器实例已创建: 地址=0x%p\n", m_Instance);
}
else {
DbgPrintEx(DPFLTR_ERROR_LEVEL, DPFLTR_ERROR_LEVEL,
"[PTE_HOOK] 创建PTE Hook管理器实例失败\n");
}
}
return m_Instance;
}
// 全局PTE Hook管理器实例
PteHookManager* g_PteHookManager = nullptr;
// 辅助函数:检查是否为目标进程
BOOLEAN IsTargetProcess(CHAR* imageName) {
CHAR currentName[16];
// 复制到本地缓冲区并确保 NULL 终止
RtlCopyMemory(currentName, imageName, 16);
currentName[15] = '\0'; // 确保终止
// 修剪尾部空格
for (int i = 15; i >= 0; i--) {
if (currentName[i] == ' ') currentName[i] = '\0';
else if (currentName[i] != '\0') break;
}
return (strcmp(currentName, target_process_name) == 0);
}
// Hook 函数
NTSTATUS MyObReferenceObjectByHandleWithTag(
HANDLE Handle,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
ULONG Tag,
PVOID* Object,
POBJECT_HANDLE_INFORMATION HandleInformation
) {
PEPROCESS currentProcess = PsGetCurrentProcess();
CHAR* imageName = PsGetProcessImageFileName(currentProcess);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[!] [HookFunction] 进入 Hook 函数! 当前进程: %s\n", imageName);
__debugbreak(); // 强制中断,确认是否执行到这里
if (IsTargetProcess(imageName)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[!] [HookFunction] 拒绝访问目标进程 PID=%d\n", HandleToULong(PsGetCurrentProcessId()));
return STATUS_ACCESS_DENIED;
}
return g_OriginalObReferenceObjectByHandleWithTag(
Handle,
DesiredAccess,
ObjectType,
AccessMode,
Tag,
Object,
HandleInformation
);
}
NTSTATUS InstallHook() {
UNICODE_STRING funcName;
RtlInitUnicodeString(&funcName, L"ObReferenceObjectByHandleWithTag");
g_OriginalObReferenceObjectByHandleWithTag = (fn_ObReferenceObjectByHandleWithTag)MmGetSystemRoutineAddress(&funcName);
if (!g_OriginalObReferenceObjectByHandleWithTag) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[-] [InstallHook] 找不到 ObReferenceObjectByHandleWithTag\n");
return STATUS_NOT_FOUND;
}
__debugbreak();
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[+] [InstallHook] 找到目标函数地址: %p\n", g_OriginalObReferenceObjectByHandleWithTag);
void* targetFunc = (void*)g_OriginalObReferenceObjectByHandleWithTag;
void* hookFunc = (void*)MyObReferenceObjectByHandleWithTag;
if (!g_PteHookManager->fn_pte_inline_hook_bp_pg(targetProcessId, &targetFunc, hookFunc)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[-] [InstallHook] PTE Hook 安装失败\n");
return STATUS_UNSUCCESSFUL;
}
g_OriginalObReferenceObjectByHandleWithTag = (fn_ObReferenceObjectByHandleWithTag)targetFunc;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[+] [InstallHook] Hook 成功安装. 跳板地址: %p\n", targetFunc);
__debugbreak(); // 强制中断,验证是否执行到这里
return STATUS_SUCCESS;
}
// 移除 Hook
VOID RemoveHook() {
if (g_OriginalObReferenceObjectByHandleWithTag && g_PteHookManager) {
g_PteHookManager->fn_remove_hook(PsGetCurrentProcessId(), (void*)MyObReferenceObjectByHandleWithTag);
}
}
// 工作线程函数
VOID InstallHookWorker(PVOID Context) {
targetProcessId = (HANDLE)Context;
DbgPrint("[+] Worker thread started for hook installation on PID: %d\n", HandleToULong(targetProcessId));
InstallHook();
PsTerminateSystemThread(STATUS_SUCCESS);
}
// 进程创建回调
VOID ProcessNotifyCallback(
_In_ HANDLE ParentId,
_In_ HANDLE ProcessId,
_In_ BOOLEAN Create
) {
UNREFERENCED_PARAMETER(ParentId);
if (Create) {
PEPROCESS process = NULL;
if (NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &process))) {
CHAR* imageName = PsGetProcessImageFileName(process);
CHAR currentName[16];
RtlCopyMemory(currentName, imageName, 16);
currentName[15] = '\0';
for (int i = 15; i >= 0; i--) {
if (currentName[i] == ' ') currentName[i] = '\0';
else if (currentName[i] != '\0') break;
}
if (strcmp(currentName, target_process_name) == 0) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[+] [ProcessNotifyCallback] 目标进程 %s 创建 (PID: %d)\n", currentName, HandleToULong(ProcessId));
HANDLE threadHandle;
NTSTATUS status = PsCreateSystemThread(
&threadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
InstallHookWorker,
(PVOID)ProcessId // 关键:传递目标进程ID
);
if (NT_SUCCESS(status)) {
ZwClose(threadHandle);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"[+] [ProcessNotifyCallback] 工作线程已创建\n");
}
else {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[-] [ProcessNotifyCallback] 创建线程失败: 0x%X\n", status);
}
}
ObDereferenceObject(process);
}
}
}
// 驱动卸载函数
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
DbgPrint("[+] Driver unloading...\n");
// 移除进程通知回调
PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)ProcessNotifyCallback, TRUE);
// 移除Hook
RemoveHook();
// 清理PTE Hook资源
if (g_PteHookManager) {
DbgPrint("[PTE_HOOK] Cleaning up PTE...\n");
// 恢复所有被修改的G位
g_PteHookManager->fn_resume_global_bits(nullptr);
// 移除所有活动的Hook
HOOK_INFO* hookInfo = g_PteHookManager->GetHookInfo();
UINT32 hookCount = g_PteHookManager->GetHookCount();
for (UINT32 i = 0; i < hookCount; i++) {
if (hookInfo[i].IsHooked) {
g_PteHookManager->fn_remove_hook(PsGetCurrentProcessId(), hookInfo[i].HookAddress);
}
}
// 释放跳板池内存
char* trampLinePool = g_PteHookManager->GetTrampLinePool();
if (trampLinePool) {
ExFreePoolWithTag(trampLinePool, 'JmpP');
}
// 释放管理器实例
ExFreePoolWithTag(g_PteHookManager, 'tpHk');
g_PteHookManager = nullptr;
}
DbgPrint("[+] Driver unloaded successfully\n");
}
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[+] [DriverEntry] 驱动加载开始\n");
DriverObject->DriverUnload = DriverUnload;
g_PteHookManager = PteHookManager::GetInstance();
if (!g_PteHookManager) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] [DriverEntry] 初始化 PteHookManager 失败\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS status = PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)ProcessNotifyCallback, FALSE);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
"[-] [DriverEntry] 注册进程通知失败 (0x%X)\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[+] [DriverEntry] 驱动加载成功\n");
return STATUS_SUCCESS;
}