Наверное, каждый программист рано или поздно начинал писать
заподлянки. Иногда — для того, чтобы подшутить над другом, иногда —
не просто подшутить :-). И главной проблемой в этом нелёгком деле
(не касаясь собственно самих заподлянских действий) является скрытие
заподлянки или вируса от обнаружения. Чаще всего методы, предлагаемые
различными авторами, сводятся к сокрытию программы от CTRL — ALT —
DEL, что эффективно только в WINDOWS 95/98/ME. Иногда предлагается простое
прописывание проги в реестр, что легко обнаруживается с помощью
MSCONFIG.EXE или REGEDIT.EXE. Недавно я разработал способ, позволяющий обойти все (почти)
вышеуказанные меры предосторожности, про который сейчас и пойдёт речь.
Но прежде чем писать программу, небольшое лирическое отступление о
программировании в WINDOWS (кто не хочет, может не читать). 

В Windows каждое окно имеет уникальный идентификатор — HANDLE
или просто НЭНДЛ, получив который, можно управлять этим окном. Так,
например, если приложение однооконное, то закрытие данного окна
приведёт к завершению работы всего приложения.
В WINAPI для описания хэндла существует тип HWND, т.е.
описание переменной в С++ имеет вид:

HWND H;»

Главной задачей является получение этого самого идентификатора окна. Самый простой вариант — использование
FindWindow: 

HWND H = FindWindow(<char *ClassName>, <char *Caption>);»

Возвращает NULL, если ни одно окно не найдено. Обязательно это проверяй!

Параметр Caption — заголовок нужного окна (NULL — то независимо от него),
а ClassName — имя класса окна, находится с помощью программ:

1) WinSight — входит в поставку C++ Builder/Delphi. Файл — ws32.exe, находится в папке BIN среды разработки.
2) Spy++ — в поставку MS Visual C++ .NET.

Программы эти выводят список окон (открытых в системе) и их
параметров. Для нас важны имя класса окна и его заголовок. К примеру,
открой Калькулятор, имя класса его окна —
"SciCalc" (соблюдай регистр имён везде), заголовок — «Калькулятор». Потом
найди эти параметры в WinSight. Теперь ты знаешь, что надо подставлять
в FindWindow в другой раз. Замечу, что иногда имя класса окна не всегда
точно совпадает с выводимым в программе. Например, Диспетчер Задач имеет в WinSight класс
"#32770:Dialog", а в реальности — «#32770». Я долго матерился, а особенно тогда, когда
нашёл реальное имя класса окна 🙂 Кстати, FindWindow не ищет дочерние окна, но нам это и не нужно.
Всё, хэндл ты умеешь находить. Теперь делай с ним всё, что хочешь.
Например, функция EnableWindow делает доступным или недоступным окно:

EnableWindow(<HWND H>, <bool Enabled>);»

Где H — хэндл, предварительно найденный FindWindow, а Enabled —
состояние, в которое переводится окно (true — доступно, false — нет).
Очень интересно состояние окна при Enabled = false.

Открой новый проект C++ Builder, перенеси кнопку на форму и впиши
в Button1Click:

HWND H = FindWindow(«SciCalc», «Калькулятор»);
if (H == NULL) //
если не найдено
{
Caption = «Облом»;
return;

static bool e = false;
EnableWindow(H, e);
e = !e;
Caption = «Нашли»;

Запускай проект и открывай Калькулятор. Теперь пощёлкай на кнопке.
После щелчка он становится недоступным, а после следующего переходит
в нормальное состояние. Ну что, нравится ? Да, красиво смотрится…  

Есть еще множество функций по управлению окнами:
SetWindowText, MoveWindow и другие, которые ты можешь найти в HELP — они там рядом.
Их названия достаточно говорят о себе. Во всех есть параметр типа 
HWND и всё остальное — понятные параметры.  Отдельно рассмотрю вопрос о закрытии окна. Есть функция
CloseWindow, но вопреки названию она только сворачивает данное окно. Для закрытия 
используется следующий оператор:

SendMessage(H, WM_CLOSE, NULL, NULL);

Здесь H — хэндл окна.

Этот метод использует сообщения WINDOWS — тоже ещё одна интересная
тема, но требующая отдельного разговора. Ну вот, теперь ты знаешь теорию, перейдём к нашей задаче.

Задача — написание программы, прописывающейся в автозапуск и
находящейся там (если не обнаружат :-)), скрывающейся от обнаружения.
Пока… Но самая главная фишка заключается в способе реализации,
который состоит в следующем: пользователь может обнаружить программу, находящуюся в автозагрузке,
через MSCONFIG.EXE или через редактор реестра WINDOWS —
REGEDIT.EXE.

Но если работающая заподлянка будет периодически (например, каждые полсекунды)
проверять, открыто ли окно MSCONFIG или REGEDIT, и если открыто — убивать
себя из автозапуска, а в противном случае восстанавливать, то никто не
догадается, что действительно она работает.
Этот простой по сути способ — очень действенная вещь, и мало кто устоит перед ним.
Но несмотря на все преимущества этого способа, он имеет, конечно, и
некоторые недостатки. Так, например, в вошедших в
WINDOWS 2000/XP существует диспетчер задач, позволяющий завершать процессы,
среди которых будет светиться и данная заподлянка. Есть несколько вариантов решения этой проблемы. Во-первых, можно
дать файлу имя типа безобидного SPOOL.EXE. Этот способ хорош, но не
настолько, чтобы не насторожить внимательную жертву. Во-вторых, можно
отлавливать появление диспетчера задач и, например, закрывать его, или
делать недоступным с помощью EnableWindow(H, false);, а можно закрывать
и выводить сообщение; вот так, к примеру:

SendMessage(H, WM_CLOSE, NULL, NULL); // Посылка мессаги окну : закройся
Application->MessageBox(«Ошибка диспетчера задач: невозможно запустить!», «Внимание», MB_OK);

Этот код закрывает диспетчер задач по известному дескриптору (хэндлу) H
и выдаёт сообщение об ошибке. Ну вот, я честно предупредил тебя о возможных трудностях, теперь пора 
начинать…

Оставить мнение

Check Also

LUKS container vs Border Patrol Agent. Как уберечь свои данные, пересекая границу

Не секрет, что если ты собрался посетить такие страны как США или Великобританию то, прежд…