EnumDeviceDrivers可获取内核驱动基址列表,需先调用两次以确定缓冲区大小,再配合GetDeviceDriverBaseNameA解析短名,不可用GetModuleFileNameA。

用 EnumDeviceDrivers 获取内核模块基址列表
Windows 内核驱动(.sys)在加载后会注册为“设备驱动程序模块”,但注意:这不是用户态服务列表,也不是 sc query 输出的内容。真正能拿到驱动模块原始加载信息的 API 是 EnumDeviceDrivers,它返回的是每个驱动的基地址(PVOID),不是名字。你必须配合 GetDeviceDriverBaseNameA 或 GetDeviceDriverFileNameA 才能还原名称或路径。
常见错误是直接对地址调用 GetModuleFileNameA —— 它只对用户态模块有效,对内核驱动会失败并返回 0。
- 必须启用
SE_DEBUG_NAME权限(调用OpenProcessToken+AdjustTokenPrivileges),否则EnumDeviceDrivers可能只返回部分结果或失败 - 数组大小需先用
EnumDeviceDrivers(NULL, 0, &cbNeeded)探测,否则容易缓冲区溢出 - 返回的地址是内核 VA,不能解引用;仅可用于后续名称查询
解析驱动名时优先用 GetDeviceDriverBaseNameA 而非 GetDeviceDriverFileNameA
GetDeviceDriverBaseNameA 返回类似 dxgkrnl.sys 的短名,稳定且无需管理员权限即可调用;而 GetDeviceDriverFileNameA 尝试返回完整路径(如 \SystemRoot\system32\drivers\dxgkrnl.sys),但在某些系统版本(尤其是 Win10 1903+)上对非微软签名驱动常返回空字符串或乱码。
如果你只需要识别驱动类型(如过滤 *nv*、*atikmdag*),用 BaseName 更可靠。
立即学习“C++免费学习笔记(深入)”;
在 Windows 上执行终端命令,或对比 Windows 与 Linux 的 Shell 语法时使用。建议先检测当前 Shell 是 PowerShell 还是 cmd.exe,再给出相应命令……
- 传入的地址必须来自
EnumDeviceDrivers的输出,其他地址会导致未定义行为 - 输出缓冲区至少 256 字节,否则截断风险高
- 返回字符串不含前导反斜杠或盘符,和注册表
HKLM\SYSTEM\CurrentControlSet\Services\{name}\ImagePath的值格式不同
绕过 UAC 限制读取完整驱动信息的替代路径
如果目标是获取更详细的元数据(如启动类型、服务状态、签名者),EnumDeviceDrivers 就不够用了——它不提供这些。此时得转向服务控制管理器(SCM)接口,但要注意:很多驱动是以 SERVICE_KERNEL_DRIVER 类型注册为 Windows 服务的,可以用 EnumServicesStatusEx 枚举。
关键点在于筛选条件:dwServiceType = SERVICE_KERNEL_DRIVER 且 dwServiceState = SERVICE_STATE_ALL。这比解析 sc query type= driver 的文本输出更稳定,也避免了 PowerShell 的 AMSI 检测干扰。
- 需要
SC_MANAGER_ENUMERATE_SERVICE权限,普通用户默认有,但沙箱或受限账户可能被禁用 - 返回的
ENUM_SERVICE_STATUS_PROCESS中lpDisplayName是服务显示名,lpServiceName才对应注册表键名,也是QueryServiceConfig的输入 - 调用
QueryServiceConfig后可拿到lpBinaryPathName,这才是驱动文件的真实磁盘路径
签名与可信度验证必须调用 WinVerifyTrust 而非检查扩展名
仅靠文件名或 ImagePath 判断驱动是否“合法”极不可靠——攻击者可伪造 mydrv.sys 并填入注册表。真实校验必须走 Windows 签名验证 API:WinVerifyTrust 配合 WINTRUST_DATA 和 WINTRUST_FILE_INFO。
典型误操作是直接用 GetFileVersionInfo 查版本字段,那只是资源节内容,完全可被篡改。
- 必须以
hFile方式打开驱动文件(GENERIC_READ+FILE_SHARE_READ),不能传路径字符串给WinVerifyTrust - 返回
ERROR_SUCCESS仅表示签名结构有效;要确认是否由 Microsoft 或 WHQL 签发,需进一步解析WINTRUST_CERTIFICATE_INFO或调用CertGetNameString - 无网络时,
WinVerifyTrust仍可验证本地证书链,但 OCSP/CRL 检查会超时,默认策略下可能降级为“未知发布者”
驱动加载列表本身不包含签名状态字段,所有可信判断都必须额外做文件级验证——这点容易被忽略,尤其在自动化扫描场景中。


















