2014-05-05 5 views
8

Mój system cierpi z powodu wysokiej rozdzielczości zegara (NtQueryTimerResolution zwraca 0,5 ms).Jak określić, który proces ustawił wysoką rozdzielczość timera w systemie Windows

Maximum timer interval: 15.600 ms 
Minimum timer interval: 0.500 ms 
Current timer interval: 0.500 ms 

Niektóre proces musi być wywołanie NtSetTimerResolution o wartości 5000 (0,5ms), ale w jaki sposób można ustalić, który z nich? Widziałem, że Intel ma narzędzie o nazwie Battery Life Analyzer, które pokazuje bieżącą rozdzielczość zegara na proces, ale to narzędzie jest dostępne tylko dla partnerów firmy Intel. Czy istnieje inne narzędzie lub sposób, aby zobaczyć to przez WinDbg? Uwaga: Wydaje się, że dzieje się to przy starcie systemu, ponieważ ustawienie punktu przerwania nie działa (rozdzielczość jest już wysoka po uruchomieniu debuggera).

+2

Powercfg.exe/energia wygeneruje zgrabny raport, który popchnie złoczyńcę. Użyj superuser.com, aby zadawać takie pytania. –

+1

@HansPassant dzięki, ale to nie zadziałało. W raporcie napisano "Request Count 1", ale nie pokazano, kto o to poprosił. Przesłałem pełny raport [tutaj] (http://rustyx.org/energy-report.html). – rustyx

+0

Powercfg.exe/energia to nie robi, Intel może to zrobić. Chciałbym również zobaczyć wywołanie API. – Arno

Odpowiedz

3

Jedynym sposobem, jaki znam i dotychczas wykorzystałem, jest wstrzykiwanie do każdego z uruchomionych procesów i wewnątrz tego procesu wywoływanie timeEndPeriod dla każdej zwiększonej rozdzielczości (wartości 1-15) w pętli przez te rozdzielczości i sprawdzanie, czy wywołanie timeEndPeriod dla bieżąca rozdzielczość zwraca TIMERR_NOCANDO lub TIMERR_NOERROR (uwaga: te zwracane wartości NIE są odpowiednio fałszywe i prawdziwe). A jeśli zwróci TIMERR_NOERROR, to dojdzie do wniosku, że program używa tej częstotliwości, a następnie ponownie wywołuje timeBeginPeriod, aby przywrócić pierwotną rozdzielczość wymaganą przez program.

Niestety, ta metoda nie wykrywa czasów timera 0,5 ms, które można ustawić za pomocą nieudokumentowanej funkcji NtSetTimerResolution.

Jeśli chcesz stale monitorować nowe rezolucje zegara, wówczas połączenia z nieudokumentowaną funkcją NtSetTimerResolution w pliku ntdll.dll są aktualnie używane (sygnaturę funkcji można pobrać na przykład z here).

Niestety, zahaczanie nie pozwala wykryć rozdzielczości zegara, które były wymagane przed zainstalowaniem haka, więc musisz połączyć je z powyższą sztuczką timeEndPeriod i zwróć także uwagę, że rozdzielczość 0,5 ms wymaga, aby przed zahaczeniem pozostała niewykryta.

Zgadzam się, ta metoda wydaje się uciążliwa. Co więcej, jest nieco inwazyjne, ponieważ modyfikuje stan procesu, a także zakłada, że ​​jesteś w stanie wstrzykiwać do wszystkich procesów.

Jeśli ktoś ma lepsze metody, byłbym zainteresowany ich również.

+1

Podoba mi się pomysł iniekcji! Ale po pierwsze, wstrzyknięty kod musiałby jedynie sprawdzić "bieżącą" rozdzielczość, a po drugie mógł również użyć NtSetTimerResolution do przetestowania STATUS_TIMER_RESOLUTION_NOT_SET. – Arno

+0

Powoduje to jednak małą przerwę, podczas gdy aplikacja traci pożądaną rozdzielczość. Czy myślisz, że w ten sposób wdrożono 'powercfg - energy '? I: Kierowcy? System w czasie rozruchu? W każdym razie przyznano nagrodę, dzięki za twój wysiłek. Zwróciłem ponownie uwagę na tę kwestię w innym pytaniu [tutaj] (http://stackoverflow.com/q/23734775/1504523). – Arno

+0

Jak mogę wprowadzić proces i wywołać timeEndPeriod? Mam taki sam problem, z wyjątkiem tego, że wzywa on, by częstotliwość zegara wynosiła 1,25 ms. –

5

Zauważyłem, że Windows 7 śledzi rozdzielczość zegara na proces w strukturze jądra _EPROCESS.

Z debugowanie włączone (boot z /debug) możliwe jest przeglądanie listy ExpTimerResolutionListHead z WinDbg (run windbg -kl) i wydobyć informacje timera takiego:

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

W moim przypadku jednak identyfikator procesu było NULL (prawdopodobnie dlatego, że sterownik wysłał żądanie) i nadal nie mogłem ustalić, który to sterownik.

+0

+1 BTW: powercfg -energy nie wstrzykuje żadnego kodu, dlatego musi uzyskać informacje w inny sposób. Ale nie może też rozwiązać ustawień zegara uzyskanych przez sterownik. – Arno

+0

powercfg -energy pokazuje również stos wywołań połączenia, który ustawił najwyższą rozdzielczość procesu. Zakładam, że ten stos wywołań działa również z mocą wsteczną - w przypadku wywołań wykonanych przed uruchomieniem -energy powercfg. Więc może jądro ma nawet informację o tych stertach. Zastanawiam się tylko, dlaczego ...? I głównie w tym kontekście - gdzie można zlokalizować tę informację? Czy jest również w tej samej strukturze danych jądra? Można się też zastanawiać, dlaczego nie ma w nich miejsca dla kierowców. Sterowniki działają w ramach procesu systemowego, jeśli dobrze rozumiem. –

+0

Zrobiłem małe wyszukiwanie Google. Wygląda na to, że tak, _EPROCESS zawiera także stosy diagnostyczne związane z żądaniami rozwiązania zegara: http: //msdn.moonsols.com/win7rtm_x86/EPROCESS.html –

Powiązane problemy