В этом блоге опубликовано немало программистских баек. Мне нравится вспоминать о своих старых глупостях. Что ж, вот ещё одна такая история.
Я впервые заинтересовался компьютерами, особенно программированием, когда мне было около 11 лет. В начале средней школы большую часть свободного времени я возился со своим C64 и писал на Бейсике, а потом вырезал ножницами плохой код. Я не шучу, ножницами.
После школы (в возрасте около 16 лет) британские дети обычно идут в колледж, там выбирают для изучения три-четыре предмета, прежде чем поступить в университет. Учитывая свою любовь к бежевой коробке и магнитофону дома, я решил, что изучение «информатики» в колледже — правильный выбор.
Курс понравился мне больше, чем я ожидал; там я впервые познакомился с Паскалем и Дельфи.
В перерывах между занятиями студенты могли работать за любой свободной машиной в компьютерном зале. Представьте себе: огромная комната, рассчитанная где-то на сто человек, с рядами столов, уставленных машинами, — вроде тех, где монитор стоит на системном блоке. Постоянное жужжание вентиляторов, мышиные шарики гудят по столам, не останавливаясь ни на секунду. В воздухе странный запах, словно 50-100 источающих гормоны подростков периодически сменяются для охлаждения сотни чипов Pentium III.
Несмотря на риски для здоровья, мне нравилось посидеть за компьютером, когда выдавалась свободная минутка.
В комнате дежурил админ, невысокий мужчина средних лет, которого выбрали на эту роль из-за неуёмного стремления стать злым диктатором. Я так полагаю. Дежурил — это слабо сказано, парень действительно любил свою работу. Ему поручили следить за порядком, чтобы никто не использовал учебный компьютер для чего-то неподобающего.
И по сей день интуиция подсказывает мне, что премия админа напрямую зависела от количества студентов, которых он поймает за руку и выпроводит из компьютерного зала. Я практически уверен, что этот парень досрочно погасил свою ипотеку.
Он сидел в дальнем углу компьютерного зала за угловым столом. И можно было с уверенностью предположить, что его фертильные мониторы нашли способ размножаться с впечатляюще коротким периодом беременности — настолько их было много. Оставалось только гадать, действительно ли он успевает следить за ними всеми. Конечно, шучу… я же упоминал, что он очень серьёзно относился к работе?
В то время компьютерная сеть работала под управлением Windows 2000. Вскоре я обнаружил, что при каждом входе в систему запускается скрипт, в котором прописан запуск сервера VNC с админского аккаунта для удалённого доступа к рабочему столу. Всякий раз, когда этот парень хотел проследить за вами, он подключался непосредственно к вашей машине и наблюдал. Это было жутко, а если сейчас подумать, скорее всего, незаконно.
Наточив зубы на Бейсике и C64, теперь я писал на C и даже немного на C++. В то время я ещё очень увлёкся языком D, который исправлял некоторые недостатки C++, как мне виделось тогда.
Я обычно заходил в компьютерный зал, чтобы почитать что-то новенькое по D или поиграть с компилятором Digital Mars D. Иногда отвлекаясь от мыслей о великом будущем D, я писал код на C для взлома других программ Win32 через дескрипторы их окон.
В старые добрые времена программирования на Win32 поиск дескриптора окна был самым простым методом для взлома других программ. Очевидно, что у всех программ с графическим интерфейсом в Windows имелось окно, даже если оно не отображалось на экране. Написав программу для извлечения дескриптора другого процесса (по сути, ссылки на него), вы могли отправлять ему сообщения. Это позволяло производить некоторые базовые операции, типа скрыть/отобразить окно программы, а также действительно классные вещи, например, заставить процесс загрузить произвольную DLL в своё пространство памяти и начать выполнение кода. После инъекции DLL начиналось самое интересное.
В первые полтора месяца этот детектив меня особо не беспокоил, он подключился к VNC-серверу на моей машине только один или два раза. Но один конкретный сеанс, вероятно, пробудил в нём интерес. Я писал какой-то код на C для скрытия окон Minesweeper (не закрывая их), чтобы было легче играть в классе, и тут заметил, что белый значок VNC в системном трее стал чёрным. Это означало, что он теперь наблюдает за мной.
Я продолжал кодить как обычно, стараясь не обращать на него внимания. Тем временем, машина начала конкретно подтормаживать, пытаясь передать максимальную частоту кадров на один из бесчисленных мониторов в углу комнаты. Винда почти перестала реагировать, когда моё терпение лопнуло, я вышел из системы и закончил на сегодня.
Во время следующих визитов в компьютерный зал Коломбо почти каждый раз проявлял живой интерес к тому, чем я занимаюсь. Примерно после четвёртого раза я решил: с этим нужно что-то делать.
Допускаю, что разумный, рациональный человек мог просто поднять этот вопрос непосредственно с ним или его начальником. Однако я всегда поддавался искушению и быстро уговорил себя избрать совершенно иную стратегию.
— Ты ничего не сможешь сделать без этого сервера VNC! —спокойно решительно сказал я себе один несколько раз.
Нужно было убить VNC.
Я начал входить в компьютерный зал с большими группами студентов и садиться как можно дальше от угла с мониторами. Некоторое время это работало и дало мне немного времени на проверку идей.
Моя первая попытка, я думаю, вы согласитесь, была довольно слабой. Щёлкнув правой кнопкой мыши по значку VNC в системном трее, я увидел меню с волшебными буквами E-X-I-T. К сожалению, буквы были написаны серым контурным текстом. Администратор отключил пункт меню «Выход» через редактор групповой политики. Я попытался убить процесс из Диспетчера задач, но, конечно, он был невидим для меня, поскольку работал под другой, более привилегированной учётной записью. Ничего не вышло.
VNC-сервер крутится на порту TCP 5900, вспомнил я. Мой следующий план состоял в том, чтобы отправить на этот порт повреждённые пакеты, дабы подвесить его.
По крайней мере несколько дней я разбирал протокол, посылая на порт 5900 различные формы корректно структурированного дерьма и надеясь, что он сломается. В конце концов, это тоже не сработало.
Я уже начал думать, что не смогу избавиться от этой штуки, когда меня вдруг осенило: там же должно быть окно! Надо его отобразить. Может, в нём будет хорошая сочная кнопка «Выключить», которой я найду отличное применение!
Я запустил свой уже практически совершенный код C для поиска дескриптора главного окна другого процесса — и действительно нашёл VNC. Я чувствовал себя окрылённым, когда пальцы набрали
Ничего!
Теперь мне стало любопытно… у него было окно, но оно игнорировало мои сообщения. Я дважды проверил свой код, чтобы убедиться, что он работает. Протестировал его на нескольких других процессах, и он работал отлично. Я пробовал посылать в окно VNC другие сообщения, и всё равно ничего.
И тут меня опять осенило!
Благодаря очень толстой книге Чарльза Петцольда я тщательно изучал, как процессы Win32 работают внутри системы. У каждого приложения Win32 есть окно, а также «очередь сообщений». Сообщения, вызванные взаимодействием с пользователем, а также сообщения, отправленные самой Windows, поступают в очередь, а само приложение решает, как их обрабатывать.
Не слишком интересно само по себе. Но когда я понял, что достаточно большая необработанная очередь сообщений выступает эвристикой для вмешательства в зависший процесс со стороны менеджера Window Process Manager, я вспотел чистым серотонином.
Не теряя ни секунды, я вернулся к своему коду C, готовясь отправить в главное окно VNC ещё одно сообщение
Я скомпилировал и запустил 4 КБ самого свободолюбивого кода в своей жизни. Примерно через три секунды Windows сообщила, что процесс
Чёрт возьми, ДА!
Позвольте признаться, что остаток дня я был невыносимо доволен собой.
После нескольких часов, потраченных на переваривание моей новой суперсилы, я решил, как буду её использовать. Просто убить сеанс прямо у него на глазах было слишком просто. У меня была идея получше — исчезнуть совсем.
После боевого крещения с программированием сокетов я понял, что могу написать код, который будет делать две вещи. Сначала он займёт недавно освобождённый порт TCP 5900, ранее занятый невежественным процессом сервера VNC. Потом создаст новое TCP-соединение с VNC-сервером заданной машины. Код будет просто проксировать все данные между двумя сокетами, и Коломбо подумает, что подключается ко мне, тогда как на самом деле будет подключаться к совершенно другому VNC-серверу.
Мой код будет действовать как тайный мост между мной и какой-нибудь другой бедной душой на мой выбор. Это было прекрасно.
Я сразу же начал писать свой поддельный бридж VNC. Коломбо несколько раз подключался ко мне, но я продолжал программировать у него на глазах. Я пришёл к выводу, что он понятия не имеет о моих действиях, хотя я писал очевидные вещи, такие как номера портов и комментарии вроде
Через пару дней я никак не мог заставить код работать правильно. Что ещё хуже, я практически непрерывно работал с чёрным значком VNC в системном трее. Пока он был подключен, я не мог освободить порт, чтобы проверить свой код.
Если бы я тогда знал о
В конце концов, нервы не выдержали, всё-таки я был нетерпеливым 17-летним парнем. Снова наблюдая, как белый значок сервера VNC становится чёрным, я психанул, открыл первоначальный код, который заполнял очередь сообщений, и запустил у него на глазах. Я даже подождал пару секунд, прежде чем нажать
Если нажатие этой кнопки ещё не полностью убедило меня, что оно того стоило, то его прыжок из-за своей крепости мониторов, чтобы быстро подойти ко мне и выпроводить меня из комнаты, определённо, стоил того.
В итоге мне запретили доступ в сеть на две недели. Справедливое наказание, подумал я. Примерно через три недели сервер VNC исчез из загрузочных скриптов и больше нигде не появлялся. Я так и не узнал, сыграл ли мой инцидент какую-то роль в этом или нет, но он полностью разрушил мой план сказочного обогащения на продаже своей пушки VNC угнетённым студентам в компьютерных залах колледжей по всей стране.
Я впервые заинтересовался компьютерами, особенно программированием, когда мне было около 11 лет. В начале средней школы большую часть свободного времени я возился со своим C64 и писал на Бейсике, а потом вырезал ножницами плохой код. Я не шучу, ножницами.
После школы (в возрасте около 16 лет) британские дети обычно идут в колледж, там выбирают для изучения три-четыре предмета, прежде чем поступить в университет. Учитывая свою любовь к бежевой коробке и магнитофону дома, я решил, что изучение «информатики» в колледже — правильный выбор.
Курс понравился мне больше, чем я ожидал; там я впервые познакомился с Паскалем и Дельфи.
В перерывах между занятиями студенты могли работать за любой свободной машиной в компьютерном зале. Представьте себе: огромная комната, рассчитанная где-то на сто человек, с рядами столов, уставленных машинами, — вроде тех, где монитор стоит на системном блоке. Постоянное жужжание вентиляторов, мышиные шарики гудят по столам, не останавливаясь ни на секунду. В воздухе странный запах, словно 50-100 источающих гормоны подростков периодически сменяются для охлаждения сотни чипов Pentium III.
Несмотря на риски для здоровья, мне нравилось посидеть за компьютером, когда выдавалась свободная минутка.
В комнате дежурил админ, невысокий мужчина средних лет, которого выбрали на эту роль из-за неуёмного стремления стать злым диктатором. Я так полагаю. Дежурил — это слабо сказано, парень действительно любил свою работу. Ему поручили следить за порядком, чтобы никто не использовал учебный компьютер для чего-то неподобающего.
И по сей день интуиция подсказывает мне, что премия админа напрямую зависела от количества студентов, которых он поймает за руку и выпроводит из компьютерного зала. Я практически уверен, что этот парень досрочно погасил свою ипотеку.
Он сидел в дальнем углу компьютерного зала за угловым столом. И можно было с уверенностью предположить, что его фертильные мониторы нашли способ размножаться с впечатляюще коротким периодом беременности — настолько их было много. Оставалось только гадать, действительно ли он успевает следить за ними всеми. Конечно, шучу… я же упоминал, что он очень серьёзно относился к работе?
В то время компьютерная сеть работала под управлением Windows 2000. Вскоре я обнаружил, что при каждом входе в систему запускается скрипт, в котором прописан запуск сервера VNC с админского аккаунта для удалённого доступа к рабочему столу. Всякий раз, когда этот парень хотел проследить за вами, он подключался непосредственно к вашей машине и наблюдал. Это было жутко, а если сейчас подумать, скорее всего, незаконно.
Наточив зубы на Бейсике и C64, теперь я писал на C и даже немного на C++. В то время я ещё очень увлёкся языком D, который исправлял некоторые недостатки C++, как мне виделось тогда.
Я обычно заходил в компьютерный зал, чтобы почитать что-то новенькое по D или поиграть с компилятором Digital Mars D. Иногда отвлекаясь от мыслей о великом будущем D, я писал код на C для взлома других программ Win32 через дескрипторы их окон.
В старые добрые времена программирования на Win32 поиск дескриптора окна был самым простым методом для взлома других программ. Очевидно, что у всех программ с графическим интерфейсом в Windows имелось окно, даже если оно не отображалось на экране. Написав программу для извлечения дескриптора другого процесса (по сути, ссылки на него), вы могли отправлять ему сообщения. Это позволяло производить некоторые базовые операции, типа скрыть/отобразить окно программы, а также действительно классные вещи, например, заставить процесс загрузить произвольную DLL в своё пространство памяти и начать выполнение кода. После инъекции DLL начиналось самое интересное.
В первые полтора месяца этот детектив меня особо не беспокоил, он подключился к VNC-серверу на моей машине только один или два раза. Но один конкретный сеанс, вероятно, пробудил в нём интерес. Я писал какой-то код на C для скрытия окон Minesweeper (не закрывая их), чтобы было легче играть в классе, и тут заметил, что белый значок VNC в системном трее стал чёрным. Это означало, что он теперь наблюдает за мной.
Я продолжал кодить как обычно, стараясь не обращать на него внимания. Тем временем, машина начала конкретно подтормаживать, пытаясь передать максимальную частоту кадров на один из бесчисленных мониторов в углу комнаты. Винда почти перестала реагировать, когда моё терпение лопнуло, я вышел из системы и закончил на сегодня.
Во время следующих визитов в компьютерный зал Коломбо почти каждый раз проявлял живой интерес к тому, чем я занимаюсь. Примерно после четвёртого раза я решил: с этим нужно что-то делать.
Допускаю, что разумный, рациональный человек мог просто поднять этот вопрос непосредственно с ним или его начальником. Однако я всегда поддавался искушению и быстро уговорил себя избрать совершенно иную стратегию.
— Ты ничего не сможешь сделать без этого сервера VNC! —
Нужно было убить VNC.
Я начал входить в компьютерный зал с большими группами студентов и садиться как можно дальше от угла с мониторами. Некоторое время это работало и дало мне немного времени на проверку идей.
Моя первая попытка, я думаю, вы согласитесь, была довольно слабой. Щёлкнув правой кнопкой мыши по значку VNC в системном трее, я увидел меню с волшебными буквами E-X-I-T. К сожалению, буквы были написаны серым контурным текстом. Администратор отключил пункт меню «Выход» через редактор групповой политики. Я попытался убить процесс из Диспетчера задач, но, конечно, он был невидим для меня, поскольку работал под другой, более привилегированной учётной записью. Ничего не вышло.
VNC-сервер крутится на порту TCP 5900, вспомнил я. Мой следующий план состоял в том, чтобы отправить на этот порт повреждённые пакеты, дабы подвесить его.
По крайней мере несколько дней я разбирал протокол, посылая на порт 5900 различные формы корректно структурированного дерьма и надеясь, что он сломается. В конце концов, это тоже не сработало.
Я уже начал думать, что не смогу избавиться от этой штуки, когда меня вдруг осенило: там же должно быть окно! Надо его отобразить. Может, в нём будет хорошая сочная кнопка «Выключить», которой я найду отличное применение!
Я запустил свой уже практически совершенный код C для поиска дескриптора главного окна другого процесса — и действительно нашёл VNC. Я чувствовал себя окрылённым, когда пальцы набрали
WM_SHOWWINDOW
. Попробуйте угадать, что я увидел перед собой?Ничего!
Теперь мне стало любопытно… у него было окно, но оно игнорировало мои сообщения. Я дважды проверил свой код, чтобы убедиться, что он работает. Протестировал его на нескольких других процессах, и он работал отлично. Я пробовал посылать в окно VNC другие сообщения, и всё равно ничего.
И тут меня опять осенило!
Благодаря очень толстой книге Чарльза Петцольда я тщательно изучал, как процессы Win32 работают внутри системы. У каждого приложения Win32 есть окно, а также «очередь сообщений». Сообщения, вызванные взаимодействием с пользователем, а также сообщения, отправленные самой Windows, поступают в очередь, а само приложение решает, как их обрабатывать.
Не слишком интересно само по себе. Но когда я понял, что достаточно большая необработанная очередь сообщений выступает эвристикой для вмешательства в зависший процесс со стороны менеджера Window Process Manager, я вспотел чистым серотонином.
Не теряя ни секунды, я вернулся к своему коду C, готовясь отправить в главное окно VNC ещё одно сообщение
WM_SHOWWINDOW
. В цикле. Вечном. Итак, множество сообщений WM_SHOWWINDOW
, которые, как я теперь знал, VNC попытается полностью игнорировать… на свой страх и риск.Я скомпилировал и запустил 4 КБ самого свободолюбивого кода в своей жизни. Примерно через три секунды Windows сообщила, что процесс
vncserver.ехе
не отвечает, и сделала предложение, от которого я просто не мог отказаться:Вы хотите завершить этот процесс?
Чёрт возьми, ДА!
Позвольте признаться, что остаток дня я был невыносимо доволен собой.
После нескольких часов, потраченных на переваривание моей новой суперсилы, я решил, как буду её использовать. Просто убить сеанс прямо у него на глазах было слишком просто. У меня была идея получше — исчезнуть совсем.
После боевого крещения с программированием сокетов я понял, что могу написать код, который будет делать две вещи. Сначала он займёт недавно освобождённый порт TCP 5900, ранее занятый невежественным процессом сервера VNC. Потом создаст новое TCP-соединение с VNC-сервером заданной машины. Код будет просто проксировать все данные между двумя сокетами, и Коломбо подумает, что подключается ко мне, тогда как на самом деле будет подключаться к совершенно другому VNC-серверу.
Мой код будет действовать как тайный мост между мной и какой-нибудь другой бедной душой на мой выбор. Это было прекрасно.
Я сразу же начал писать свой поддельный бридж VNC. Коломбо несколько раз подключался ко мне, но я продолжал программировать у него на глазах. Я пришёл к выводу, что он понятия не имеет о моих действиях, хотя я писал очевидные вещи, такие как номера портов и комментарии вроде
// Прощай, жуткий шпион VNC
.Через пару дней я никак не мог заставить код работать правильно. Что ещё хуже, я практически непрерывно работал с чёрным значком VNC в системном трее. Пока он был подключен, я не мог освободить порт, чтобы проверить свой код.
Если бы я тогда знал о
netcat
!В конце концов, нервы не выдержали, всё-таки я был нетерпеливым 17-летним парнем. Снова наблюдая, как белый значок сервера VNC становится чёрным, я психанул, открыл первоначальный код, который заполнял очередь сообщений, и запустил у него на глазах. Я даже подождал пару секунд, прежде чем нажать
End Process
, просто чтобы убедиться, что он это видел.Если нажатие этой кнопки ещё не полностью убедило меня, что оно того стоило, то его прыжок из-за своей крепости мониторов, чтобы быстро подойти ко мне и выпроводить меня из комнаты, определённо, стоил того.
В итоге мне запретили доступ в сеть на две недели. Справедливое наказание, подумал я. Примерно через три недели сервер VNC исчез из загрузочных скриптов и больше нигде не появлялся. Я так и не узнал, сыграл ли мой инцидент какую-то роль в этом или нет, но он полностью разрушил мой план сказочного обогащения на продаже своей пушки VNC угнетённым студентам в компьютерных залах колледжей по всей стране.