Как-то раз, я торопился домой, а моя
любимая Windows NT никак не хотела выключаться. "Ну
же, давай, дохни, родимая," - в нетерпении
понукал я машину но тщетно. Особенно меня бесило
то, что никаких разумных причин таких тормозов не
наблюдалось. К внешним устройствам обращения
нет, машина не свопится. Сколько же нужно
операций процессору, чтобы выключить машину?
Очевидно, дядюшка Билли просто решил оттянуться
с "Мириндой" или пробовал новый "Дью".
Итак, надо мной откровенно издевались, а мне лишь
оставалось в бессильной злобе скрипеть зубами.
Немыслимое унижение, а главное от кого?! И в
ярости я поклялся отмстить!!!
- За это ти умрешь, как подлий шакал!
Снедаемый жаждой мести, я деятельно
приступил к поискам. Что же происходит, когда
умирают Винды? Увы, в Инете никаких умных мыслей и
рассуждений по этому поводу я не нашел. А нашел я
буржуинское предложение купить прогу, что
выключает машину. И всего за каких-то жалких 50$!
- За дэвушку, спортсмэнку, камсамолку, я прошу
всэго каких-то 25 баранов!
Окончательно убитый, я
еще немного меланхолично пощелкал мышью в разных
окошках и с печальным вздохом нажал Ctrl-D.
- Нэ надо, слюшай!
- Сам нэ хачу!
Как всем известно, есть такая хорошо задокументированная функция ExitWindowsEx(), а еще есть плохо задокументированная функция ZwShutDownSystem(). Логично предположить, что эти функции взаимосвязаны и в конце концов ExitWindowsEx() передает управление ZwShutDownSystem(). Попробовал, обе функции прекрасно выключают Windows, только первая делает это долго, а вторая быстро. Казалось бы все понятно: именно в ExitWindowsEx() и происходят все ненужные нам паузы. Ага, щас!
- И передает ее влюбленному джигиту.
- Нэт, и пэрэдает ее кунакам влюбленного джигита.
При штатном останове функция ZwShutDownSystem() вообще не вызывается! Давайте рассмотрим, что же происходит при вызове ZwShutDownSystem().
BOOL ZwShutDownSystem(DWORD arg);
где arg - некий параметр, может быть и адресом и
числом.
0x00 - Shutdown
0x01 - Reboot
0x02 - Poweroff
Из ntdll.dll сразу же происходит обращение в ядро (ntoskrnl.exe). Далее, система последовательно дергает кучу других "shutdown". А именно,
...
call _ExShutdownSystem
...
call _IoshutdownSystem
...
call _CmShutdownSystem
...
call _MmShutdownSystem
...
call _IoShutdownSystem
...
call _DbgUnloadImageSymbols
...
Как говорится, без комментариев. И, наконец, "здравствуй железо"
call __imp__HalReturnToFirmware
После короткой возни в hall.dll, все заканчивается короткой командой ... нет, не "Пли!", нет, и не "Режь!", а
out DX, AL
Как я ее понял, в 64 порт пишут значение 0xfe. По-видимому, это останов процессора. А может и нет! Кто знает, напишите мне, пожалуйста! Заметим, что SoftIce работает до самого конца! То есть, скорее всего выгрузки драйверов не происходит. Но вернемся к нашему единственному барану, а именно к функции ExitWindowsEx(). Здесь процедура и проще, и ... сложнее! Я еще раз оценил юмор компании Microsoft.
- Ха! Шютник! Будишь рэзать свой невеста, мэня нэ забудь позвать!
Вся работа ExitWindowsEx() сводится к
добавлению к своим двум аргументам (один из
которых по официальной версии не используется)
еще одного (всегда 0x00) и вызову функции ExitWindowsWorker()
теперь уже с тремя аргументами (один из которых
по официальной версии не используется, а другой
всегда 0x00).
В ExitWindowsWorker() после короткой проверки
вызывается
...
call imp_CsrClientCallServer
...
Итак, остается констатировать неутешительный факт: остановка Windows отдана на откуп подсистеме, взаимодействие с которой происходит через LPC-механизм.
- В маем доме нэ выражаться!
- А что я сказал?
Благодаря господину Охапкину (поистине великий гуру!), формат функции CsrClientCallServer() известен:
int CsrClientCallServer(DWORD length, DWORD opcode, DWORD zero, PVOID message),
где length - длина чего-то, но не всего сообщения;
opcode - не то флаги, не то идентификатор внутри
подсистемы;
zero - неизвестно что, но всегда ноль;
message - буфер данных для отправки сообщения в
подсистему.
При вызове ExitWindowsEx() аргументы
CsrClientCallServer() имеют следующие значения:
length - всегда 0x10;
opcode - для NT4.0 всегда 0x00030a00, для Win2000 всегда 0x00030400
zero - всегда 0x00;
message - мне известно только то, что 11-ое и 12-ое
слова буфера (считая от нуля) - это параметры
ExitWindowsEx(). Остальное можно занулить, и тем не менее
все будет работать.
Итак, можно перегружать (restart), завершать сеанс (log off) и выключать Windows (shut down или power off), используя CsrClientCallServer() с соответствующим 11 словом. Например, 0x08 - Power off 0x00 - Log off 0x02 - Reboot и т. д.
"Ну хорошо, это в NT4.0, а как насчет
Windows 2000?" - спросит читатель и будет совершенно
прав. В Win2000 дядюшка Билли уже не так добр и
открыт, как в старые добрые времена. Многие
функции из user32.dll больше не экспортируются в том
числе и функция ExitWindowsWorker() (хотя по-прежнему
вызывается). Перед отправкой сообщение в
подсистему происходят еще какие-то действия
внутри win32k.sys. В остальном все очень похоже, разве,
как уже было сказано, opcode изменился. Что касается
ZwShutDownSystem(), то мне удалось выяснить только, что в
определенный момент происходит проход по
спискам драйверов, и где-то на середине Soft-Ice
намертво падает.
Между прочим, один почтенный старец
поведал мне старое предание о том, что где-то под
Рязанью в отшельническом скиту живет могучий
богатырь Евлампий. Дескать, сей буй-тур Евлампий
Батькович доходил под Soft-Ice до самого до краю
двухтысячных Виндов. Более того, он знает как
работает команда hboot. Коли сыщется кто-то, кто
ведает о сем достойном муже, не сочтите за труд,
черкните письмецо.
Чтобы проистрюллировать (или
пролюлистрировать?) свои исследования прилагаю
исходник shut.cpp. Прога тестилась на серверах
NT4.0 (SP4, SP6) и на Win2000 (SP2). На выбор Вы можете
выключать Винды быстро (особенно это приятно там,
где стоит Exchange), или обычным способом.
- Будем ждать. Сдавай!
Да, кстати, чуть не забыл. Биллофобам и окноненавистникам, думаю, будет приятно узнать, что если с помощью CsrClientCallServer() отправить подряд два сообщения с 11-ым словом 0x08 (см. исходник), то сервера как NT4.0, так и Win2000 падают довольно специфическим способом: пустой экран, мышь работает, Soft-Ice работает, но больше ничего сделать нельзя, Task Manager не вызывается.
- Нычего ж нэ сдэлал, только вошел! Обыдно, слюшай!
Минут 15 ничего не менялось, дальше мое терпение истощилось и я нажал Reset. Вот, пожалуй, и все. Если есть вопросы, замечания или предложения, пишите по адресу tanaka@rambler.ru или смотрите на нашем сайте teamz.nm.ru
P.S.
Послушайте, мне тут такую вещь показали!!!
Оказывается, что если нажать кнопочку "Start",
потом в менюшке выбрать "Shut down ...", потом из
выпадающего окошка выбрать "Shut down", а потом
нажать кнопочку "OK" ... Сейчас я Вам
продемонстрирую. И что удивительно, все раб...
обсудить | все отзывы (0) | |
[28132; 30; 7.6] |
|
|