windows 驱动实例分析系列: HidHide驱动分析-HidHideClient 篇(中)

HidHide 驱动分析 - HidHideClient 篇(中):白名单对话框(WhitelistDlg)

一、白名单对话框的功能定位

CWhitelistDlg 是主对话框中的应用标签页,负责管理白名单(Whitelist) ------即允许访问隐藏设备的应用程序列表。用户可以通过"插入"按钮选择可执行文件,或直接通过拖放(Drag & Drop)将 .exe.com.bin 文件拖入列表,从而实现快速添加。该对话框同时提供"删除"按钮移除选中条目,以及"反转白名单"复选框用于切换逻辑模式。

二、类结构与成员变量

cpp 复制代码
class CWhitelistDlg : public CDialogEx, public HidHide::IDropTarget {
    CHidHideClientDlg& m_HidHideClientDlg;          // 父对话框引用
    HidHide::FullImageNames m_DropTargetFullImageNames; // 拖放时缓存的路径列表
    CListBox m_Whitelist;                           // 显示白名单的列表框
    CStatic m_Guidance;                             // 提示标签
    CButton m_Insert;                               // 插入按钮
    CButton m_Delete;                               // 删除按钮
    CButton m_Inverse;                              // 反转复选框
    // 方法:OnDragEnter, OnDragOver, OnDropEx, OnBnClicked... 等
};

HidHide::FullImageNamesstd::set<std::filesystem::path> 的类型别名,确保白名单中无重复条目。

三、初始化与资源加载(OnInitDialog)

cpp 复制代码
m_Guidance.SetWindowTextW(HidHide::StringTable(IDS_STATIC_WHITELIST_GUIDANCE).c_str());
m_Insert.SetWindowTextW(HidHide::StringTable(IDS_BUTTON_WHITELIST_INSERT).c_str());
m_Delete.SetWindowTextW(HidHide::StringTable(IDS_BUTTON_WHITELIST_DELETE).c_str());
m_Inverse.SetWindowTextW(HidHide::StringTable(IDS_CHECK_WHITELIST_INVERSE).c_str());
m_Inverse.SetCheck(FilterDriverProxy().GetInverse() ? BST_CHECKED : BST_UNCHECKED);

所有标签从字符串表资源加载,支持本地化。反转复选框的初始状态从驱动读取,保持与内核一致。

四、列表内容的刷新(Refresh 与 OnUserMessageRefresh)

由于设备或进程状态可能动态变化(如白名单被外部程序修改),Refresh 方法通过 PostMessage(WM_USER_CM_NOTIFICATION_REFRESH) 异步刷新 UI,避免在敏感的窗口消息处理中阻塞。

OnUserMessageRefresh 执行实际刷新逻辑:

cpp 复制代码
m_Whitelist.ResetContent();
m_Whitelist.SetSel(-1, FALSE);
for (auto const& fullImageName : FilterDriverProxy().GetWhitelist()) {
    auto const index = m_Whitelist.AddString(fullImageName.c_str());
    // 检查文件是否存在,若不存在则高亮(选中)提示用户
    auto const exists = std::filesystem::exists(HidHide::FullImageNameToFileName(fullImageName));
    if (!exists) m_Whitelist.SetSel(index, TRUE);
}
m_Whitelist.SetFocus();

高亮不存在的文件条目,帮助用户识别已失效的应用路径,及时清理。

五、插入操作(OnBnClickedButtonWhitelistInsert)

  1. 清除当前列表框的选择状态。
  2. 使用 CFileDialog 打开文件选择对话框,过滤条件为可执行文件(.exe, .com, .bin)。
  3. 用户选择文件后,通过 HidHide::FileNameToFullImageName 将逻辑盘符路径转换为 NT 设备路径(如 \Device\HarddiskVolume1\...),这是驱动白名单所需的格式。
  4. 遍历现有列表,防止重复添加。
  5. 调用 m_Whitelist.AddString 添加到列表框,并通过 FilterDriverProxy().SetWhitelist(ListBoxToPathSet(m_Whitelist)) 同步到驱动。

关键函数 FileNameToFullImageName 的实现原理 :通过 GetVolumeNameForVolumeMountPointQueryDosDeviceW 建立逻辑盘符到设备名称的映射,拼接出完整设备路径。这确保了即使盘符在重启后改变,白名单依然能精准匹配。

六、删除操作(OnBnClickedButtonWhitelistDelete)

  1. 调用 m_Whitelist.GetSelCount() 获取选中的条目数量,并通过 GetSelItems 获取所有选中索引。
  2. 从后往前遍历索引,逐个调用 DeleteString 删除(从后往前避免索引变化影响)。
  3. 更新后的列表通过 SetWhitelist 同步到驱动。

七、拖放支持(IDropTarget 接口实现)

7.1 OnDragEnter:准入判断

当用户拖拽文件进入窗口时,OnDragEnter 首先提取拖拽的文件列表(通过 HidHide::DragTargetFileNames(pDataObject)),然后遍历检查:

  • 文件扩展名是否为 .exe.com.bin
  • 文件是否能成功转换为全路径(FileNameToFullImageName 非空)。

若全部满足,则将转换后的路径存入 m_DropTargetFullImageNames,并返回 DROPEFFECT_COPY;否则返回 DROPEFFECT_NONE,阻止拖放。

7.2 OnDragOver:实时反馈

在拖拽过程中,OnDragOver 检查鼠标位置是否位于列表框区域内(MousePointerAtWhitelist),同时确认按键状态符合复制操作(左键 + 无 Ctrl/Shift/Alt)。只有满足条件时才显示"可放置"光标,提供清晰的交互反馈。

7.3 OnDropEx:执行放置

当用户释放鼠标时,OnDropEx 执行最终添加逻辑:

cpp 复制代码
auto dirty = false;
auto whitelist = FilterDriverProxy().GetWhitelist();
for (auto const& fullImageName : m_DropTargetFullImageNames) {
    if (whitelist.emplace(fullImageName).second) dirty = true;
}
if (dirty) {
    FilterDriverProxy().SetWhitelist(whitelist);
    Refresh();
}
return DROPEFFECT_COPY;

利用 std::set::emplace 的返回值判断是否新增了条目,避免不必要的驱动写入。

八、反转复选框(OnBnClickedCheckInverse)

cpp 复制代码
FilterDriverProxy().SetInverse(0 != (m_Inverse.GetCheck() & BST_CHECKED));

立即将反转状态同步到驱动,无需重启。

九、错误处理与异常安全

所有 UI 操作均被 try-catch 包裹(在消息响应函数中由 MFC 顶层捕获,但代码中显式使用 THROW_WIN32 抛出),异常信息通过全局异常处理机制向用户展示。列表框操作(如 AddString)若返回 LB_ERRLB_ERRSPACE,会抛出异常,避免静默失败。

相关推荐
我是Superman丶13 小时前
Arduino IDE 安装教程:Windows/macOS/Linux 开发环境搭建
ide·windows·macos
辻弋20113 小时前
自动检测硬件生成驱动清单、实时监控FPS、120秒性能记录——30+项优化模块化开关,所有改动可精确复原
服务器·windows·游戏引擎·电脑·开源软件
江湖人称菠萝包13 小时前
【Windows】《深入浅出Windows API程序设计:编程基础篇》笔记-Chapter8-子窗口控件
windows·笔记
其实防守也摸鱼15 小时前
OpenClaw Windows 踩坑实战指南
运维·服务器·数据库·windows·github·copilot
佳&弥20 小时前
后渗透痕迹清理
服务器·windows·web安全·网络安全
MSTcheng.20 小时前
【Linux学习】Linux学习第四弹——Linux基本指令3
linux·windows·学习·操作系统·指令
霸道流氓气质21 小时前
MyBatis 与 SQL 层面关键技术详解
windows·sql·mybatis
一直走下去-明1 天前
在 Windows 上安装 uv
windows·uv
Lost of 程序猿1 天前
C# 12 / .NET 9 新特性机制深度:编译器替你写了什么,哪些糖吃下去会出事
windows·c#·.net