当前位置: 首页 > news >正文

深入Winlogon:用C++和Detours库拦截Windows关机/重启的实战教程(含完整项目代码)

深入Winlogon:用C++和Detours库拦截Windows关机/重启的实战教程(含完整项目代码)

在Windows系统开发领域,掌握底层API拦截技术是进阶开发者的必备技能。本文将带领您从零开始构建一个完整的关机拦截工具,通过Detours库实现对ExitWindowsExInitiateShutdownW等关键API的挂钩,并提供可直接编译的Visual Studio项目代码。

1. Windows关机机制深度解析

Windows系统的关机流程是一个复杂的多进程协作过程。当用户触发关机操作时,系统会经历以下关键阶段:

  1. 用户界面层:Explorer.exe接收用户操作
  2. 会话管理层:Winlogon.exe协调关机流程
  3. 系统服务层:Wininit.exe执行最终关机操作

关键API调用链

// 用户层调用 ExitWindowsEx(dwFlags, dwReason); // 系统层调用 InitiateShutdownW(lpMachineName, lpMessage, dwGracePeriod, dwShutdownFlags, dwReason); // 内核层调用 NtShutdownSystem(dwAction);

不同Windows版本对关机流程的实现有显著差异:

Windows版本主要关机API会话隔离机制
Win7及之前ExitWindowsExSession 0隔离
Win8/8.1InitiateShutdownW增强型会话隔离
Win10/11RPC调用组合PPL进程保护

2. Detours库实战环境搭建

2.1 开发环境配置

  1. 安装Visual Studio 2019/2022(需勾选C++桌面开发组件)
  2. 通过NuGet安装Detours库:
Install-Package Detours -Version 4.0.1
  1. 创建Win32控制台应用程序项目,配置项目属性:
// 预处理器定义 WIN32_LEAN_AND_MEAN // 附加包含目录 $(SolutionDir)packages\Microsoft.Detours.4.0.1\lib\native\include // 附加库目录 $(SolutionDir)packages\Microsoft.Detours.4.0.1\lib\native\lib\x86

2.2 基础挂钩框架搭建

构建一个基本的DLL注入项目结构:

ShutdownInterceptor/ ├── ShutdownHook/ │ ├── ShutdownHook.cpp // 主挂钩逻辑 │ ├── ShutdownHook.def // 模块定义文件 │ └── ShutdownHook.vcxproj ├── Injector/ │ ├── Injector.cpp // DLL注入器 │ └── Injector.vcxproj └── ShutdownInterceptor.sln

关键代码结构

// 原始函数指针定义 typedef BOOL(WINAPI* TrueExitWindowsEx)(UINT, DWORD); // 钩子函数声明 BOOL WINAPI HookedExitWindowsEx(UINT uFlags, DWORD dwReason); // Detours事务管理 void StartHook(); void RemoveHook();

3. 核心API挂钩实现

3.1 ExitWindowsEx挂钩实现

针对Windows 7及以下系统的关键拦截代码:

BOOL WINAPI HookedExitWindowsEx(UINT uFlags, DWORD dwReason) { // 解析关机类型 const wchar_t* operation = L"未知操作"; switch(uFlags) { case EWX_LOGOFF: operation = L"注销"; break; case EWX_SHUTDOWN: operation = L"关机"; break; case EWX_REBOOT: operation = L"重启"; break; } // 显示拦截提示 MessageBoxW(NULL, L"系统关机操作已被拦截\n请保存工作后重试", L"关机拦截提示", MB_ICONWARNING | MB_OK); // 返回FALSE表示阻止关机 SetLastError(ERROR_CANCELLED); return FALSE; }

3.2 InitiateShutdownW挂钩实现

针对Windows 8/8.1系统的增强型拦截:

DWORD WINAPI HookedInitiateShutdownW( LPWSTR lpMachineName, LPWSTR lpMessage, DWORD dwGracePeriod, DWORD dwShutdownFlags, DWORD dwReason) { // 创建拦截日志 LogEvent(L"拦截到系统关机请求,标志位: 0x%X", dwShutdownFlags); // 终止LogonUI进程防止关机界面卡住 TerminateProcessByName(L"LogonUI.exe"); return ERROR_OPERATION_ABORTED; }

3.3 跨会话UI显示技术

由于Winlogon运行在Session 0隔离环境,常规MessageBox无法显示。需要使用WTSSendMessage实现跨会话弹窗:

void ShowSessionMessage(DWORD sessionId, const wchar_t* title, const wchar_t* message) { DWORD response; WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, sessionId, title, wcslen(title)*2, message, wcslen(message)*2, MB_ICONWARNING | MB_OK, 0, &response, TRUE); }

4. 高级技巧与系统适配

4.1 Windows版本检测与适配

enum WindowsVersion { WIN_UNSUPPORTED, WIN_7, WIN_8, WIN_10, WIN_11 }; WindowsVersion GetWindowsVersion() { OSVERSIONINFOEX osvi = { sizeof(OSVERSIONINFOEX) }; GetVersionEx((OSVERSIONINFO*)&osvi); if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) return WIN_7; if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) return WIN_8; if (osvi.dwMajorVersion == 10 && osvi.dwBuildNumber < 22000) return WIN_10; if (osvi.dwMajorVersion == 10 && osvi.dwBuildNumber >= 22000) return WIN_11; return WIN_UNSUPPORTED; }

4.2 PPL绕过技术(Win10/11)

对于受保护的Wininit进程,需要特殊处理:

bool BypassPPL(DWORD pid) { // 加载PPLKiller驱动 if (!LoadDriver("PPLKiller.sys")) { LogEvent(L"驱动加载失败"); return false; } // 通过IOCTL与驱动通信 HANDLE hDevice = CreateFile(L"\\\\.\\PPLKiller", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) { LogEvent(L"设备打开失败: %d", GetLastError()); return false; } DWORD bytesReturned; PPL_KILL_REQUEST request = { pid }; DeviceIoControl(hDevice, IOCTL_PPL_KILL, &request, sizeof(request), NULL, 0, &bytesReturned, NULL); CloseHandle(hDevice); return true; }

5. 完整项目代码结构

项目包含以下关键组件:

  1. 核心挂钩模块

    • API拦截实现
    • 错误处理机制
    • 日志记录系统
  2. 注入器工具

    • 进程注入功能
    • 权限提升处理
    • 命令行接口
  3. 测试应用程序

    • 模拟关机操作
    • 验证拦截效果
    • 系统兼容性测试

关键代码文件说明

文件功能
ShutdownHook.cpp主挂钩逻辑实现
Injector.cppDLL注入工具实现
SessionUtils.cpp会话管理相关功能
PPLBypass.cppPPL绕过实现
ShutdownInterceptor.slnVisual Studio解决方案文件

6. 实战调试技巧

6.1 调试挂钩DLL

  1. 使用DebugView捕获内核模式输出
  2. 配置Visual Studio远程调试
  3. 使用Process Explorer验证DLL注入

6.2 常见问题解决

问题1:挂钩后系统不稳定

解决方案:确保在Detours事务中正确处理线程状态

问题2:拦截无效

检查目标进程是否正确注入,使用API Monitor验证调用

问题3:跨会话UI不显示

确认WTSSendMessage调用参数正确,检查会话ID

7. 安全与稳定性考量

  1. 错误处理最佳实践
void SafeHookOperation() { __try { // 敏感操作代码 StartHook(); } __except(EXCEPTION_EXECUTE_HANDLER) { LogEvent(L"挂钩操作异常: 0x%X", GetExceptionCode()); } }
  1. 资源清理规范

    • 确保所有句柄正确关闭
    • 在DLL_PROCESS_DETACH中移除挂钩
    • 释放分配的临时内存
  2. 系统兼容性检查表

检查项Win7Win10Win11
ExitWindowsEx挂钩
InitiateShutdownW挂钩
PPL绕过不需要需要需要
会话隔离增强增强

(✓完全支持 △部分支持 ✗不支持)

8. 扩展应用场景

基于本技术的衍生应用:

  1. 企业数据保护:防止员工意外关机导致数据丢失
  2. 工业控制系统:确保关键操作完成前不中断
  3. 安全软件:拦截恶意关机行为
  4. 自动化测试:模拟各种关机场景

性能优化建议

  • 最小化挂钩函数中的操作
  • 避免在挂钩中调用可能被挂钩的API
  • 使用异步方式处理复杂逻辑

9. 完整代码示例

以下是关键挂钩实现的完整代码片段:

// ShutdownHook.h #pragma once #include <windows.h> #include <detours.h> typedef BOOL(WINAPI* TrueExitWindowsEx)(UINT, DWORD); typedef DWORD(WINAPI* TrueInitiateShutdownW)(LPWSTR, LPWSTR, DWORD, DWORD, DWORD); extern TrueExitWindowsEx OriginalExitWindowsEx; extern TrueInitiateShutdownW OriginalInitiateShutdownW; BOOL WINAPI HookedExitWindowsEx(UINT uFlags, DWORD dwReason); DWORD WINAPI HookedInitiateShutdownW(LPWSTR lpMachineName, LPWSTR lpMessage, DWORD dwGracePeriod, DWORD dwShutdownFlags, DWORD dwReason); void InstallHooks(); void RemoveHooks();
// ShutdownHook.cpp #include "ShutdownHook.h" #include <WtsApi32.h> #pragma comment(lib, "WtsApi32.lib") TrueExitWindowsEx OriginalExitWindowsEx = nullptr; TrueInitiateShutdownW OriginalInitiateShutdownW = nullptr; BOOL WINAPI HookedExitWindowsEx(UINT uFlags, DWORD dwReason) { // 详细实现参考前文 return FALSE; } DWORD WINAPI HookedInitiateShutdownW(LPWSTR lpMachineName, LPWSTR lpMessage, DWORD dwGracePeriod, DWORD dwShutdownFlags, DWORD dwReason) { // 详细实现参考前文 return ERROR_OPERATION_ABORTED; } void InstallHooks() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); OriginalExitWindowsEx = (TrueExitWindowsEx)DetourFindFunction("user32.dll", "ExitWindowsEx"); OriginalInitiateShutdownW = (TrueInitiateShutdownW)DetourFindFunction("advapi32.dll", "InitiateShutdownW"); DetourAttach(&(PVOID&)OriginalExitWindowsEx, HookedExitWindowsEx); DetourAttach(&(PVOID&)OriginalInitiateShutdownW, HookedInitiateShutdownW); DetourTransactionCommit(); } void RemoveHooks() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)OriginalExitWindowsEx, HookedExitWindowsEx); DetourDetach(&(PVOID&)OriginalInitiateShutdownW, HookedInitiateShutdownW); DetourTransactionCommit(); } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: InstallHooks(); break; case DLL_PROCESS_DETACH: RemoveHooks(); break; } return TRUE; }

10. 进阶开发建议

  1. 多层级拦截策略

    • 用户模式API挂钩
    • 内核模式过滤驱动
    • RPC调用拦截
  2. 智能拦截逻辑

bool ShouldBlockShutdown() { // 检查关键进程是否运行 if (IsProcessRunning(L"important_app.exe")) { return true; } // 检查网络传输状态 if (IsNetworkTransferActive()) { return true; } // 检查系统负载 if (GetSystemLoad() > 0.8) { return true; } return false; }
  1. 配置化管理
    • XML/JSON规则配置
    • 动态规则加载
    • 远程管理接口

在实际项目中,我们发现Windows 10 1809版本后对PPL的保护更加严格,需要结合多个技术点才能实现稳定拦截。建议开发者针对不同Windows版本编译不同的二进制,并在运行时动态选择挂钩策略。

http://www.rkmt.cn/news/1363076.html

相关文章:

  • STR91xFA Rev H内存验证错误解决方案
  • 2026年APP流量变现平台排行:开源广告SDK、微信小程序广告、聚合SDK广告、聚合广告联盟、APP变现、APP商业化变现选择指南 - 优质品牌商家
  • # 软考软件设计师 · 考前2天轻松复习与终极必背手册
  • # 软考软件设计师 · 考前3天终极实战全攻略
  • AI驱动的新闻编辑与调查:从信息聚合到智能洞察的系统设计
  • LPC2000复位行为解析与调试技巧
  • 神经形态光子计算与单通道压缩感知:重塑超高速机器视觉新范式
  • AI与PDCA循环融合:构建韧性医院物流系统的实践指南
  • 经济合同纠纷律师费用解析及合规律所参考指南:取保候审缓刑律师咨询/四川墨科律师事务所/律师费用收取标准/房产纠纷律师咨询/选择指南 - 优质品牌商家
  • ArcGIS新手别怕!用Union和字段计算器,5步搞定土地利用变化图斑分析
  • AI 安全与对齐:幻觉、偏见、可控性与可信 AI 构建
  • MacBook新手别慌!Final Cut Pro 10.6.5保姆级教程:从导入素材到导出网课视频全流程
  • 手把手教你用udev规则在统信UOS上灵活管控USB设备(允许特定U盘/完全禁用)
  • 2026年专业电动车停车棚厂家TOP5实力排行:充电桩停车棚/厂区停车棚/小区停车棚/汽车停车棚/膜结构体育看台/选择指南 - 优质品牌商家
  • 多模态 AI 技术融合、核心架构与应用场景
  • 基于RNN的数字-实体关系抽取:从非结构化文本中提取结构化信息
  • 在VirtualBox里跑Win10,远程桌面连不上?试试这个被忽略的虚拟机专用配置
  • iPaaS平台全景扫描:五款主流集成产品解读
  • 别再乱拷贝.so文件了!详解银河麒麟下Qt程序、Qt Creator与输入法插件的“版本锁”问题
  • iPaaS集成平台:五大产品关键能力速查
  • 别再乱试了!这些看似“整蛊”的Windows批处理命令,分分钟让你的电脑报废
  • 银河麒麟+Qt5.9.9编译fcitx-qt5插件踩坑实录:手把手教你修改源码适配旧版Qt
  • Arm CoreSight调试工具CSAT与CSAT600对比解析
  • 改性阻燃ABS技术选型全解析:绍兴,四川,河南,阻燃abs颗粒/阻燃pvc颗粒/pvc塑胶颗粒/发泡pvc颗粒/选择指南 - 优质品牌商家
  • 实测对比:纯CPU环境下,llama.cpp在x86 Ubuntu与RISC-V Kylin上的推理速度与效果差异
  • 从方差分析到回归验证:F检验在机器学习特征工程中的3个实战应用
  • 在CentOS 7上编译安装OpenSSL 1.1.1,为Python 3.10的ssl模块铺平道路
  • 别再只跑代码了!用泰坦尼克号数据集,手把手教你从EDA到模型调优的完整数据分析实战
  • 视频融合与空间计算先行者
  • Evident方法论:用观察、假设、测试构建可复现的数据科学工作流