如何可靠识别触发UAC提示的实际程序路径?
问题:识别触发UAC提示的程序路径
我正在开发一个C++程序,使用Toolhelp32Snapshot API跟踪新启动的进程,相关代码片段如下:
std::optional<Process> getNewProcess() { static DWORD last_created_process_id = 0; DWORD newest_process_id = 0; FILETIME newest_creation_time = {}; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { return std::nullopt; } PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, &pe32)) { CloseHandle(hSnapshot); return std::nullopt; } do { HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); if (hProcess) { FILETIME creation_time, exit_time, kernel_time, user_time; if (GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time)) { if (CompareFileTime(&creation_time, &newest_creation_time) > 0) { newest_creation_time = creation_time; newest_process_id = pe32.th32ProcessID; } } CloseHandle(hProcess); } } while (Process32Next(hSnapshot, &pe32)); CloseHandle(hSnapshot); if (newest_process_id == 0) { return std::nullopt; } else { if (newest_process_id != last_created_process_id && newest_process_id != GetCurrentProcessId()) { last_created_process_id = newest_process_id; return Process(newest_process_id); } else { return std::nullopt; } } }
该代码在大多数情况下运行正常,但当启动的程序触发UAC提示时,代码检测到的是consent.exe和ctfmon.exe,而非触发UAC提示的实际程序。
我还尝试通过钩子监控CreateFile调用,从lpFileName中提取程序名称,但尚未成功实现。
请问是否存在可靠的方法来识别导致UAC提示的程序路径?
解决方案
1. 基于ETW(事件跟踪)捕获进程创建事件
ETW是Windows原生高效事件跟踪机制,订阅Microsoft-Windows-Kernel-Process提供者的ProcessStart事件,可精准捕获所有进程的创建细节,包括进程ID、父进程ID、可执行文件路径、创建时间戳。
对于UAC场景,触发提升的原始进程与consent.exe会形成事件链,可通过父进程ID关联两者,结合时间戳筛选出目标程序。实现思路:
- 用
OpenTrace初始化ETW会话 - 订阅
Microsoft-Windows-Kernel-Process的ProcessStart事件(事件ID为1) - 在事件回调中解析数据,提取进程路径、父进程ID等信息
- 捕获到
consent.exe启动事件时,通过父进程ID回溯到原始触发进程
2. 遍历进程父链并结合状态分析
触发UAC时,原始进程会进入等待状态(等待用户确认),consent.exe是其直接或间接子进程。关联步骤:
- 检测到
consent.exe启动时,通过Process32First/Process32Next或NtQueryInformationProcess获取其父进程ID - 回溯父进程链,排除
svchost.exe、explorer.exe等系统进程,找到最近创建的非系统进程 - 对比该进程与
consent.exe的创建时间,或用WaitForInputIdle判断是否处于等待状态,确认关联关系
3. 钩子权限提升相关API
UAC提升依赖CreateProcessWithTokenW、CreateProcessAsUserW、ShellExecuteExW这类API,钩子这些API可直接捕获目标程序路径:
- 使用Detours或MinHook等钩子库挂钩目标API
- 在钩子函数中提取
lpApplicationName或lpCommandLine参数,获取程序路径 - 注意处理32/64位进程兼容性,且程序需以管理员权限运行
4. 解析UAC相关事件日志
Windows会将UAC提升事件记录到安全日志(事件ID 4672或4688),可读取日志提取程序路径:
- 用
OpenEventLog或WMI查询Win32_NTLogEvent类,筛选安全日志中的UAC事件 - 解析事件中的进程信息字段,获取原始程序路径
内容的提问来源于stack exchange,提问作者Eviatar
相关产品推荐
相关产品推荐

