活动介绍

kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF kd> ed nt!Kd_IHVDRIVER_Mask 0xFFFFFFFF kd> g [+] [DriverEntry] 驱动加载开始 [+] [DriverEntry] 驱动加载成功 [+] [ProcessNotifyCallback] 目标进程 oxygen.exe 创建 (PID: 8052) [+] [ProcessNotifyCallback] 工作线程已创建 [+] Worker thread started for hook installation on PID: 8052 Break instruction exception - code 80000003 (first chance) obpcallback!InstallHook+0x50: fffff803`0e2a12f0 cc int 3 kd> g [+] [InstallHook] 找到目标函数地址: FFFFF803062EFB60 [PTE_HOOK] 开始隔离页面: PID=8052, 地址=0xFFFFF803062EFB60 [PTE_HOOK] 正在拆分大页: 输入PDE=0xa00000002a001a1, 输出PDE=0xFFFFBB878EFA3F80 [PTE_HOOK] 大页拆分完成: 新PTE表物理地址=0x239dab000 [PTE_HOOK] G-Bit Info: Align Address: 0xFFFFF803062EF000 IsLargePage: 1 PDE: 0xa00000002a000a1 (Address: 0xFFFFFE7F3E00C188) [PTE_HOOK] 清除大页G位: PDE=0xa00000002a000a1 [PTE_HOOK] 开始隔离页表: CR3=0x12e16c000, 地址=0xFFFFF803062EF000 KDTARGET: Refreshing KD connection *** Fatal System Error: 0x0000007e (0xFFFFFFFFC0000005,0xFFFFF8030E2A2265,0xFFFF80031C95B638,0xFFFF80031C95AE70) 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: fffff803`05ffd0b0 cc int 3 kd> !analyze -v Connected to Windows 10 19041 x64 target at (Wed Jul 9 20:20:01.053 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`00259018). Type ".hh dbgerr001" for details Loading unloaded module list ...... ERROR: FindPlugIns 8007007b ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common BugCheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: ffffffffc0000005, The exception code that was not handled Arg2: fffff8030e2a2265, The address that the exception occurred at Arg3: ffff80031c95b638, Exception Record Address Arg4: ffff80031c95ae70, Context Record Address 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`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details PEB is paged out (Peb.Ldr = 00000000`00259018). Type ".hh dbgerr001" for details KEY_VALUES_STRING: 1 Key : AV.Type Value: Read Key : Analysis.CPU.mSec Value: 4234 Key : Analysis.Elapsed.mSec Value: 39170 Key : Analysis.IO.Other.Mb Value: 0 Key : Analysis.IO.Read.Mb Value: 2 Key : Analysis.IO.Write.Mb Value: 0 Key : Analysis.Init.CPU.mSec Value: 3250 Key : Analysis.Init.Elapsed.mSec Value: 59417 Key : Analysis.Memory.CommitPeak.Mb Value: 72 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: 0x7e Key : Bugcheck.Code.LegacyAPI Value: 0x7e Key : Bugcheck.Code.TargetModel Value: 0x7e Key : Failure.Bucket Value: AV_obpcallback!PteHookManager::fn_isolation_pagetable Key : Failure.Exception.Code Value: 0xc0000005 Key : Failure.Exception.IP.Address Value: 0xfffff8030e2a2265 Key : Failure.Exception.IP.Module Value: obpcallback Key : Failure.Exception.IP.Offset Value: 0x2265 Key : Failure.Exception.Record Value: 0xffff80031c95b638 Key : Failure.Hash Value: {03bbd39e-299b-91b8-212d-d002a6bff650} 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: 7e BUGCHECK_P1: ffffffffc0000005 BUGCHECK_P2: fffff8030e2a2265 BUGCHECK_P3: ffff80031c95b638 BUGCHECK_P4: ffff80031c95ae70 FAULTING_THREAD: ffffbb8793f90080 EXCEPTION_RECORD: ffff80031c95b638 -- (.exr 0xffff80031c95b638) ExceptionAddress: fffff8030e2a2265 (obpcallback!PteHookManager::fn_isolation_pagetable+0x0000000000000315) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 0000000000000000 Parameter[1]: 0000000239dab000 Attempt to read from address 0000000239dab000 CONTEXT: ffff80031c95ae70 -- (.cxr 0xffff80031c95ae70) rax=0000000239dab000 rbx=ffffbb8793f90080 rcx=0000000000001000 rdx=0000000000000000 rsi=0000000239dab000 rdi=ffff9181d99a7000 rip=fffff8030e2a2265 rsp=ffff80031c95b870 rbp=0000000000000080 r8=ffff80031c95b940 r9=8000000000000200 r10=0000000000000000 r11=ffffbb8790910000 r12=0000000000000280 r13=0000000000000000 r14=ffffbb878f4af040 r15=fffff8030c094000 iopl=0 nv up ei pl nz ac po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050216 obpcallback!PteHookManager::fn_isolation_pagetable+0x315: fffff803`0e2a2265 f3a4 rep movs byte ptr [rdi],byte ptr [rsi] Resetting default scope PROCESS_NAME: oxygen.exe READ_ADDRESS: unable to get nt!PspSessionIdBitmap 0000000239dab000 ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p 0x%p %s EXCEPTION_CODE_STR: c0000005 EXCEPTION_PARAMETER1: 0000000000000000 EXCEPTION_PARAMETER2: 0000000239dab000 EXCEPTION_STR: 0xc0000005 STACK_TEXT: ffff8003`1c95b870 fffff803`0e2a1da1 : ffffbb87`8efa7000 00000001`2e16c000 fffff803`062ef000 ffffbb87`8efa3f80 : obpcallback!PteHookManager::fn_isolation_pagetable+0x315 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 526] ffff8003`1c95b9c0 fffff803`0e2a25df : ffffbb87`8efa7000 00000000`00001f74 fffff803`062efb60 00000000`00000035 : obpcallback!PteHookManager::fn_isolation_pages+0x261 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 602] ffff8003`1c95bad0 fffff803`0e2a1344 : ffffbb87`8efa7000 00000000`00001f74 ffff8003`1c95bbb0 fffff803`0e2a1500 : obpcallback!PteHookManager::fn_pte_inline_hook_bp_pg+0x4f [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 723] ffff8003`1c95bb90 fffff803`0e2a13d4 : fffff803`0e2a44a0 00000000`00001f74 00000000`00000000 fffff803`040ef180 : obpcallback!InstallHook+0xa4 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 982] ffff8003`1c95bbe0 fffff803`05ea29a5 : 00000000`00001f74 fffff803`0e2a13a0 00000000`00001f74 fffff803`00000001 : obpcallback!InstallHookWorker+0x34 [C:\Users\17116\source\repos\obpcallback\obpcallback\Ô´.cpp @ 1010] ffff8003`1c95bc10 fffff803`05ffc868 : fffff803`040ef180 ffffbb87`93f90080 fffff803`05ea2950 ffff8003`1c95bc80 : nt!PspSystemThreadStartup+0x55 ffff8003`1c95bc60 00000000`00000000 : ffff8003`1c95c000 ffff8003`1c956000 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: 526 FAULTING_SOURCE_CODE: 522: memcpy(Va4kb, replace_align_addr, PAGE_SIZE); 523: 524: if (Table.IsLargePage && split_pde_ptr) { 525: auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; > 526: memcpy(VaPt, (void*)(split_pde->flags.page_frame_number << 12), PAGE_SIZE); 527: } 528: else { 529: memcpy(VaPt, (void*)(Table.PdeAddress->flags.page_frame_number << 12), PAGE_SIZE); 530: } 531: SYMBOL_NAME: obpcallback!PteHookManager::fn_isolation_pagetable+315 MODULE_NAME: obpcallback IMAGE_NAME: obpcallback.sys STACK_COMMAND: .cxr 0xffff80031c95ae70 ; kb BUCKET_ID_FUNC_OFFSET: 315 FAILURE_BUCKET_ID: AV_obpcallback!PteHookManager::fn_isolation_pagetable OS_VERSION: 10.0.19041.1 BUILDLAB_STR: vb_release OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {03bbd39e-299b-91b8-212d-d002a6bff650} Followup: MachineOwner ---------按照你改的结果出错了。代码如下:#include <ntifs.h> #include <ntddk.h> #include <intrin.h> #include "ptehook.h" #define CR0_WP (1 << 16) 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(); // 添加析构函数声明 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); 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; // 实现部分 __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; return MmGetVirtualForPhysical(physAddr); } 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.PdpteAddress->flags.page_size) ? 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.PdeAddress->flags.large_page) ? 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); if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; memcpy(VaPt, (void*)(split_pde->flags.page_frame_number << 12), PAGE_SIZE); } else { memcpy(VaPt, (void*)(Table.PdeAddress->flags.page_frame_number << 12), PAGE_SIZE); } memcpy(VaPdt, (void*)(Table.PdpteAddress->flags.page_frame_number << 12), PAGE_SIZE); memcpy(VaPdpt, (void*)(Table.Pml4Address[pml4e_index] & ~0xFFF), PAGE_SIZE); auto new_pte = (decltype(PAGE_TABLE::PteAddress))VaPt; new_pte[pte_index].flags.page_frame_number = fn_va_to_pa(Va4kb) >> 12; 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; auto new_pdpte = (decltype(PAGE_TABLE::PdpteAddress))VaPdpt; new_pdpte[pdpte_index].flags.page_frame_number = fn_va_to_pa(VaPdt) >> 12; auto new_pml4 = (UINT64*)fn_pa_to_va(cr3_val & ~0xFFF); new_pml4[pml4e_index] = (new_pml4[pml4e_index] & 0xFFF) | (fn_va_to_pa(VaPdpt) & ~0xFFF); __invlpg(replace_align_addr); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 页表隔离完成: 新PFN=0x%llx\n", fn_va_to_pa(Va4kb) >> 12); return true; } bool PteHookManager::fn_isolation_pages(HANDLE process_id, void* ori_addr) { PEPROCESS Process; if (!NT_SUCCESS(PsLookupProcessByProcessId(process_id, &Process))) { logger("查找进程失败", true); return false; } DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 开始隔离页面: PID=%d, 地址=0x%p\n", (ULONG)(ULONG_PTR)process_id, ori_addr); KAPC_STATE ApcState; KeStackAttachProcess(Process, &ApcState); void* AlignAddr = PAGE_ALIGN(ori_addr); PAGE_TABLE Table = { 0 }; Table.LineAddress = (UINT64)AlignAddr; UINT64 target_cr3 = *(UINT64*)((UCHAR*)Process + 0x28); if (!NT_SUCCESS(get_page_table(target_cr3, Table))) { KeUnstackDetachProcess(&ApcState); ObDereferenceObject(Process); logger("获取目标进程页表失败", true); return false; } bool success = false; decltype(PAGE_TABLE::PdeAddress) split_pde = nullptr; if (Table.IsLargePage) { split_pde = (decltype(PAGE_TABLE::PdeAddress))ExAllocatePoolWithTag(NonPagedPool, sizeof(*split_pde), 'pdeS'); if (!split_pde || !fn_split_large_pages(Table.PdeAddress, split_pde)) { if (split_pde) ExFreePoolWithTag(split_pde, 'pdeS'); KeUnstackDetachProcess(&ApcState); ObDereferenceObject(Process); logger("拆分大页失败", true); return false; } if (Table.PdeAddress->flags.global) { Table.PdeAddress->flags.global = 0; fn_add_g_bit_info(AlignAddr, Table.PdeAddress, nullptr); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 清除大页G位: PDE=0x%llx\n", Table.PdeAddress->value); } success = fn_isolation_pagetable(target_cr3, AlignAddr, split_pde); } else if (Table.PteAddress && Table.PteAddress->flags.global) { Table.PteAddress->flags.global = 0; fn_add_g_bit_info(AlignAddr, nullptr, Table.PteAddress); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 清除PTE G位: PTE=0x%llx\n", Table.PteAddress->value); success = fn_isolation_pagetable(target_cr3, AlignAddr, split_pde); if (split_pde) ExFreePoolWithTag(split_pde, 'pdeS'); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 页表状态: IsLargePage=%d, Is1GBPage=%d\n", Table.IsLargePage, Table.Is1GBPage); if (Table.PteAddress) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] PTE 值: 0x%llx (G位=%d)\n", Table.PteAddress->value, Table.PteAddress->flags.global); } KeUnstackDetachProcess(&ApcState); ObDereferenceObject(Process); if (success) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 页面隔离成功\n"); } else { logger("页面隔离失败", true); } return success; } 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] 获取目标进程上下文 PEPROCESS targetProcess; if (!NT_SUCCESS(PsLookupProcessByProcessId(process_id, &targetProcess))) { return false; } KAPC_STATE apcState; KeStackAttachProcess(targetProcess, &apcState); // [3] 构造跳转指令 JMP_ABS jmpCmd = {}; memcpy(jmpCmd.opcode, "\xFF\x25\x00\x00\x00\x00", 6); // FF25 00000000 jmpCmd.address = reinterpret_cast<ULONG64>(hk_addr); // [4] 直接写入被隔离页 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); // [5] 记录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++; } // [6] 清理 KeUnstackDetachProcess(&apcState); ObDereferenceObject(targetProcess); return success; } // 析构函数清理资源 PteHookManager::~PteHookManager() { if (m_TrampLinePool) { MmFreeContiguousMemory(m_TrampLinePool); m_TrampLinePool = nullptr; } } 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; }

时间: 2025-07-23 09:03:12 浏览: 5
<think>根据错误日志,问题发生在`fn_isolation_pagetable`函数中,具体是在尝试复制大页拆分后的PTE表时出现了访问违规(Access violation)。错误信息显示:`Attempt to read from address 0000000239dab000`。这个地址是一个物理地址(0x239dab000),而我们试图在虚拟地址空间直接访问它,这是不允许的。 ### 问题分析 在`fn_isolation_pagetable`函数中,有以下代码: ```cpp if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; memcpy(VaPt, (void*)(split_pde->flags.page_frame_number << 12), PAGE_SIZE); } ``` 这里,`split_pde->flags.page_frame_number << 12`得到的是物理地址(0x239dab000),然后我们将其强制转换为`void*`并试图用`memcpy`复制。但是,在Windows内核中,我们不能直接访问物理地址,必须将其映射到虚拟地址才能访问。 ### 解决方案 我们需要将物理地址转换为虚拟地址。在代码中已经有一个函数`fn_pa_to_va`用于将物理地址转换为虚拟地址。因此,我们应该使用这个函数来获取虚拟地址,然后再进行复制。 ### 修复代码 修改`fn_isolation_pagetable`函数中的相关部分: ```cpp if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; // 获取物理地址 UINT64 pte_phys = split_pde->flags.page_frame_number << 12; // 转换为虚拟地址 void* pte_va = fn_pa_to_va(pte_phys); if (pte_va) { memcpy(VaPt, pte_va, PAGE_SIZE); } else { logger("无法将PTE物理地址转换为虚拟地址", true); // 清理并返回错误 MmFreeContiguousMemory(VaPt); MmFreeContiguousMemory(Va4kb); MmFreeContiguousMemory(VaPdt); MmFreeContiguousMemory(VaPdpt); return false; } } else { // 同样,对于非大页的情况,也要转换 UINT64 pte_phys = Table.PdeAddress->flags.page_frame_number << 12; void* pte_va = fn_pa_to_va(pte_phys); if (pte_va) { memcpy(VaPt, pte_va, PAGE_SIZE); } else { logger("无法将PTE物理地址转换为虚拟地址", true); MmFreeContiguousMemory(VaPt); MmFreeContiguousMemory(Va4kb); MmFreeContiguousMemory(VaPdt); MmFreeContiguousMemory(VaPdpt); return false; } } ``` ### 解释 1. 我们首先从PDE中获取页表的物理地址(`split_pde->flags.page_frame_number << 12`)。 2. 使用`fn_pa_to_va`函数将物理地址转换为虚拟地址。 3. 如果转换成功(返回非NULL),则使用`memcpy`复制页表内容。 4. 如果转换失败,记录错误并清理资源,返回失败。 ### 其他注意事项 在非大页的情况下(else分支),同样需要将物理地址转换为虚拟地址,因此我们同样进行了修改。 ### 完整修复后的`fn_isolation_pagetable`函数相关部分 ```cpp // ... [前面代码不变] if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; UINT64 pte_phys = split_pde->flags.page_frame_number << 12; void* pte_va = fn_pa_to_va(pte_phys); if (pte_va) { memcpy(VaPt, pte_va, PAGE_SIZE); } else { logger("无法将PTE物理地址转换为虚拟地址", true); MmFreeContiguousMemory(VaPt); MmFreeContiguousMemory(Va4kb); MmFreeContiguousMemory(VaPdt); MmFreeContiguousMemory(VaPdpt); return false; } } else { UINT64 pte_phys = Table.PdeAddress->flags.page_frame_number << 12; void* pte_va = fn_pa_to_va(pte_phys); if (pte_va) { memcpy(VaPt, pte_va, PAGE_SIZE); } else { logger("无法将PTE物理地址转换为虚拟地址", true); MmFreeContiguousMemory(VaPt); MmFreeContiguousMemory(Va4kb); MmFreeContiguousMemory(VaPdt); MmFreeContiguousMemory(VaPdpt); return false; } } // ... [后面代码不变] ``` ### 测试建议 在修复后,重新运行测试,确保能够正确访问转换后的虚拟地址,避免访问违规。 ### 其他潜在问题 在`fn_isolation_pages`函数中,当处理非大页且PTE的G位被清除的情况时,我们调用了`fn_isolation_pagetable`,但是在调用后立即释放了`split_pde`(如果存在)并解除了进程附加。然而,在`fn_isolation_pagetable`中我们使用了`split_pde_ptr`,所以要注意在`fn_isolation_pagetable`完成之前不能释放`split_pde`。目前,在`fn_isolation_pages`中,非大页情况下`split_pde`为nullptr,所以没有问题。大页情况下,`split_pde`在`fn_isolation_pagetable`使用后,在`fn_isolation_pages`中释放(在非大页分支中不会进入,所以不会释放两次)。因此,释放的位置是合理的。 但是,在`fn_isolation_pages`的大页处理分支中,`split_pde`在调用`fn_isolation_pagetable`后并没有被释放,这可能会导致内存泄漏。因此,我们需要在`fn_isolation_pages`中释放它。 修改`fn_isolation_pages`函数的大页分支: ```cpp if (Table.IsLargePage) { // ... 分配split_pde和拆分大页 ... success = fn_isolation_pagetable(target_cr3, AlignAddr, split_pde); // 释放split_pde if (split_pde) { ExFreePoolWithTag(split_pde, 'pdeS'); } } ``` ### 总结 主要问题是直接访问了物理地址,需要通过`fn_pa_to_va`转换为虚拟地址。此外,注意内存泄漏问题,及时释放分配的`split_pde`。 §§相关问题§§: 1. 在内核中如何安全地将物理地址映射到虚拟地址? 2. 页表隔离技术中如何处理多处理器环境下的TLB刷新? 3. 在Windows内核中,大页拆分后如何确保新页表的正确性? 4. 如何验证页表隔离确实成功,使得不同进程看到不同的物理页面?</think>根据错误日志分析,问题出在页表隔离函数 `fn_isolation_pagetable` 中访问物理地址时没有正确转换为虚拟地址。具体错误发生在: ```cpp memcpy(VaPt, (void*)(split_pde->flags.page_frame_number << 12), PAGE_SIZE); ``` 这里直接将物理地址作为指针使用,导致访问违规(Access Violation)。以下是修复方案: ### 问题原因 1. **物理地址直接访问**:`split_pde->flags.page_frame_number << 12` 得到的是物理地址,不能直接作为虚拟地址访问 2. **缺少地址转换**:没有使用 `fn_pa_to_va()` 将物理地址转换为虚拟地址 3. **内存类型不匹配**:`MmAllocateContiguousMemorySpecifyCache` 分配的内存需要特殊处理 ### 修复方案 #### 1. 修改页表隔离函数中的内存访问 ```cpp bool PteHookManager::fn_isolation_pagetable(UINT64 cr3_val, void* replace_align_addr, void* split_pde_ptr) { // ... [其他代码不变] ... // 修复点:添加物理地址到虚拟地址的转换 auto get_va_from_pfn = [this](UINT64 pfn) -> void* { PHYSICAL_ADDRESS physAddr; physAddr.QuadPart = pfn << 12; return MmGetVirtualForPhysical(physAddr); }; // 修改内存拷贝部分 if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; void* source_va = get_va_from_pfn(split_pde->flags.page_frame_number); if (!source_va) { logger("无法转换物理地址到虚拟地址", true); return false; } memcpy(VaPt, source_va, PAGE_SIZE); } else { void* source_va = get_va_from_pfn(Table.PdeAddress->flags.page_frame_number); if (!source_va) { logger("无法转换物理地址到虚拟地址", true); return false; } memcpy(VaPt, source_va, PAGE_SIZE); } // ... [其他代码不变] ... } ``` #### 2. 增强物理地址转换函数 ```cpp void* PteHookManager::fn_pa_to_va(UINT64 pa) { PHYSICAL_ADDRESS physAddr; physAddr.QuadPart = pa; // 使用更安全的转换方法 PMDL pMdl = IoAllocateMdl((PVOID)physAddr.QuadPart, PAGE_SIZE, FALSE, FALSE, NULL); if (!pMdl) return nullptr; __try { MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess); PVOID mappedVa = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority); MmUnlockPages(pMdl); IoFreeMdl(pMdl); return mappedVa; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(pMdl); return nullptr; } } ``` #### 3. 修改大页拆分函数中的内存分配 ```cpp bool PteHookManager::fn_split_large_pages(void* in_pde_ptr, void* out_pde_ptr) { // ... [其他代码不变] ... // 修改内存分配方式 PHYSICAL_ADDRESS maxAddr; maxAddr.QuadPart = MAXULONG64; PHYSICAL_ADDRESS lowAddr; lowAddr.QuadPart = 0; // 使用正确的内存类型 auto pt = (decltype(PAGE_TABLE::PteAddress))MmAllocateContiguousMemoryEx( PAGE_SIZE, lowAddr, maxAddr, lowAddr, PAGE_READWRITE | PAGE_NOCACHE ); // ... [其他代码不变] ... } ``` ### 完整修复后的关键函数 ```cpp void* PteHookManager::fn_pa_to_va(UINT64 pa) { PHYSICAL_ADDRESS physAddr; physAddr.QuadPart = pa; PMDL pMdl = IoAllocateMdl((PVOID)physAddr.QuadPart, PAGE_SIZE, FALSE, FALSE, NULL); if (!pMdl) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[PTE_HOOK] 分配MDL失败 (PA=0x%llx)\n", pa); return nullptr; } __try { MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess); PVOID mappedVa = MmGetSystemAddressForMdlSafe(pMdl, NormalPagePriority); MmUnlockPages(pMdl); IoFreeMdl(pMdl); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 物理地址转换: PA=0x%llx -> VA=0x%p\n", pa, mappedVa); return mappedVa; } __except (EXCEPTION_EXECUTE_HANDLER) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[PTE_HOOK] 地址转换异常 (PA=0x%llx)\n", pa); IoFreeMdl(pMdl); return nullptr; } } bool PteHookManager::fn_isolation_pagetable(UINT64 cr3_val, void* replace_align_addr, void* split_pde_ptr) { // ... [初始化代码] ... // 安全获取源地址 auto get_source_va = [this](auto entry) -> void* { if (!entry) return nullptr; UINT64 pfn = entry->flags.page_frame_number; UINT64 physAddr = pfn << 12; return fn_pa_to_va(physAddr); }; // 修改内存拷贝部分 if (Table.IsLargePage && split_pde_ptr) { auto split_pde = (decltype(PAGE_TABLE::PdeAddress))split_pde_ptr; void* source_va = get_source_va(split_pde); if (!source_va) { logger("无法获取大页PTE的虚拟地址", true); return false; } memcpy(VaPt, source_va, PAGE_SIZE); } else { void* source_va = get_source_va(Table.PdeAddress); if (!source_va) { logger("无法获取常规PTE的虚拟地址", true); return false; } memcpy(VaPt, source_va, PAGE_SIZE); } // ... [其他代码不变] ... } ``` ### 修复说明 1. **物理地址转换**: - 使用 `IoAllocateMdl` + `MmProbeAndLockPages` 安全地将物理地址映射到虚拟地址 - 添加了详细的错误日志和异常处理 2. **内存分配修正**: - 使用 `MmAllocateContiguousMemoryEx` 替代 `MmAllocateContiguousMemorySpecifyCache` - 明确设置内存属性为 `PAGE_NOCACHE`,避免缓存一致性问题 3. **错误处理增强**: - 在每个关键操作后添加了详细的调试输出 - 增加了空指针检查和异常处理 4. **TLB刷新优化**: ```cpp // 在 __invlpg 后添加多核刷新 KeIpiGenericCall([](ULONG_PTR Context) -> ULONG_PTR { __invlpg((void*)Context); return 0; }, (ULONG_PTR)replace_align_addr); ``` ### 验证建议 在关键位置添加更多调试输出: ```cpp DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[PTE_HOOK] 复制页表数据: 源VA=%p, 目标VA=%p, 大小=%d\n", source_va, VaPt, PAGE_SIZE); ``` 这些修改将解决物理地址访问问题,并提高代码的健壮性。
阅读全文

相关推荐

kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF kd> ed nt!Kd_IHVDRIVER_Mask 0xFFFFFFFF kd> g [+] [DriverEntry] 驱动加载开始 [+] [DriverEntry] 驱动加载成功 [+] [ProcessNotifyCallback] 目标进程 oxygen.exe 创建 (PID: 4796) [+] [ProcessNotifyCallback] 工作线程已创建 [+] Worker thread started for hook installation [+] [InstallHook] 找到目标函数地址: FFFFF8057B2EFB60 [PTE_HOOK] Hook安装成功!跳板指令: jmp [0xFFFFCF812E85D006] -> 0xFFFFF805802B14E0 [+] [InstallHook] Hook 成功安装. 跳板地址: FFFFCF812E85D000 Break instruction exception - code 80000003 (first chance) obpcallback!InstallHook+0xf6: fffff805802b1396 cc int 3 kd> g Break instruction exception - code 80000003 (first chance) ******************************************************************************* * * * You are seeing this message because you pressed either * * CTRL+C (if you run console kernel debugger) or, * * CTRL+BREAK (if you run GUI kernel debugger), * * on your debugger machine's keyboard. * * * * THIS IS NOT A BUG OR A SYSTEM CRASH * * * * If you did not intend to break into the debugger, press the "g" key, then * * press the "Enter" key now. This message might immediately reappear. If it * * does, press "g" and "Enter" again. * * * ******************************************************************************* nt!DbgBreakPointWithStatus: fffff8057affd0b0 cc int 3 kd> u FFFFCF812E85D000 ffffcf812e85d000 ff2500000000 jmp qword ptr [ffffcf812e85d006] ffffcf812e85d006 e014 loopne ffffcf812e85d01c ffffcf812e85d008 2b8005f8ffff sub eax,dword ptr [rax-7FBh] ffffcf812e85d00e ffd5 call rbp ffffcf812e85d010 fd std ffffcf812e85d011 5f pop rdi ffffcf812e85d012 dd75f5 fnsave [rbp-0Bh] ffffcf812e85d015 5d pop rbp

nt!DbgBreakPointWithStatus: fffff8057affd0b0 cc int 3 kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF kd> ed nt!Kd_IHVDRIVER_Mask 0xFFFFFFFF kd> g [+] [ProcessNotifyCallback] 目标进程 oxygen.exe 创建 (PID: 8104) [+] [ProcessNotifyCallback] 工作线程已创建 [+] Worker thread started for hook installation [+] [InstallHook] 找到目标函数地址: FFFFF8057B2EFB60 [PTE_HOOK] 跳板池分配成功: 地址=0xFFFFCF812F1A9000, 大小=32768字节 [PTE_HOOK] 构造跳转指令: 目标地址: 0xFFFFF805802B15A0 跳板位置: 0xFFFFCF812F1A9000 指令格式: FF 25 00 00 00 00 + 8字节地址 [PTE_HOOK] 跳板指令: jmp [rip+0] -> 0xFFFFF805802B15A0 [PTE_HOOK] Hook记录 #0: 原始地址=0xFFFFF8057B2EFB60, 跳板=0xFFFFCF812F1A9000 [PTE_HOOK] Hook安装成功! 跳板指令: jmp [rip+0] -> 0xFFFFF805802B15A0 [+] [InstallHook] Hook 成功安装. 跳板地址: FFFFCF812F1A9000 Break instruction exception - code 80000003 (first chance) ******************************************************************************* * * * You are seeing this message because you pressed either * * CTRL+C (if you run console kernel debugger) or, * * CTRL+BREAK (if you run GUI kernel debugger), * * on your debugger machine's keyboard. * * * * THIS IS NOT A BUG OR A SYSTEM CRASH * * * * If you did not intend to break into the debugger, press the "g" key, then * * press the "Enter" key now. This message might immediately reappear. If it * * does, press "g" and "Enter" again. * * * ******************************************************************************* nt!DbgBreakPointWithStatus: fffff8057affd0b0 cc int 3 kd> u FFFFCF812F1A9000 ffffcf812f1a9000 ff2500000000 jmp qword ptr [ffffcf812f1a9006] ffffcf812f1a9006 a0152b8005f8ffffff mov al,byte ptr [FFFFFFF805802B15h] ffffcf812f1a900f d5 ??? ffffcf812f1a9010 fd std ffffcf812f1a9011 5f pop rdi ffffcf812f1a9012 dd75f5 fnsave [rbp-0Bh] ffffcf812f1a9015 5d pop rbp ffffcf812f1a9016 7df7 jge ffffcf812f1a900f这个写入还没成功吗?什么原因

nt!DbgBreakPointWithStatus: fffff8057affd0b0 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: 7948) [+] [ProcessNotifyCallback] 工作线程已创建 [+] Worker thread started for hook installation [+] [InstallHook] 找到目标函数地址: FFFFF8057B2EFB60 [PTE_HOOK] 跳板池分配成功: 地址=0xFFFFCF812F9C8000, 大小=32768字节 [PTE_HOOK] 构造跳转指令: 目标地址: 0xFFFFF805802B14E0 跳板位置: 0xFFFFCF812F9C8000 指令大小: 18字节 写入跳板结构到 0xFFFFCF812F9C8000: FF 25 00 00 00 00 00 00 00 00 E0 14 2B 80 05 F8 FF FF 反汇编跳板指令: Break instruction exception - code 80000003 (first chance) nt!KeCheckStackAndTargetAddress+0x53: fffff8057ae8da03 cc int 3 kd> g KDTARGET: Refreshing KD connection *** Fatal System Error: 0x00000139 (0x0000000000000000,0x0000000000000000,0x0000000000000000,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: fffff8057affd0b0 cc int 3 kd> !analyze -v Connected to Windows 10 19041 x64 target at (Tue Jun 24 23:20:51.742 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 Loading unloaded module list ...... ERROR: FindPlugIns 8007007b ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* KERNEL_SECURITY_CHECK_FAILURE (139) A kernel component has corrupted a critical data structure. The corruption could potentially allow a malicious user to gain control of this machine. Arguments: Arg1: 0000000000000000, A stack-based buffer has been overrun. Arg2: 0000000000000000, Address of the trap frame for the exception that caused the BugCheck Arg3: 0000000000000000, Address of the exception record for the exception that caused the BugCheck Arg4: 0000000000000000, Reserved 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. KEY_VALUES_STRING: 1 Key : Analysis.CPU.mSec Value: 3750 Key : Analysis.Elapsed.mSec Value: 44828 Key : Analysis.IO.Other.Mb Value: 0 Key : Analysis.IO.Read.Mb Value: 2 Key : Analysis.IO.Write.Mb Value: 0 Key : Analysis.Init.CPU.mSec Value: 3625 Key : Analysis.Init.Elapsed.mSec Value: 71532 Key : Analysis.Memory.CommitPeak.Mb Value: 62 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: 0x139 Key : Bugcheck.Code.LegacyAPI Value: 0x139 Key : Bugcheck.Code.TargetModel Value: 0x139 Key : Failure.Bucket Value: 0x139_0_LEGACY_GS_VIOLATION_nt!guard_icall_bugcheck Key : Failure.Hash Value: {9bee41a7-2ef9-07ca-7e59-7d5a0c6e2d05} 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: 139 BUGCHECK_P1: 0 BUGCHECK_P2: 0 BUGCHECK_P3: 0 BUGCHECK_P4: 0 FAULTING_THREAD: ffffbd046bee5080 TRAP_FRAME: ffff800000000000 -- (.trap 0xffff800000000000) Unable to read trap frame at ffff800000000000 Resetting default scope EXCEPTION_RECORD: 0000000000000000 -- (.exr 0x0) Cannot read Exception record @ 0000000000000000 PROCESS_NAME: System STACK_TEXT: fffffc89cb028028 fffff8057b111882 : fffffc89cb028190 fffff8057af7c940 0000000000000100 0000000000000000 : nt!DbgBreakPointWithStatus fffffc89cb028030 fffff8057b110e66 : 0000000000000003 fffffc89cb028190 fffff8057b00a0c0 0000000000000139 : nt!KiBugCheckDebugBreak+0x12 fffffc89cb028090 fffff8057aff5317 : fffff8057ac00000 0000000000000001 fffffc89cb029a38 fffff8057aea29a5 : nt!KeBugCheck2+0x946 fffffc89cb0287a0 fffff8057affdd1b : 0000000000000139 0000000000000000 0000000000000000 0000000000000000 : nt!KeBugCheckEx+0x107 fffffc89cb0287e0 fffff8057ae8da0c : fffffc89cb028878 fffffc89cb0288b8 0000000000000000 fffffc89cb028920 : nt!guard_icall_bugcheck+0x1b fffffc89cb028810 fffff8057afcbe6b : fffff8057aea29a5 fffff8057acd158c 0000000000000000 0000000000000000 : nt!KeCheckStackAndTargetAddress+0x5c fffffc89cb028840 fffff8057affe0d2 : fffff8057acd158c fffffc89cb028e20 fffff8057afcbe30 0000000000000000 : nt!_C_specific_handler+0x3b fffffc89cb0288b0 fffff8057ae52db7 : fffffc89cb028e20 0000000000000000 fffffc89cb029c10 fffff8057aea29a5 : nt!RtlpExecuteHandlerForException+0x12 fffffc89cb0288e0 fffff8057ae519a6 : fffffc89cb0297f8 fffffc89cb029530 fffffc89cb0297f8 fffffc89cb029a9a : nt!RtlDispatchException+0x297 fffffc89cb029000 fffff8057b0072ac : 0000000000001000 fffffc89cb0298a0 ffff800000000000 0000000000000000 : nt!KiDispatchException+0x186 fffffc89cb0296c0 fffff8057b003443 : fffffc89cb029a48 fffffc89cb029990 fffffc89cb0299a0 fffff8057affd0d5 : nt!KiExceptionDispatch+0x12c fffffc89cb0298a0 0000000000000000 : fffff805802b19e9 fffff805802b2ce0 00000000000000b8 0000000000000000 : nt!KiPageFault+0x443 SYMBOL_NAME: nt!guard_icall_bugcheck+1b MODULE_NAME: nt IMAGE_NAME: ntkrnlmp.exe STACK_COMMAND: .process /r /p 0xffffbd046545f1c0; .thread 0xffffbd046bee5080 ; kb BUCKET_ID_FUNC_OFFSET: 1b FAILURE_BUCKET_ID: 0x139_0_LEGACY_GS_VIOLATION_nt!guard_icall_bugcheck OS_VERSION: 10.0.19041.1 BUILDLAB_STR: vb_release OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {9bee41a7-2ef9-07ca-7e59-7d5a0c6e2d05} Followup: MachineOwner --------- kd> u FFFFCF812F9C8000 ffffcf812f9c8000 ff2500000000 jmp qword ptr [ffffcf812f9c8006] ffffcf812f9c8006 0000 add byte ptr [rax],al ffffcf812f9c8008 0000 add byte ptr [rax],al ffffcf812f9c800a e014 loopne ffffcf812f9c8020 ffffcf812f9c800c 2b8005f8ffff sub eax,dword ptr [rax-7FBh] ffffcf812f9c8012 dd75f5 fnsave [rbp-0Bh] ffffcf812f9c8015 5d pop rbp ffffcf812f9c8016 7df7 jge ffffcf812f9c800f这是什么错误?写入时候的错误还是执行hook内容的错误?

nt!DbgBreakPointWithStatus: fffff8057affd0b0 cc int 3 kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF kd> g [+] Driver loaded successfully [+] Target process oxygen.exe created (PID: 3348) [+] Worker thread created for hook installation [+] Worker thread started for hook installation [+] Found ObReferenceObjectByHandleWithTag at: FFFFF8057B2EFB60 [+] Hook installed successfully. Trampoline at FFFFCF812EB73000 Break instruction exception - code 80000003 (first chance) ******************************************************************************* * * * You are seeing this message because you pressed either * * CTRL+C (if you run console kernel debugger) or, * * CTRL+BREAK (if you run GUI kernel debugger), * * on your debugger machine's keyboard. * * * * THIS IS NOT A BUG OR A SYSTEM CRASH * * * * If you did not intend to break into the debugger, press the "g" key, then * * press the "Enter" key now. This message might immediately reappear. If it * * does, press "g" and "Enter" again. * * * ******************************************************************************* nt!DbgBreakPointWithStatus: fffff8057affd0b0 cc int 3 kd> u FFFFCF812EB73000 ffffcf812eb73000 ff2500000000 jmp qword ptr [ffffcf812eb73006] ffffcf812eb73006 e014 loopne ffffcf812eb7301c ffffcf812eb73008 2b8005f8ffff sub eax,dword ptr [rax-7FBh] ffffcf812eb7300e ffd5 call rbp ffffcf812eb73010 fd std ffffcf812eb73011 5f pop rdi ffffcf812eb73012 dd75f5 fnsave [rbp-0Bh] ffffcf812eb73015 5d pop rbp kd> dd ffffcf812eb73006 ffffcf812eb73006 802b14e0 fffff805 5ffdd5ff 5df575dd ffffcf812eb73016 5777f77d 7d755f75 5d5df5f5 555fd555 ffffcf812eb73026 55557555 555d7d55 555555f5 55555555 ffffcf812eb73036 55555555 55555555 55555555 55555555 ffffcf812eb73046 55555555 55555555 55555555 55555555 ffffcf812eb73056 55555555 55555555 55555555 55555555 ffffcf812eb73066 55555555 55555555 55555555 55555555 ffffcf812eb73076 55555555 55555555 55555555 55555555正确吗?

kd> ed nt!Kd_DEFAULT_Mask 0xFFFFFFFF kd> ed nt!Kd_IHVDRIVER_Mask 0xFFFFFFFF kd> g KDTARGET: Refreshing KD connection *** Fatal System Error: 0x0000007e (0xFFFFFFFFC0000005,0xFFFFF805802B1699,0xFFFFFC89CAC5A458,0xFFFFFC89CAC59C90) 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: fffff8057affd0b0 cc int 3 kd> !analyze -v Connected to Windows 10 19041 x64 target at (Tue Jul 15 22:09:55.446 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 Loading unloaded module list ...... ERROR: FindPlugIns 8007007b ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common BugCheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: ffffffffc0000005, The exception code that was not handled Arg2: fffff805802b1699, The address that the exception occurred at Arg3: fffffc89cac5a458, Exception Record Address Arg4: fffffc89cac59c90, Context Record Address 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. KEY_VALUES_STRING: 1 Key : AV.Type Value: Read Key : Analysis.CPU.mSec Value: 3609 Key : Analysis.Elapsed.mSec Value: 47643 Key : Analysis.IO.Other.Mb Value: 0 Key : Analysis.IO.Read.Mb Value: 3 Key : Analysis.IO.Write.Mb Value: 0 Key : Analysis.Init.CPU.mSec Value: 3734 Key : Analysis.Init.Elapsed.mSec Value: 52586 Key : Analysis.Memory.CommitPeak.Mb Value: 74 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: 0x7e Key : Bugcheck.Code.LegacyAPI Value: 0x7e Key : Bugcheck.Code.TargetModel Value: 0x7e Key : Failure.Bucket Value: AV_pte1!InitHookWin10 Key : Failure.Exception.Code Value: 0xc0000005 Key : Failure.Exception.IP.Address Value: 0xfffff805802b1699 Key : Failure.Exception.IP.Module Value: pte1 Key : Failure.Exception.IP.Offset Value: 0x1699 Key : Failure.Exception.Record Value: 0xfffffc89cac5a458 Key : Failure.Hash Value: {14fb13e5-207c-6ef8-f4d3-d7bd4cc8e1a3} 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: 7e BUGCHECK_P1: ffffffffc0000005 BUGCHECK_P2: fffff805802b1699 BUGCHECK_P3: fffffc89cac5a458 BUGCHECK_P4: fffffc89cac59c90 FAULTING_THREAD: ffffbd0465f0f040 EXCEPTION_RECORD: fffffc89cac5a458 -- (.exr 0xfffffc89cac5a458) ExceptionAddress: fffff805802b1699 (pte1!InitHookWin10+0x0000000000000639) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 0000000000000000 Parameter[1]: 00000245cb781000 Attempt to read from address 00000245cb781000 CONTEXT: fffffc89cac59c90 -- (.cxr 0xfffffc89cac59c90) rax=0000000000000000 rbx=0000000000000000 rcx=00000000001ff000 rdx=0000000000000000 rsi=00000245cb781000 rdi=ffffdf7d0da01000 rip=fffff805802b1699 rsp=fffffc89cac5a690 rbp=0000000000000000 r8=fffffc89cac5a068 r9=7fffbd046545f688 r10=7ffffffffffffffc r11=ffffbd0465f0f040 r12=ffff8d005e2fa950 r13=ffffffff800020c4 r14=fffff805802b42a8 r15=ffffbd046b39fe30 iopl=0 nv up ei pl zr na po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050246 pte1!InitHookWin10+0x639: fffff805802b1699 f3a4 rep movs byte ptr [rdi],byte ptr [rsi] Resetting default scope PROCESS_NAME: System READ_ADDRESS: unable to get nt!PspSessionIdBitmap 00000245cb781000 ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p 0x%p %s EXCEPTION_CODE_STR: c0000005 EXCEPTION_PARAMETER1: 0000000000000000 EXCEPTION_PARAMETER2: 00000245cb781000 EXCEPTION_STR: 0xc0000005 STACK_TEXT: fffffc89cac5a690 fffff805802b1f7d : fffff8057b266000 0000000000001ec8 0000000000000ca0 fffff8057ae1cb26 : pte1!InitHookWin10+0x639 [C:\Users\17116\source\repos\pte1\pte1\Ô´.cpp @ 204] fffffc89cac5a830 fffff805802b20fb : ffffbd046b39fe30 ffffbd046575f000 ffffbd046575f000 ffffbd046cc53de0 : pte1!DriverEntry+0x9d [C:\Users\17116\source\repos\pte1\pte1\Ô´.cpp @ 349] fffffc89cac5a890 fffff805802b2030 : ffffbd046575f000 fffffc89cac5aa60 ffffbd046c6aedd0 ffffbd046b39fe30 : pte1!FxDriverEntryWorker+0xbf [minkernel\wdf\framework\kmdf\src\dynamic\stub\stub.cpp @ 360] fffffc89cac5a8d0 fffff8057b3538f4 : ffffbd046575f000 0000000000000000 ffffbd046b39fe30 0000000000000000 : pte1!FxDriverEntry+0x20 [minkernel\wdf\framework\kmdf\src\dynamic\stub\stub.cpp @ 249] fffffc89cac5a900 fffff8057b31e3cd : 000000000000000a 0000000000000000 0000000000000000 0000000000001000 : nt!PnpCallDriverEntry+0x4c fffffc89cac5a960 fffff8057b364207 : 0000000000000000 0000000000000000 fffff8057b925440 0000000000000000 : nt!IopLoadDriver+0x4e5 fffffc89cac5ab30 fffff8057af034b5 : ffffbd0400000000 ffffffff800020c4 ffffbd0465f0f040 ffffbd040000000c : nt!IopLoadUnloadDriver+0x57 fffffc89cac5ab70 fffff8057aea29a5 : ffffbd0465f0f040 0000000000000080 ffffbd046545f1c0 000fa067b8bbbdff : nt!ExpWorkerThread+0x105 fffffc89cac5ac10 fffff8057affc868 : fffff80575eaf180 ffffbd0465f0f040 fffff8057aea2950 0000000000000000 : nt!PspSystemThreadStartup+0x55 fffffc89cac5ac60 0000000000000000 : fffffc89cac5b000 fffffc89cac55000 0000000000000000 0000000000000000 : nt!KiStartSystemThread+0x28 FAULTING_SOURCE_LINE: C:\Users\17116\source\repos\pte1\pte1\Ô´.cpp FAULTING_SOURCE_FILE: C:\Users\17116\source\repos\pte1\pte1\Ô´.cpp FAULTING_SOURCE_LINE_NUMBER: 204 FAULTING_SOURCE_CODE: 200: UnmapPhysicalMemory(Cr3Va); 201: return status; 202: } 203: > 204: RtlCopyMemory(LargePageBuf, OrigDataVa, 0x200000); 205: UnmapPhysicalMemory(OrigDataVa); 206: 207: // ?????????????? 208: PUCHAR HookLoc = (PUCHAR)LargePageBuf + (TargetVa & 0x1FFFFF) + Offset; 209: HookLoc[0] = 0x90; // NOP SYMBOL_NAME: pte1!InitHookWin10+639 MODULE_NAME: pte1 IMAGE_NAME: pte1.sys STACK_COMMAND: .cxr 0xfffffc89cac59c90 ; kb BUCKET_ID_FUNC_OFFSET: 639 FAILURE_BUCKET_ID: AV_pte1!InitHookWin10 OS_VERSION: 10.0.19041.1 BUILDLAB_STR: vb_release OSPLATFORM_TYPE: x64 OSNAME: Windows 10 FAILURE_ID_HASH: {14fb13e5-207c-6ef8-f4d3-d7bd4cc8e1a3} Followup: MachineOwner --------- #include <ntifs.h> #include <wdm.h> // 完整的页表项结构 typedef union _HARDWARE_PTE { struct { ULONG64 Valid : 1; ULONG64 Write : 1; ULONG64 Owner : 1; ULONG64 WriteThrough : 1; ULONG64 CacheDisable : 1; ULONG64 Accessed : 1; ULONG64 Dirty : 1; ULONG64 LargePage : 1; // 修复:添加缺失的LargePage ULONG64 Global : 1; ULONG64 CopyOnWrite : 1; ULONG64 Prototype : 1; ULONG64 reserved0 : 1; ULONG64 PageFrameNumber : 36; ULONG64 reserved1 : 4; ULONG64 SoftwareWsIndex : 11; ULONG64 NoExecute : 1; }; ULONG64 AsUINT64; // 添加联合体支持 } HARDWARE_PTE, * PHARDWARE_PTE; // 全局资源记录 typedef struct _HOOK_CONTEXT { PVOID NewPages[4]; // [0]PPE [1]PDE [2]PTE [3]Data ULONG_PTR OriginalPTE; BOOLEAN IsLargePage; } HOOK_CONTEXT, * PHOOK_CONTEXT; static HANDLE g_hSection = NULL; // 全局节对象句柄 NTSTATUS MapPhysicalMemory(IN PHYSICAL_ADDRESS PhysicalAddress, OUT PVOID* MappedVa) { SIZE_T size = PAGE_SIZE; NTSTATUS status = STATUS_SUCCESS; // 第一次调用时打开节对象 if (g_hSection == NULL) { UNICODE_STRING physName; RtlInitUnicodeString(&physName, L"\\Device\\PhysicalMemory"); OBJECT_ATTRIBUTES oa; InitializeObjectAttributes(&oa, &physName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenSection(&g_hSection, SECTION_ALL_ACCESS, &oa); if (!NT_SUCCESS(status)) { DbgPrint("ZwOpenSection failed: 0x%X\n", status); return status; } } // 映射物理内存 PHYSICAL_ADDRESS baseAddress = PhysicalAddress; status = ZwMapViewOfSection( g_hSection, NtCurrentProcess(), MappedVa, 0L, size, &baseAddress, &size, ViewUnmap, 0, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { DbgPrint("ZwMapViewOfSection failed: 0x%X\n", status); } return status; } VOID UnmapPhysicalMemory(PVOID MappedVa) { if (MappedVa) { ZwUnmapViewOfSection(NtCurrentProcess(), MappedVa); } } NTSTATUS InitHookWin10(IN ULONG_PTR TargetVa, IN HANDLE Pid, IN ULONG_PTR Offset) { PEPROCESS Process = NULL; PHYSICAL_ADDRESS Cr3Pa = { 0 }; PVOID Cr3Va = NULL; HOOK_CONTEXT ctx = { 0 }; NTSTATUS status; // 1. 获取目标进程CR3 status = PsLookupProcessByProcessId(Pid, &Process); if (!NT_SUCCESS(status)) { DbgPrint("PsLookupProcessByProcessId failed: 0x%X\n", status); return status; } // 获取进程CR3 (Win10 10240偏移为0x28) Cr3Pa.QuadPart = *(ULONG_PTR*)((PUCHAR)Process + 0x28) & ~0xF; ObDereferenceObject(Process); // 2. 映射CR3 status = MapPhysicalMemory(Cr3Pa, &Cr3Va); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for CR3 failed: 0x%X\n", status); return status; } // 3. 计算页表索引 (x64四级页表) ULONG Pml4Index = (TargetVa >> 39) & 0x1FF; ULONG PdptIndex = (TargetVa >> 30) & 0x1FF; ULONG PdIndex = (TargetVa >> 21) & 0x1FF; ULONG PtIndex = (TargetVa >> 12) & 0x1FF; // 4. 复制并修改PML4E (实际为PDPT) PHYSICAL_ADDRESS LowAddr = { 0 }; PHYSICAL_ADDRESS HighAddr = { 0 }; HighAddr.QuadPart = ~0ULL; // 修复:正确的初始化 ctx.NewPages[0] = MmAllocateContiguousMemorySpecifyCache( PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmCached); if (ctx.NewPages[0] == NULL) { DbgPrint("MmAllocateContiguousMemorySpecifyCache for PPE failed\n"); UnmapPhysicalMemory(Cr3Va); return STATUS_INSUFFICIENT_RESOURCES; } PHARDWARE_PTE OrigPml4e = (PHARDWARE_PTE)((PUCHAR)Cr3Va + Pml4Index * sizeof(ULONG64)); PHYSICAL_ADDRESS PdptPa = { 0 }; PdptPa.QuadPart = OrigPml4e->PageFrameNumber << 12; PVOID PdptVa = NULL; status = MapPhysicalMemory(PdptPa, &PdptVa); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for PDPT failed: 0x%X\n", status); MmFreeContiguousMemory(ctx.NewPages[0]); UnmapPhysicalMemory(Cr3Va); return status; } RtlCopyMemory(ctx.NewPages[0], PdptVa, PAGE_SIZE); // 复制原始PDPT UnmapPhysicalMemory(PdptVa); // 5. 处理PDPTE (实际为PD) ctx.NewPages[1] = MmAllocateContiguousMemorySpecifyCache( PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmCached); if (ctx.NewPages[1] == NULL) { DbgPrint("MmAllocateContiguousMemorySpecifyCache for PDE failed\n"); MmFreeContiguousMemory(ctx.NewPages[0]); UnmapPhysicalMemory(Cr3Va); return STATUS_INSUFFICIENT_RESOURCES; } PHARDWARE_PTE OrigPdpte = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[0] + PdptIndex * sizeof(ULONG64)); PHYSICAL_ADDRESS PdPa = { 0 }; PdPa.QuadPart = OrigPdpte->PageFrameNumber << 12; PVOID PdVa = NULL; status = MapPhysicalMemory(PdPa, &PdVa); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for PD failed: 0x%X\n", status); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); UnmapPhysicalMemory(Cr3Va); return status; } RtlCopyMemory(ctx.NewPages[1], PdVa, PAGE_SIZE); // 复制原始PD UnmapPhysicalMemory(PdVa); // 6. 检查大页 PHARDWARE_PTE OrigPde = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[1] + PdIndex * sizeof(ULONG64)); ctx.IsLargePage = OrigPde->LargePage; if (ctx.IsLargePage) { // 处理2MB大页 ULONG_PTR LargePageBase = TargetVa & ~0x1FFFFF; PHYSICAL_ADDRESS DataPa = { 0 }; DataPa.QuadPart = OrigPde->PageFrameNumber << 12; // 分配2MB对齐内存 PVOID LargePageBuf = MmAllocateContiguousMemorySpecifyCache( 0x200000, LowAddr, HighAddr, LowAddr, MmCached); if (LargePageBuf == NULL) { DbgPrint("Failed to allocate 2MB contiguous memory\n"); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); UnmapPhysicalMemory(Cr3Va); return STATUS_INSUFFICIENT_RESOURCES; } PHYSICAL_ADDRESS NewDataPa = MmGetPhysicalAddress(LargePageBuf); // 复制原始数据 PVOID OrigDataVa = NULL; status = MapPhysicalMemory(DataPa, &OrigDataVa); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for large page data failed: 0x%X\n", status); MmFreeContiguousMemory(LargePageBuf); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); UnmapPhysicalMemory(Cr3Va); return status; } RtlCopyMemory(LargePageBuf, OrigDataVa, 0x200000); UnmapPhysicalMemory(OrigDataVa); // 修改新页面指令 PUCHAR HookLoc = (PUCHAR)LargePageBuf + (TargetVa & 0x1FFFFF) + Offset; HookLoc[0] = 0x90; // NOP HookLoc[1] = 0x90; // NOP HookLoc[2] = 0xC3; // RET // 更新PDE OrigPde = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[1] + PdIndex * sizeof(ULONG64)); OrigPde->PageFrameNumber = NewDataPa.QuadPart >> 12; ctx.NewPages[3] = LargePageBuf; } else { // 处理4KB页 ctx.NewPages[2] = MmAllocateContiguousMemorySpecifyCache( PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmCached); if (ctx.NewPages[2] == NULL) { DbgPrint("MmAllocateContiguousMemorySpecifyCache for PTE failed\n"); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); UnmapPhysicalMemory(Cr3Va); return STATUS_INSUFFICIENT_RESOURCES; } PHYSICAL_ADDRESS PtPa = { 0 }; PtPa.QuadPart = OrigPde->PageFrameNumber << 12; PVOID PtVa = NULL; status = MapPhysicalMemory(PtPa, &PtVa); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for PT failed: 0x%X\n", status); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); MmFreeContiguousMemory(ctx.NewPages[2]); UnmapPhysicalMemory(Cr3Va); return status; } RtlCopyMemory(ctx.NewPages[2], PtVa, PAGE_SIZE); // 复制原始PT UnmapPhysicalMemory(PtVa); // 处理PTE PHARDWARE_PTE OrigPte = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[2] + PtIndex * sizeof(ULONG64)); ctx.OriginalPTE = OrigPte->AsUINT64; // 使用联合体访问 PHYSICAL_ADDRESS DataPa = { 0 }; DataPa.QuadPart = OrigPte->PageFrameNumber << 12; // 分配新数据页 PVOID NewData = MmAllocateContiguousMemorySpecifyCache( PAGE_SIZE, LowAddr, HighAddr, LowAddr, MmCached); if (NewData == NULL) { DbgPrint("Failed to allocate data page\n"); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); MmFreeContiguousMemory(ctx.NewPages[2]); UnmapPhysicalMemory(Cr3Va); return STATUS_INSUFFICIENT_RESOURCES; } PHYSICAL_ADDRESS NewDataPa = MmGetPhysicalAddress(NewData); // 复制原始数据 PVOID OrigDataVa = NULL; status = MapPhysicalMemory(DataPa, &OrigDataVa); if (!NT_SUCCESS(status)) { DbgPrint("MapPhysicalMemory for data page failed: 0x%X\n", status); MmFreeContiguousMemory(NewData); MmFreeContiguousMemory(ctx.NewPages[0]); MmFreeContiguousMemory(ctx.NewPages[1]); MmFreeContiguousMemory(ctx.NewPages[2]); UnmapPhysicalMemory(Cr3Va); return status; } RtlCopyMemory(NewData, OrigDataVa, PAGE_SIZE); UnmapPhysicalMemory(OrigDataVa); // 修改新页面指令 PUCHAR HookLoc = (PUCHAR)NewData + (TargetVa & 0xFFF) + Offset; HookLoc[0] = 0x90; // NOP HookLoc[1] = 0x90; // NOP HookLoc[2] = 0xC3; // RET // 更新PTE OrigPte = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[2] + PtIndex * sizeof(ULONG64)); OrigPte->PageFrameNumber = NewDataPa.QuadPart >> 12; ctx.NewPages[3] = NewData; } // 7. 更新页表链 PHARDWARE_PTE NewPdpte = (PHARDWARE_PTE)((PUCHAR)ctx.NewPages[0] + PdptIndex * sizeof(ULONG64)); NewPdpte->PageFrameNumber = MmGetPhysicalAddress(ctx.NewPages[1]).QuadPart >> 12; PHARDWARE_PTE NewPml4e = (PHARDWARE_PTE)((PUCHAR)Cr3Va + Pml4Index * sizeof(ULONG64)); NewPml4e->PageFrameNumber = MmGetPhysicalAddress(ctx.NewPages[0]).QuadPart >> 12; // 8. 清理映射 UnmapPhysicalMemory(Cr3Va); // 保存上下文以便卸载(实际应保存到全局变量) // g_HookContext = ctx; return STATUS_SUCCESS; } // 驱动卸载时释放资源 VOID UninstallHook(PHOOK_CONTEXT ctx) { for (int i = 0; i < 4; i++) { if (ctx->NewPages[i] != NULL) { MmFreeContiguousMemory(ctx->NewPages[i]); ctx->NewPages[i] = NULL; } } } VOID DriverUnload(PDRIVER_OBJECT DriverObject) { HOOK_CONTEXT ctx = { 0 }; // 实际应从全局获取 UninstallHook(&ctx); if (g_hSection) { ZwClose(g_hSection); g_hSection = NULL; } DbgPrint("Driver unloaded\n"); } extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DriverObject->DriverUnload = DriverUnload; // 获取NtOpenProcess地址 UNICODE_STRING funcName = RTL_CONSTANT_STRING(L"NtOpenProcess"); ULONG_PTR funcAddr = (ULONG_PTR)MmGetSystemRoutineAddress(&funcName); if (funcAddr == 0) { DbgPrint("Failed to get NtOpenProcess address\n"); return STATUS_NOT_FOUND; } ULONG_PTR pageBase = funcAddr & ~0xFFF; ULONG_PTR offset = funcAddr & 0xFFF; // 假设目标进程PID为1234 return InitHookWin10(pageBase, (HANDLE)7880, offset); } 这个是什么错误导致的

大家在看

recommend-type

美敦力BIS监护仪串口通讯协议手册

Document Title: BIS, MONITORING SYSTEMS, SERIAL PORT TECHNICAL SPEC
recommend-type

Cisco Enterprise Print System-开源

一组使大量打印机的管理和支持变得更加容易的工具。
recommend-type

web仿淘宝项目

大一时团队做的一个仿淘宝的web项目,没有实现后台功能
recommend-type

只输入固定-vc实现windows多显示器编程的方法

P0.0 只输入固定 P0.1 P0CON.1 P0.2 P0CON.2 PORT_SET.PORT_REFEN P0.3 P0CON.3 自动“偷”从C2的交易应用程序在. PORT_SET.PORT_CLKEN PORT_SET.PORT_CLKOUT[0] P0.4 P0CON.4 C2调试的LED驱动器的时钟输入,如果作为 未启用. P0.5 PORT_CTRL.PORT_LED[1:0] 输出港口被迫为.阅读 实际LED驱动器的状态(开/关) 用户应阅读 RBIT_DATA.GPIO_LED_DRIVE 14只脚 不能用于在开发系统中,由于C2交易扰 乱输出. 参考区间的时钟频率 对抗 控制控制 评论评论 NVM的编程电压 VPP = 6.5 V 矩阵,和ROFF工业* PORT_CTRL 2 GPIO 1 矩阵,和ROFF工业* PORT_CTRL 3 参考 clk_ref GPIO 矩阵 4 C2DAT 产量 CLK_OUT GPIO 5 C2CLK LED驱动器 1 2 工业* PORT_CTRL 1 2 3 1 2 6 产量 CLK_OUT GPIO 1 2 1 1 1 PORT_SET.PORT_CLKEN PORT_SET.PORT_CLKOUT[1] P0.6 P0CON.6 P0.7 P0CON.7 P1.0 P1CON.0 P1.1 P1CON.1 7 8 9 GPIO GPIO GPIO 14只脚 14只脚 14只脚 *注:工业注:工业 代表“独立报”设置. “ 矩阵矩阵 and Roff 模式控制模拟垫电路. 116 修订版修订版1.0
recommend-type

小游戏源码-端午节龙舟大赛.rar

小游戏源码-端午节龙舟大赛.rar

最新推荐

recommend-type

【路径规划】基于ADMM求解时间窗车辆路径问题VRPTW附Matlab代码.rar

【路径规划】基于ADMM求解时间窗车辆路径问题VRPTW附Matlab代码
recommend-type

基于GTD的项目管理系统。.zip

基于GTD的项目管理系统。
recommend-type

2022年园区大数据治理解决方案(1).pptx

2022年园区大数据治理解决方案(1).pptx
recommend-type

船舶通信与沟通(共29张)(1).pptx

船舶通信与沟通(共29张)(1).pptx
recommend-type

【风电预测】基于BiTCN-LSTM的风电功率预测研究附Matlab代码.rar

2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
recommend-type

获取本机IP地址的程序源码分析

从给定文件信息中我们可以提取出的关键知识点是“取本机IP”的实现方法以及与之相关的编程技术和源代码。在当今的信息技术领域中,获取本机IP地址是一项基本技能,广泛应用于网络通信类的软件开发中,下面将详细介绍这一知识点。 首先,获取本机IP地址通常需要依赖于编程语言和操作系统的API。不同的操作系统提供了不同的方法来获取IP地址。在Windows操作系统中,可以通过调用Windows API中的GetAdaptersInfo()或GetAdaptersAddresses()函数来获取网络适配器信息,进而得到IP地址。在类Unix操作系统中,可以通过读取/proc/net或是使用系统命令ifconfig、ip等来获取网络接口信息。 在程序设计过程中,获取本机IP地址的源程序通常会用到网络编程的知识,比如套接字编程(Socket Programming)。网络编程允许程序之间进行通信,套接字则是在网络通信过程中用于发送和接收数据的接口。在许多高级语言中,如Python、Java、C#等,都提供了内置的网络库和类来简化网络编程的工作。 在网络通信类中,IP地址是区分不同网络节点的重要标识,它是由IP协议规定的,用于在网络中唯一标识一个网络接口。IP地址可以是IPv4,也可以是较新的IPv6。IPv4地址由32位二进制数表示,通常分为四部分,每部分由8位构成,并以点分隔,如192.168.1.1。IPv6地址则由128位二进制数表示,其表示方法与IPv4有所不同,以冒号分隔的8组16进制数表示,如2001:0db8:85a3:0000:0000:8a2e:0370:7334。 当编写源代码以获取本机IP地址时,通常涉及到以下几个步骤: 1. 选择合适的编程语言和相关库。 2. 根据目标操作系统的API或系统命令获取网络接口信息。 3. 分析网络接口信息,提取出IP地址。 4. 将提取的IP地址转换成适合程序内部使用的格式。 5. 在程序中提供相应功能,如显示IP地址或用于网络通信。 例如,在Python中,可以使用内置的socket库来获取本机IP地址。一个简单的示例代码如下: ```python import socket # 获取主机名 hostname = socket.gethostname() # 获取本机IP local_ip = socket.gethostbyname(hostname) print("本机IP地址是:", local_ip) ``` 在实际应用中,获取本机IP地址通常是为了实现网络通信功能,例如建立客户端与服务器的连接,或者是在开发涉及到IP地址的其他功能时使用。 关于文件名称“getIP”,这是一个自解释的文件名,明显表示该文件或程序的作用是获取本机的IP地址。从标签“控件 源码 网络通信类 资源”中我们可以看出,这个文件很可能是一个可以嵌入其他软件中的代码片段,用以实现网络通信功能的一部分,具有较高的灵活性和重用性。 综上所述,获取本机IP地址是一个涉及到操作系统API、网络编程以及特定编程语言知识的技能。它不仅需要对编程语言提供的库函数有深入的理解,还要对操作系统的网络配置和IP协议有足够的认识。通过阅读和分析相关的源代码,如“getIP”,可以加深对网络编程实现细节的理解,并能够在实际开发中快速地应用这一技术。
recommend-type

【权威指南】:Win11笔记本上RTX4080驱动的安装与调试秘籍

# 1. Win11笔记本与RTX4080显卡介绍 随着技术的不断发展,笔记本电脑已不再是仅仅满足办公需求的移动设备,而是逐渐成为可以胜任复杂图形处理和游戏任务的强大工具。微软推出的Windows 11操作系统,以其全新的用户界面和改进的系统性能,为用户提供了更为流畅的操作体验。而在硬件方面,NVIDIA的RTX 4080显卡以其卓越的图形处理能力和AI支持,为笔记本电脑带来了前所未有的性能提升。本章节将带您初步了解Windows 11笔记本与NVIDIA RTX 4080显卡的基础信息,为进一步深入探讨它们的优化和调试技巧奠定基础。 ## 1.1 Win11笔记本的优势 Windows
recommend-type

windows环境举例

<think>好的,用户现在想在Windows环境下创建C函数库,需要具体的方法和示例代码。我需要结合之前的回答和用户提供的引用内容来给出合适的指导。 首先回顾之前的回答,用户已经了解了在Linux下创建静态库和动态库的方法,现在需要切换到Windows环境。根据引用[2],Windows下的C标准库和动态链接库的处理与Linux不同,比如使用dlfcn.h在Linux,而Windows可能需要其他方式。另外,引用[1]提到了在Windows下配置gcc环境(MinGW-w64),这可能是一个关键点,因为用户可能需要使用MinGW来编译库。 用户提供的引用[3]提到了使用MSVC编译器,这
recommend-type

QQ自动发送/回复系统源代码开放

根据提供的文件信息,我们可以了解到以下几点关键的知识点: ### 标题:“qqhelp” 1. **项目类型**: 标题“qqhelp”暗示这是一个与QQ相关的帮助工具或项目。QQ是中国流行的即时通讯软件,因此这个标题表明项目可能提供了对QQ客户端功能的辅助或扩展。 2. **用途**: “help”表明此项目的主要目的是提供帮助或解决问题。由于它提到了QQ,并且涉及“autosend/reply”功能,我们可以推测该项目可能用于自动化发送消息回复,或提供某种形式的自动回复机制。 ### 描述:“I put it to my web, but nobody sendmessage to got the source, now I public it. it supply qq,ticq autosend/reply ,full sourcecode use it as you like” 1. **发布情况**: 描述提到该项目原先被放置在某人的网站上,并且没有收到请求源代码的消息。这可能意味着项目不够知名或者需求不高。现在作者决定公开发布,这可能是因为希望项目能够被更多人了解和使用,或是出于开源共享的精神。 2. **功能特性**: 提到的“autosend/reply”表明该项目能够实现自动发送和回复消息。这种功能对于需要进行批量或定时消息沟通的应用场景非常有用,例如客户服务、自动化的营销通知等。 3. **代码可用性**: 作者指出提供了“full sourcecode”,意味着源代码完全开放,用户可以自由使用,无论是查看、学习还是修改,用户都有很大的灵活性。这对于希望学习编程或者有特定需求的开发者来说是一个很大的优势。 ### 标签:“综合系统类” 1. **项目分类**: 标签“综合系统类”表明这个项目可能是一个多功能的集成系统,它可能不仅限于QQ相关的功能,还可能包含了其他类型的综合服务或特性。 2. **技术范畴**: 这个标签可能表明该项目的技术实现比较全面,可能涉及到了多个技术栈或者系统集成的知识点,例如消息处理、网络编程、自动化处理等。 ### 压缩包子文件的文件名称列表: 1. **Unit1.dfm**: 这是一个Delphi或Object Pascal语言的窗体定义文件,用于定义应用程序中的用户界面布局。DFM文件通常用于存储组件的属性和位置信息,使得开发者可以快速地进行用户界面的设计和调整。 2. **qqhelp.dpr**: DPR是Delphi项目文件的扩展名,包含了Delphi项目的核心设置,如程序入口、使用的单元(Units)等。这个文件是编译和构建Delphi项目的起点,它能够帮助开发者了解项目的组织结构和编译指令。 3. **Unit1.pas**: PAS是Delphi或Object Pascal语言的源代码文件。这个文件可能包含了与QQ帮助工具相关的核心逻辑代码,例如处理自动发送和回复消息的算法等。 4. **readme.txt**: 这是一个常见的文本文件,包含项目的基本说明和使用指导,帮助用户了解如何获取、安装、运行和定制该项目。README文件通常是用户与项目首次交互时首先阅读的文件,因此它对于一个开源项目的用户友好度有着重要影响。 通过以上分析,我们可以看出“qqhelp”项目是一个针对QQ通讯工具的自动化消息发送与回复的辅助工具。项目包含完整的源代码,用户可以根据自己的需要进行查看、修改和使用。它可能包含Delphi语言编写的窗体界面和后端逻辑代码,具有一定的综合系统特性。项目作者出于某种原因将其开源,希望能够得到更广泛的使用和反馈。
recommend-type

【7步打造Win11深度学习利器】:Tensorflow-GPU与RTX4080终极优化指南

# 1. 深度学习与Windows 11的融合 在人工智能时代,深度学习已渗透到生活的方方面面,而Windows 11作为最新一代的操作系统,为深度学习提供了一个高效的工作平台。本章节将探讨深度学习技术如何与Windows 11系统融合,以及这一