windows prefetch文件位于c:\windows\prefetch\,以“程序名-哈希.pf”命名,是头部含“scca”标识的二进制文件;执行次数(runcount)在v17格式中位于偏移0x84、v11中位于0x74,占4字节小端序,需校验版本后按偏移提取并转换字节序。

Prefetch文件在哪、长什么样、能不能直接读
Windows Prefetch文件(.pf)存放在 C:\Windows\Prefetch\,比如 SVCHOST.EXE-2A8F391D.pf。它不是文本,是二进制格式,微软未公开完整规范,但头部结构相对稳定——前4字节固定为 "SCCA"(大端),后面跟着版本号(常见 0x11 或 0x17)、执行次数字段(32位整数)、最后运行时间等。不能用 fstream::getline() 或 std::string 直接解析,必须按偏移+类型逐字段读取。
执行次数字段在什么位置、怎么提取
对于 v17(Windows 10/11 常见)格式,执行次数位于偏移 0x84 处,占4字节,小端序;v11(Win7)则在 0x74。注意:该字段是累计执行次数(RunCount),不是启动次数或服务调用次数,且仅当系统启用Prefetch(默认开启)且程序被多次执行后才会递增。
实操建议:
- 先用
ifstream.read()读取至少0x90字节到缓冲区 - 检查前4字节是否等于
"SCCA"(注意字节顺序,别用strcmp) - 读取第5字节判断版本:
buffer[4]==0x17→ v17;==0x11→ v11 - 根据版本计算偏移,用
memcpy或指针强转提取uint32_t,再用ntohl()或手动翻转字节序(小端→主机序)
读取时容易崩的几个点
直接 new char[1024] 然后 read() 不校验长度?大概率越界访问。Prefetch 文件大小不固定(从几KB到几百KB),但关键字段都在前段;部分文件可能被系统锁定(如正在使用的 CSRSS.EXE-*.pf),ifstream 构造失败会静默失败,必须检查 is_open() 和 good()。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见错误现象:
-
RunCount读出来是极大值(如0xdeadbeef)→ 没做字节序转换,直接当大端用了 - 读出
0→ 偏移算错,或文件根本没执行过(首次运行后才生成,第二次才写入计数) - 程序崩溃 → 没检查文件是否可读,或读取长度不足就访问
buffer[0x84] - 不同Windows版本结果不一致 → 混用了 v11/v17 偏移,没校验版本字节
一个最小可用的C++读取片段(仅提取 RunCount)
#include <fstream>
#include <cstdint>
#include <iostream><p>uint32_t getPrefetchRunCount(const char* path) {
std::ifstream f(path, std::ios::binary);
if (!f.is_open()) return 0;</p>
<pre class="brush:php;toolbar:false;">uint8_t hdr[0x90] = {};
f.read(reinterpret_cast<char*>(hdr), sizeof(hdr));
if (f.gcount() < 5) return 0;
if (hdr[0]!='S' || hdr[1]!='C' || hdr[2]!='C' || hdr[3]!='A') return 0;
uint8_t version = hdr[4];
uint32_t offset = (version == 0x17) ? 0x84 : (version == 0x11) ? 0x74 : 0;
if (!offset || f.gcount() <= offset + 4) return 0;
uint32_t runCount;
std::memcpy(&runCount, hdr + offset, 4);
// 小端转主机序
runCount = (runCount & 0xFF) << 24 |
((runCount >> 8) & 0xFF) << 16 |
((runCount >> 16) & 0xFF) << 8 |
(runCount >> 24);
return runCount;
}
这个函数不处理Unicode路径、不验证签名完整性、也不解析模块列表——那些字段偏移更易变,且和执行次数无关。真正想稳定获取 RunCount,重点就三件事:确认 "SCCA"、读对版本、按版本选对偏移、正确翻字节序。其它字段留到真需要时再深挖。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










