Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 1 марта!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



BackDoor - удалённое администрирование 2

Автор: Danil
WEB-сайт: http://www.danil.dp.ua

- В чем заключается многозадачность Windows?
- Она глючит и работает одновременно.

Начнем с отзывов. Во-первых, спасибо за положительные. Во-вторых, я допустил ошибку, а никто и не увидел. Процесс обработки очереди надо все-таки терминайтить. Но об этом далее. В-третьих, комментариев в коде вполне достаточно. Я так пишу. Охоту к написанию комментариев у меня отбили еще в универе. А если не можешь разобраться, так нафига вообще трепыхаться - ходи на порно-сайты и дыши с присвистом. В-четвертых, объясню почему сервер писался на асме. На это есть 6 причин:

  1. Быстродействие. Все равно быстрее будет работать чем на сях и delphi (не говоря уже о тормознутом визуал бейсике. Такой язык надо в школе изучать - это надо ж, грузить dll-и и запускать с них функции);
  2. Размеры. 11 kb "всунуть" в что-то все таки легче чем, например, 100;
  3. Если мы пишем на асме, то имеем дело с ошибками своими и мелкософта, а не с глюками программера из фирмы Borland. Взять хотя-бы "RadioGroup" в Delphi;
  4. В ранних версиях "DTr", периодически возникала ошибка 10060 асинхронной работы. Только на некоторых компьютерах, но все-таки. Написание сервера на сях не помогло. После выхода версии на асме и сооружения в клиенте процесса обработки очереди приходящих сообщений, у меня еще такой ошибки не возникало;
  5. В своих продуктах фирмы по производству программного обеспечения, любят при ошибке вызывать исключительную ситуацию, на что виндоуз реагирует показом "красивого" окошка с сообщением об ошибке. Некоторые такие реакции не подавляются try-except. Для сервера это, мягко сказать, нежелательно. В асме все проще;
  6. Для борьбы с буржуйскими программами с помощью WINdasm, SoftIce и т.п., ассемблер надо знать. А для того чтобы его знать, на нем иногда надо писать. Завести 2-ой комп и бегать, смотреть на одном окно SoftIce, а на другом доки - это сильно круто.

Теперь продолжим разговор о нашем клиенте. Как я уже говорил, процесс обработки очереди при разсоединении и выходе из проги надо прерывать. Для этого модифицируем нашу процедуру "ClientSocket1Disconnect", вставив в нее вот такой код:


 if not RecvThread.Terminated then
 begin
   while not RecvThread.Terminated do
   begin
     try
       RecvThread.Terminate;
     except
     end;
     sleep(100);
     Application.ProcessMessages;
   end;
 end;
 LstRbeg:=nil;
 LstRend:=nil;
 

Также нас интересует событие, происходящее перед выходом из клиента. Выделим нашу форму ("Form1"), перейдем в "Object Inspector" на закладку "Events" и 2 раза "click"-нем по "onClose". Перейдем в раздел кода и запишем:


 // Выход из проги
 procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
 begin
   Action := caNone;
   if constat then
     Form1.Button1Click(Sender);
   Application.ProcessMessages;
   Application.Terminate;
   Halt(1);
 end;
 

Теперь поговорим о визуализации и удобстве работы с клиентом. Кнопки, которые отвечают за посылание серверу команд, надо как-то выделить. Для этого воспользуемся объектом "ImageList" с закладки "Win32" ("ImageList1"). Помещаем его на форму и с помощью правой кнопки мыши добавляем в него изображения для кнопок. Теперь нужно выделить "ToolBar1" и в его свойстве "Images", из всплывающего списка, поставить "ImageList1". После этого перейдем на "ToolButton1", в свойстве "ImageIndex", выберем нужный рисунок. Для отображения "всплывающей" подсказки в свойстве "ShowHint" поставим "true", а в свойстве "Hint", напишем "Кнопка № 1". Очень информативно.

Сканер для сервера.

Допустим, мы знаем, что серверная часть запущена у человека (это звучит гордо), пользующегося услуами провайдера "Slow". Мы также знаем пространство адресов этого провайдера. Но мы не знаем, какой адрес даст провайдер этому челу.

Или у нас есть локалка. Почему-то иногда прога путает адреса на плюс-минус два. Почему - до сих пор не знаю (данная проблема была замечена не мной), но если кто знает, то пусть отпишет в "Отзывы".

Или мы изменили порт, а какой забыли.

Для всего этого нам нужен сканер по адресам и портам. То, о чем пойдет речь далее, можно использовать не только для нашего сервера. Итак, в Delphi, в проекте нашего сервера, выбираем в верхнем меню "File"-->"New Form". Пусть это будет "Form2". В свойстве "Caption" пишем "Сканер". Размещаем на форме компоненты:

Edit1
С какого порта начинать сканирование;
Edit2
По какой порт;
Edit3
Первые 3 цифры адреса в виде "xxx.xxx.xxx.xxx" (без точки в конце);
Edit4, Edit5
Диапазон последней цифры адреса;
Edit6
Время ожидания соединения (в секундах);
Button1
Начать/прекратить сканирование;
Memo1
Отчет сканирования;
ProgressBar1, ProgressBar2 (Win32)
Для визуализации процесса перебора по адресам и портам соответственно;
ClientSocket1
И так понятно.

Теперь на "Form1" лепим кнопку, обзываем ее "Scaner" и нажимаем на ней два раза. В разделе кода пишем :


 // Scaner
 procedure TForm1.Button2Click(Sender: TObject);
 begin
   Form2.WindowState := wsNormal;
   Form2.Visible := true;
   Form2.SetFocus;
 end;
 

В раздел "uses" добавляем "Unit2". Переходим на "Form2". Два раза нажимаем на "Button1", на события "onConnect" и "onError" в "ClientSocket1" и на "onClose" в "Form2". Вот текст модуля "Unit2.pas":


 unit Unit2;
 
 interface
 
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   ComCtrls, StdCtrls, ScktComp;
 
 type
   TForm2 = class(TForm)
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
   Edit4: TEdit;
   Edit5: TEdit;
   Edit6: TEdit;
   Button1: TButton;
   Memo1: TMemo;
   ProgressBar1: TProgressBar;
   ProgressBar2: TProgressBar;
   ClientSocket1: TClientSocket;
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure Button1Click(Sender: TObject);
   procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
   procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
   private
     { Private declarations }
   public
     { Public declarations }
 end;
 
 var
   Form2: TForm2;
   Rez11: Boolean = false;
   Bool: Boolean = false;
 
 implementation
 
 {$R *.DFM}
 
 //Close Scaner
 procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
 begin
   // если запущен, то прерываем процесс
   if Rez11 then
   begin
     Action := caNone;
     Form2.Button1Click(Sender);
   end;
 end;
 
 // Включить/отключить сканер
 procedure TForm2.Button1Click(Sender: TObject);
 var
   I, J, K: Integer;
   DopStr: string;
 begin
   if Rez11 then
   begin
     // прервать сканирование
     if Application.MessageBox('Прервать сканирование?', 'Сканер', mb_YesNo + mb_IconQuestion) = idYes then
     begin
       Rez11 := false;
       Bool := false;
     end;
   end
   else
   begin
     // запуск сканера
     if StrToInt(Form2.Edit2.Text) < StrToInt(Form2.Edit1.Text) then
     begin
       Application.MessageBox('Неверно указан диапазон для портов','Сканер', mb_Ok + mb_IconStop);
       exit;
     end;
 
     if StrToInt(Form2.Edit5.Text) < StrToInt(Form2.Edit4.Text) then
     begin
       Application.MessageBox('Неверно указан диапазон IP-адресов','Сканер', mb_Ok + mb_IconStop);
       exit;
     end;
 
     Form2.Caption:='Идет сканирование...';
     Form2.Memo1.Lines.Clear;
 
     try
       DopStr := trim(Form2.Edit3.Text);
       Rez11 := true;
       Form2.Button1.Caption := 'Отмена';
       Form2.Memo1.Lines.Add('-------------' + #13 + #10 + '===========');
 
       // начальные значения для порта и адреса
       I := StrToInt(Form2.Edit1.Text);
       J := StrToInt(Form2.Edit4.Text);
 
       try
         Form2.ProgressBar1.Max := StrToInt(Form2.Edit2.Text) - StrToInt(Form2.Edit2.Text) + 2;
         Form2.ProgressBar1.Position := 1;
         Form2.ProgressBar2.Max := StrToInt(Form2.Edit5.Text) - StrToInt(Form2.Edit4.Text) + 2;
         Form2.ProgressBar2.Position := 1;
 
         // цикл по адресам
         while I <= StrToInt(Form2.Edit2.Text) do
         begin
           J := StrToInt(Form2.Edit4.Text);
           // цикл по портам
           while J <= StrToInt(Form2.Edit5.Text) do
           begin
             Application.ProcessMessages;
             if not Rez11 then
               break;
             Form2.ClientSocket1.Active := false;
             Form2.ClientSocket1.Port := I;
             Form2.ClientSocket1.Address := trim(DopStr) + '.' + trim(IntToStr(J));
 
             try
               // попытка соедениться
               Form2.ClientSocket1.Active := true;
               Application.ProcessMessages;
 
               // время ожидания
               Bool := true;
               K := round(StrToInt(Form2.Edit6.Text) * 1000 / 50);
               while Bool do
               begin
                 Sleep(50);
                 Application.ProcessMessages;
                 dec(K);
                 if K=0 then
                 begin
 
                   try
                     Form2.ClientSocket1.Active:=false;
                   except
                   end;
                   break;
                 end;
               end;
             except
             end;
 
             Application.ProcessMessages;
             Form2.ProgressBar2.Position := Form2.ProgressBar2.Position + 1;
             inc(J);
           end;
           inc(I);
           Application.ProcessMessages;
 
           if not Rez11 then
             break;
 
           Form2.ProgressBar1.Position := Form2.ProgressBar1.Position + 1;
         end;
         Form2.ProgressBar2.Position := Form2.ProgressBar1.Position + 1;
         Form2.ProgressBar1.Position := Form2.ProgressBar1.Position + 1;
       except
         Application.MessageBox('Ошибка выполнения операции', 'Сканер', MB_Ok + mb_IconStop);
       end;
       Form2.Button1.Caption := 'Сканер';
       Form2.ProgressBar1.Position := 0;
       Form2.ProgressBar2.Position := 0;
       Form2.Caption := 'Сканер по адресам и портам';
       if Rez11 then
       begin
         Application.MessageBox('Процедура сканирования по адресам и портам закончена.', 'Сканер', mb_Ok + mb_IconAsterisk);
         Form2.Memo1.Lines.Add('-----------------'+#13+#10+'========== ВСЕ АДРЕСА И ПОРТЫ ОТСКАНИРОВАНЫ'+#13+#10+#13+#10);
         Rez11 := false;
       end
       else
         Form2.Memo1.Lines.Add('------------'+#13+#10+'============== ПРЕРВАНО НА порт-'+IntToStr(I)+', адрес-'+trim(DopStr)+'.'+IntToStr(J-1)+#13+#10+#13+#10);
     except
       Application.MessageBox('Ошибка инициализации процесса.','Сканер',mb_Ok+mb_IconStop);
     end;
     Form2.Caption:='Сканер по адресам и портам';
   end;
 end;
 
 // Есть ответ сервера
 procedure TForm2.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
 begin
   // если соеденились вывести сообщение
   Form2.Memo1.Lines.Add('***' + #13 + #10 + 'Порт: ' + IntToStr(Form2.ClientSocket1.Port) + ' ' + 'Адрес: ' + Form2.ClientSocket1.Address + ' - ЕСТЬ ОТВЕТ' + #13 + #10);
   Application.ProcessMessages;
   // прервать время ожидания
   try
     Form2.ClientSocket1.Active := false;
   except
   end;
   Bool := false;
 end;
 
 // Ошибка при соединении
 procedure TForm2.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
 begin
   // прервать время ожидания если ошибка
   ErrorCode := 0;
   Bool := false;
 end;
 
 end.
 

Теперь проверим. Запускаем сервер и клиент. Жмем кнопку "Сканер". В "Edit1" пишем "10001", в "Edit2" - "10001", в "Edit3" - "127.0.0", в "Edit4" - "1", в "Edit5" - "254", в "Edit6" - "1". Все значения без кавычек. Жмем нашу кнопку начала сканирования. Все, проверка закончена.

P.S. Статья и программа предоставлена в целях обучения и вся ответственность за использование ложится на твои хилые плечи.




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS