Kiedyś, mój ówczesny szef, przedstawiając mnie współpracownikom powiedział, że używam wyszukiwarek tylko po to, żeby znaleźć coś, co już na pewno opisałem na blogu. Pomijając już to, jak takie stwierdzenie łechce ego (czego dowodem jest, że je po latach pamiętam), to myślę, że tak naprawdę, takie podejście nie jest obce nikomu, kto prowadzi bloga dłużej niż kilka miesięcy. No bo o ile nowości na pewno nigdy opisywane wcześniej nie były, o tyle jakieśtam mniej lub bardziej zaawansowane szczegóły i szczególiki czasem tak długo ma się w głowie na liście "do opisania", że potem człowiek naprawdę mocno się dziwi, gdy chce znaleźć linka do swojego artykułu a tu okazuje się, że on nigdy nie powstał... Ja miałem tak wczoraj, gdy próbowałem znaleźć przepis na postępowanie w przypadku występowania BSOD z kodem 0x19 BAD_POOL_HEADER.
Błąd ten jest nietrywialny do przeanalizowania, ponieważ powstaje w sytuacji, gdy sterownik sięgnie do puli pamięci, której nagłówek został przez kogoś popsuty. Podstawowa analiza wskazuje więc "ofiarę" a nie winnego całej sytuacji. Prawdziwym winnym jest ten, kto popsuł, a w momencie pojawienia się blue screena nie mamy żadnych wyraźnych śladów kto to był i kiedy to zrobił ani dlaczego. Biorąc pod uwagę, że prawie 80% blue screenów spowodowane jest przez sterowniki firm trzecich, możemy strzelać w ciemno i próbować aktualizować oprogramowanie do karty graficznej czy sieciowej, jednak nie ma to wiele wspólnego z rzetelnym naukowym podejściem do tematu. Analiza dumpa wiele nam nie da, bo wskaże ofiarę. Co więc pozostaje? Otóż trzeba złapać winnego na gorącym uczynku, w momencie, gdy próbuje modyfikować nie swoje obszary pamięci. Nie jest to aż takie trudne, ponieważ mamy do dyspozycji potężne narzędzie, które (z nie do końca dla mnie zrozumiałych powodów) leży i czeka na dysku każdego komputera wyposażonego w system Windows. Mowa o Driver Verifier.
Generalnie rzecz ujmując, Driver Verifier sprawia, że mechanizmy działające w jądrze systemu i współpracujące ze sterownikami zaczynają być nieco mniej ufne i szczegółowo przyglądają się każdej czynności. Czy aby na pewno sterownik zwalnia całą pamięć, gdy przestaje działać? Czy pracujący w trybie jądra sterownik nie sięga w brzydki sposób do pamięci w trybie użytkownika? Czy to, czego sterownik próbuje użyć jako uchwytu, faktycznie jest uchwytem?
Jedną z możliwości jądra jest na przykład takie alokowanie żądanych puli pamięci, aby nie dało się do nich wejść przypadkiem. Większość błędów związanych z zamazaniem przez źle napisany sterownik cudzych obszarów pamięci bierze się stąd, że sterownik taki, zapisując bajt po bajcie, w którymś momencie wyjdzie poza swój obszar. Jeżeli następny obszar należy do kogoś innego, to katastrofa gotowa a winnego po fakcie może być trudno wskazać. Zabezpieczenie przed tym nie jest bardzo złożone – wystarczy, zamiast umieszczać jeden blok pamięci za drugim, rozdzielić bloki obszarem ziemi niczyjej. Celowo nikt tam nie wejdzie a przypadkowy dostęp zostanie natychmiast zauważony i wywoła BSOD o numerze 0xCD PAGE_FAULT_BEYOND_END_OF_ALLOCATION. Jaki mamy efekt w przypadku opisanym na początku? Zamiast błędu 0x19 pojawia się błąd 0xCD. Nie brzmi to może szczególnie atrakcyjnie, bo w końcu blue screen to blue screen, ale różnica jest niezwykle istotna: identyfikujemy winnego a nie ofiarę! A to już nienajgorszy start do skutecznego wyeliminowania łobuza z naszego systemu.
Wróćmy do narzędzia. Ponieważ Driver Verifier stosowany bywa przez programistów do badania poprawności działania pisanych przez nich sterowników, jego funkcjonalność jest znacząco większa niż to, czego potrzebuje użytkownik walczący z trudnym BSOD. Dlatego, najlepiej podejść do niego z precyzyjną instrukcją:
- Uruchomić aplikację verifier.exe. Leży w folderze system32 i musi być uruchamiana z uprawnieniami administratora.
- Można użyć "Standard Settings" – ten zestaw ustaweń (opisany dokładnie w MSDN) pozwala na wykrycie typowych problemów i jest bardzo dobrym punktem wyjścia.
- Korzystamy z opcji "Select driver names from a list"
- Sortujemy sterowniki po kolumnie "Provider" i na początku i końcu listy zaznaczamy wszystkie te, które nie są dostarczone przez Microsoft. I tak nie powinniśmy weryfikować działania wszystkich sterowników na raz, a statystyki mówią, że znalezienie czegokolwiek jest znacząco bardziej prawdopodobne w kodzie firm trzecich.
- Jeżeli w dumpie dają się znaleźć sterowniki (polecenie "lmof" w WinDbg może być tu pomocne), których nie ma na liście Verifiera, bo nie są w momencie jego uruchamiania załadowane, można je dodać manualnie.
- Klikamy "Finish" i restartujemy komputer.
Wydajność komputera jest nieco ograniczona (dlatego praca z Verifierem stale aktywnym nie jest polecana) ale wszystko działa. A gdy zdarzy się błąd, dowiemy się o nim natychmiast a jego analiza nie powinna już być trudna. Po znalezieniu winnego i wyeliminowaniu problemu, należy ponownie uruchomić verifier.exe i korzystając z opcji "Delete existing settings" i restartu, przełączyć system w normalny tryb pracy.
Do pełni obrazu, dodałbym jeszcze kilka ważnych uwag końcowych:
- Jeżeli chcemy się czegoś nowego nauczyć, pobawić Verifierem a uparcie nie pojawiają nam się BSODy, to polecam użycie aplikacji NotMyFault. Na maszynie wirtualnej a nie na produkcyjnym systemie! Nawet, jeżeli coś sobie popsujemy, to snapshoty pomogą nam oszczędzić sporo czasu. W przypadku NotMyFault, konieczne będzie weryfikowanie sterownika myfault.sys – jeżeli nie ma go na liście, to przycisk "Add currently not loaded driver(s) to the list..." w opcjach Verifiera na pewno się przyda.
- Jeżeli mamy pecha, to "ratowniczy" blue screen pojawi się zanim będzie możliwe zalogowanie się do systemu. Żeby móc opanować system czy zainstalować zaktualizowany sterownik, musimy jednak jakoś Verifiera odpalić. Pomoże nam w tym Safe Mode, ale warto wiedzieć, że ten tryb potrafimy włączyć zanim pierwszy raz uruchomimy verifier.exe.
- Uważajmy zanim komuś "życzliwemu" wyślemy nasz dump do analizy. Są w nim poufne informacje (na przykład hasła) i beztroskie publikowanie dumpów na forach niekoniecznie jest najlepszym podejściem.
- Pamiętajmy, że przyczyną istotnej części BSOD są problemy sprzętowe. Niestety nie jest to proste do wykrycia i często tracimy wiele czasu na walkę z przedziwnymi objawami. Poszukując przyczyn kłopotów, nie wolno o sprzęcie zapominać.
A tak naprawdę, to nikomu nie życzę potrzeby używania takich narzędzi.
Autor: Grzegorz Tworek [MVP]
PS sprawdzając szybko czy zamiast pisać sam, nie znajdę gdzieś gotowego do polecenia przepisu na poradzenie sobie z BSOD 0x19 trafiłem na jeden wyjątkowo kuriozalny. Chyba nie polecam.