如何判断哪个进程在Windows中设置了高计时器分辨率

rus*_*tyx 8 windows windows-kernel

我的系统正在遭受高计时器分辨率(NtQueryTimerResolution返回0.5ms).

Maximum timer interval: 15.600 ms
Minimum timer interval: 0.500 ms
Current timer interval: 0.500 ms
Run Code Online (Sandbox Code Playgroud)

某些进程必须使用NtSetTimerResolution5000(0.5ms)的值调用,但如何确定哪一个?我看到英特尔有一个名为电池寿命分析器的工具,它显示每个进程的当前计时器分辨率,但该工具仅供英特尔合作伙伴使用.是否有其他工具或通过WinDbg查看它的方法?注意:似乎在启动时发生,因为设置断点不起作用(调试器启动时分辨率已经很高).

Rol*_*kas 3

到目前为止,我知道并使用过的唯一方法是注入到每个正在运行的进程中,并在该进程内部timeEndPeriod在这些分辨率的循环中调用每个增加的分辨率(值 1-15),并检查timeEndPeriod对当前分辨率的调用是否返回TIMERR_NOCANDOTIMERR_NOERROR(注意:这些返回值并不对应 false 和 true)。如果返回,TIMERR_NOERROR则得出程序正在使用该频率的结论,然后再次调用timeBeginPeriod以恢复程序请求的原始分辨率。

不幸的是,此方法无法检测可通过未记录的函数设置的 0.5 ms 计时器分辨率NtSetTimerResolution

如果您想持续监视新的计时器分辨率,那么我当前使用的方法是挂钩对 ntdll.dll 中未记录函数的调用(例如,可以从此处NtSetTimerResolution获取该函数的签名)。

不幸的是,挂钩不会检测安装挂钩之前请求的计时器分辨率,因此您需要将其与上述timeEndPeriod技巧结合起来,并注意挂钩之前的 0.5 毫秒分辨率请求未被检测到。

我同意,这种方法看起来很麻烦。此外,它有点侵入性,因为它修改了进程的状态,并且还假设您能够注入到所有进程中。

如果有人有更好的方法,我也有兴趣了解它们。