User Assist 注册表项:它到底是什么,存了什么?

Windows 系统为了提升用户体验,会记录你最近打开的程序,这就是 User Assist 注册表项存在的意义。它本质上是一个“行为记录器”,专门跟踪你点击过的快捷方式、可执行文件、甚至文档。这些数据并不是直接明文存储的,而是经过了一套加密流程:先对原始字符串做 ROT13 加密,然后再进行 Base64 编码(部分键值里还夹杂着时间戳和计数器)。这些数据的具体位置在:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist,下面还有多个子键,每个子键对应一个 GUID,比如 {CEBFF5CD-ACE2-4F4A-98E4-48C232D70A1F}

需要注意的是,这些数据并非一成不变。不同版本的 Windows(比如 Win7、Win10、Win11)、不同的系统架构(x64 还是 WoW64)、甚至是否启用了“运行新实例”策略,都会影响数据的布局和可读性。更关键的是,默认权限下,普通进程想要读取这个路径,很可能直接触发 UAC 或者被 Windows Defender 拦下来——可不是“能打开就能读”那么简单。

用 RegQueryValueEx 读数据?先过这三道坎

很多人第一反应是直接调用 RegOpenKeyEx 加上 RegQueryValueEx,但结果往往是 ERROR_ACCESS_DENIED 或者返回空数据。为什么会这样?原因主要有三个:

实操中,有几个关键点:

解密 ROT13+Base64 数据:C++ 实现要点

User Assist 的数据结构其实很固定:前 4 字节是计数器(小端序),接下来 4 字节是最后执行时间(FILETIME 的低 32 位),再 4 字节是高 32 位,然后剩下的部分才是经过 ROT13 加密的 UTF-16 字符串。最后,整个结构(包括计数器和时间)再一起进行 Base64 编码。

一些常见的“坑”需要特别注意:

大致代码逻辑如下:

// 假设 raw_data 是 RegQueryValueEx 返回的 BYTE*,len 是长度
std::vector decoded = base64_decode(raw_data, len); // 自行实现或用 OpenSSL
if (decoded.size() < 16) return;

uint32_t count = *(uint32_t*)&decoded[0];
uint64_t ft = *(uint64_t*)&decoded[4]; // FILETIME 是 uint64_t

// 仅对 offset=16 之后的 UTF-16 字符做 ROT13
for (size_t i = 16; i + 1 < decoded.size(); i += 2) {
    BYTE lo = decoded[i];
    if (lo >= 'a' && lo <= 'z') decoded[i] = 'a' + (lo - 'a' + 13) % 26;
    else if (lo >= 'A' && lo <= 'Z') decoded[i] = 'A' + (lo - 'A' + 13) % 26;
}
// 然后 reinterpret_cast(&decoded[16]) 即可得原始程序名

权限与反检测:为什么你的程序一读就蓝/被杀

读取 User Assist 的难点,从来不是解密算法,而是系统是否允许你触碰那块内存。这里涉及到的安全问题很多:

实操建议:

c++如何读取Windows下的User Assist注册表记录【深度】

本文转载于:https://www.php.cn/faq/2313891.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。