You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何可靠识别触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:45:14