Наверное, каждый программист рано или поздно начинал писать
заподлянки. Иногда - для того, чтобы подшутить над другом, иногда -
не просто подшутить :-). И главной проблемой в этом нелёгком деле
(не касаясь собственно самих заподлянских действий) является скрытие
заподлянки или вируса от обнаружения. Чаще всего методы, предлагаемые
различными авторами, сводятся к сокрытию программы от 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
и выдаёт сообщение об ошибке. Ну вот, я честно предупредил тебя о возможных трудностях, теперь пора 
начинать...

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии