Wie kann ich feststellen, welcher Prozess die hohe Zeitauflösung in Windows festgelegt hat?

8

Mein System leidet unter einer hohen Timer-Auflösung ( NtQueryTimerResolution gibt 0.5ms zurück).

%Vor%

Einige Prozesse müssen NtSetTimerResolution mit einem Wert von 5000 (0,5 ms) aufrufen, aber wie kann ich feststellen, welche? Ich habe gesehen, dass Intel ein Tool namens Battery Life Analyzer hat zeigt die aktuelle Timer-Auflösung pro Prozess, aber dieses Tool ist nur für Intel-Partner verfügbar. Gibt es ein anderes Tool oder eine Möglichkeit, es über WinDbg zu sehen? Hinweis: Es scheint beim Booten zu passieren, da das Setzen eines Haltepunkts nicht funktioniert (die Auflösung ist bereits hoch, wenn der Debugger gestartet wird).

    
rustyx 05.05.2014, 11:14
quelle

2 Antworten

5

Ich habe festgestellt, dass Windows 7 die Timer-Auflösung pro Prozess in der _EPROCESS-Kernel-Struktur verfolgt.

Bei aktiviertem Debugging (boot mit /debug ) ist es möglich, die Liste ExpTimerResolutionListHead mit windbg (run windbg -kl ) zu durchsuchen und Timer-Informationen wie folgt zu extrahieren:

lkd> !list "-e -x \"dt nt!_EPROCESS @$extret-@@(#FIELD_OFFSET(nt!_EPROCESS,TimerResolutionLink)) ImageFileName UniqueProcessId SmallestTimerResolution RequestedTimerResolution\" nt!ExpTimerResolutionListHead"

In meinem Fall war die Prozess-ID jedoch NULL (wahrscheinlich, weil ein Treiber die Anfrage gestellt hat), und ich konnte immer noch nicht herausfinden, welcher Treiber es war.

    
rustyx 20.05.2014 11:02
quelle
3

Der einzige Weg, den ich kenne und bisher verwendet habe, besteht darin, in jeden laufenden Prozess zu injizieren und innerhalb dieses Prozesses timeEndPeriod für jede erhöhte Auflösung (Werte 1-15) in einer Schleife über diese Auflösungen aufzurufen und zu prüfen, ob timeEndPeriod Aufruf für eine aktuelle Auflösung gibt TIMERR_NOCANDO oder TIMERR_NOERROR zurück (Hinweis: diese Rückgabewerte sind NICHT entsprechend falsch und wahr). Und wenn es TIMERR_NOERROR zurückgibt, dann folge daraus, dass das Programm diese Frequenz verwendet, und rufe dann timeBeginPeriod erneut auf, um die vom Programm angeforderte ursprüngliche Auflösung wiederherzustellen.

Leider erkennt diese Methode nicht die Timer-Auflösungen von 0,5 ms, die von undocumented NtSetTimerResolution function gesetzt werden können.

Wenn Sie ständig die neuen Timer-Auflösungen überwachen wollen, dann ist das Anhaken von Aufrufen an undocumented NtSetTimerResolution function in ntdll.dll die Art, die ich momentan verwende (die Signatur der Funktion kann zB aus hier ).

Leider erkennt das Hooking keine Timer-Auflösungen, die vor der Installation des Hooks angefordert wurden. Daher müssen Sie es mit dem obigen timeEndPeriod Trick kombinieren und beachten, dass die Auflösungen von 0,5 ms vor dem Hooking unentdeckt bleiben.

Und ich stimme zu, diese Methode scheint umständlich. Darüber hinaus ist es ein wenig aufdringlich, da es den Zustand des Prozesses verändert und davon ausgeht, dass Sie in alle Prozesse injizieren können.

Wenn jemand bessere Methoden hat, wäre ich auch daran interessiert, sie zu kennen.

    
Roland Pihlakas 20.05.2014 03:34
quelle

Tags und Links