Главная > Программирование > Совсем удаленная отладка драйверов или safe mode — наше все.

Совсем удаленная отладка драйверов или safe mode — наше все.


Вспоминается анекдот-загадка:
Сколько нужно программистов чтобы вкрутить лампочку?
Ответ: Ни одного. Программисты не решают апаратные проблемы.

С удаленной отладкой примерно также: сколько нужно компьютеров, чтобы удаленно отлаживать драйвера? Ответ: три.

Почему 3, а не 2? Да потому что, если это настоящая удаленная отладка, то драйвер выполняется на машине у клиента, а вы конектитесь на еще одну удаленную машину, которая через COM или Firewire подключена к первому. Итого: 2 компа у клиента, и один у вас.

Но это мечта программиста, в реальности обычно используется 2:

1) ваш, на котором «все работает»

2) комп клиента, на котором все не работает.

Как же с этим жить и успешно фиксить баги?

В моем случае был драйвер файловой системы который по правилам блокировал все и вся. А так же по правилам разрешал или запрещал запуск процессов. Компьютер работал 24/7, и проблем было море:

1) Обычный Remote Desktop, который mstsc, при подключении к нему, порождал кучу действий, которые нарушали правила драйвера, он их блокировал. И в общем ничего не работало.

2) Забрать крэш дамп было тоже проблематично, потому что нужно было перезагружаться в safe mode, где этот драйвер не запущен, чтобы не бороться с его правилами

3) В safe mode не работает удаленный рабочий стол, законектиться некак, и нужно было просить чтобы ручками перезагружали тачку, забирали файл, а потом перезагружали обратно. Мне ли рассказывать, что такое упрашивать клиента собрать инфу…

4) Некак посмотреть дебажный лог драйвера, если он не пишет его на диск. Писать на диск с DISPATCH_LEVEL’а вообще как-то не очень получается. Выдумывать свой хитромудрый файловый лог, который будет многопоточным, не будет снижать производительность, и который сможет на любом IRQL работать, да еще и не привнесет новых багов — это надо ооочень хорошо постараться. А использовать Event Log нереально — вы ограничены ~ 110 байтами. Больше за раз записать нельзя. В общем логов нет 😦

5) Нужно как-то обновлять драйвер, а это опять же перезагрузка в safe mode, чтобы не бороться с правилами.

В общем надеюсь уже достаточно демотивирует 🙂

Итого: нужно было как-то перезагружать машину в safe mode без участия клиента, в safe mode иметь удаленный рабочий стол и каким-то образом получать дебажные логи ядра.

Начнем с конца.

Как получать логи?

На помощь идет как ни странно DbgView. Его можно запускать на логирование в файл с коммандной строки:

dbgview /c /t /l путь к файлу

Прописываем это дело в автозагрузку и получаем при каждом запуске новый лог. У dbgview есть также режим создавания нового лога каждый час, так что при желании можно завалиться логами.

Как сделать удаленный рабочий стол в safe mode?

Намучавшись с виндовым рабочим столом я перешел на ultravnc. Но как же его запустить в safe mode? Ответ в реестре.

Есть ветка:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SafeBoot
которая описывает службы и драйвера, которые должны запускаться в различных безопасных режимах.

Нас собственно интересует:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SafeBoot\Network
«Безопасный режим с загрузкой сетевых драйверов»

Создаем в нем раздел для сервиса ultravnc:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\uvnc_service
и в этом разделе прописываем значение «(По умолчанию)» = «Service» (без кавычек).

Вот и все, теперь при входе в «Безопасный режим с загрузкой сетевых драйверов» будет запускаться UltraVnc. Естественно нужно сделать чтобы компьютер автоматически логинился, потому что некому будет ввести пароль. Используем проверенный метод:
control userpasswords2
И конечно отключить UAC, потому что бороться с ним удаленно — весело.

Кому сильно нужен виндовый remote desktop — флаг в руки, выясняйте какие ему надо сервисы, прописывайте в реестр. Но имхо оно в safe mode работать не сможет.

А как же перезагружать компьютер в safe mode?

В Vista (до Seven руки не дошли) это делается довольно просто:
bcdedit /set {current} safeboot Network
и все, текущая загрузочная запись нас будет всегда перезагружать в safe mode. Поэтому, когда попали в safemode используем:
bcdedit /deletevalue {current} safeboot
чтобы сделать текущую загрузочную запись снова «нормальной».

На XP немного сложнее, надо редактировать boot.ini. И дописывать к параметрам загрузочной записи дополнительные параметры:
/safeboot:network /sos /bootlog /noguiboot

то есть должно быть вот как-то так:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /safeboot:network /sos /bootlog /noguiboot

Потом в safe mode соответственно, удалять их.

Но это в теории, на практике XP при старте в safe mode выводит сообщение типа «Мы щас в safe mode, а хотите запустить консоль восстановления да/нет?». И кто будет на эту месагу у нас нажимать? Служба ultravnc не будет запущена пока не будет нажато «да». Вот такая подлянка от разработчиков винды. И никак это не отключается, кроме как если пропатчить explorer.exe, но мы этим заниматься не будем.

Explorer, перед тем как вывести эту месагу, обрабатывает ключ RunOnce. Да-да в safe mode можно запускать не только свои сервисы, но и обычные приложения! Для этого просто нужно прописать в ключ:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
свое строковое значение, но оно должно начинаться со зведочки(*), то есть имя ключа должно быть к примеру «*MyOnceKey».

Но как нам ответить «Да»? А вот так:

   HMODULE module=LoadLibraryEx("c:\\windows\\explorer.exe",
                                0,
                                LOAD_LIBRARY_AS_IMAGE_RESOURCE);
   wchar_t desktopName[100];
   const UINT desktopNameResourceId=524; //localized name of desktop

   LoadStringW(module,
                    desktopNameResourceId,
                    desktopName,
                    _countof(desktopName));
   FreeLibrary(module);

   for (int i=0;i<10;i++) //dumb, but much easier to implement :)
   {
      HWND msgBoxWnd=FindWindowW(L"#32770",desktopName);
      if (msgBoxWnd!=NULL)
      {
         SendMessage(msgBoxWnd,WM_COMMAND,IDYES,0);
         break;
      }
      Sleep(1000); 
   }

Запускаемся, ждем пока появится окошко и шлем ему месагу, что было нажато YES. 🙂

Хорошо, есть программа, но руками это все прописывать задалбывает уже где-то на 3-й раз. Поэтому была написана программа для автоматизации всего этого дела.
Брать вместе с сорцами тут:
http://extint.narod.ru/Files/BootSafe.rar

Как использовать:
1) скопировать файлы BootSafe.exe и TestOnce.exe в корень диска C:
2) запустить BootSafe.exe
3) перезагрузить для перехода в safe mode
4) в safe mode просто перезагрузить чтобы вернуться в нормальный режим.

Дополнение:
Как оказалось, сервисы на XP запускаются и без нажатия на клавишу «Да», поэтому эта фича в общем не обязательна 🙂

Рубрики:Программирование Метки: ,
  1. Hex
    17 марта, 2010 в 23:09

    Вот написал это все и думаю: это ведь малварь за не фиг делать может это все юзать… Перезагружаешься в safe mode чтобы почистить комп, а там тебя уже ждут…

  2. 0xcd03
    17 марта, 2010 в 23:34

    Так вроде же, то же конфикер использовал сейф мод, чтобы узер не смог почистить свой пк.

  3. Hex
    18 марта, 2010 в 07:35

    У меня его не было, не знаю 🙂 Но раз уже было, значит «как страшно жить» (с)

  1. No trackbacks yet.

Оставьте комментарий