Programming: Delphi
Сканируем порты на Delphi
Автор: freetonik
Источник:
Всеобщие приветы! Сегодня будем вместе кодить
настоящий сканер портов! Без лишних прелюдий начнем.
Что нам понадобится? Delphi (исходник версии 6.0 !) и стандартные
компоненты. Если быть точнее, то: 6 Edit’ов, один ListBox, две кнопки (у
меня – два компонента SuperButton), 3 Label’а, Memo, StatusBar, два
PopupMenu и наконец главный компонент – powersock из закладки FastNet.
Чтобы понять, как все расставить на форме – смотрите скриншот: ниже.
Расставили? Не забудьте поставить Caption’ы кнопкам и лейблам. Тут уже
на ваше усмотрение – хотите вместо «Скан» наберите «Сканируйся, дурацкая
штуковина!!!» - пожалуйста! От этого программа хуже работать не будет
=)
Ну вот, с интерфейсом разобрались. Теперь самое время понять, как все
будет работать. Видите – там где написано «IP» стоят три Едита и еще
два справа? Так вот – тут будет вводится диапазон IP-адресов. Первые три
блока не изменяются, а последний может варьироваться от 1 до 255. Так что
наш сканер разведывает наличие открытых портов не на одной машине, а на
нескольких! В самом проекте я ввел адрес 127.0.0.1/1, чтобы при случайном
нажатии кнопки «Скан» не вылетала ошибка. Справа в листбоксе будут
порты, в которые будет коннектиться программка. Значения берутся из файла
ports.txt, туда их можно вставлять как вручную с помощью любого текстового
редактора, так и в программе. Для этого нам и понадобится PopupMenu – при
клике правой кнопкой на список портов будет появляться меню, где можно
добавить и удалить порт (в моем исходнике это PopupMenu2). Свойство
«Popupmenu» компонента ListBox’ нужно сделать равным «PopupMenu2», а
свойство «Popupmenu» memo нужно сделать равным «PopupMenu1». Теперь
отредактируй эти самые менюшки. Кликни два раза по ним и добавь в первое
меню: «копировать» и «очистить», а во второе – «добавить порт» и
«удалить». Под едитами есть еще один едит – там указывается пауза в
миллисекундах. Для чего нужна пауза в сканере? Когда программа соединяется
с портом (или пытается), то это увидит администратор в логах. Если
сканирование делать без пауз, то есть сразу во все порты, то админ увидит
неладное и примет меры. Так что пауза нужна! И помните – в секунде 1000
миллисекунд.
Все! Теперь будем шкодить!
Процедура нажатия на кнопку «Скан»:
procedure TForm1.Button1Click(Sender:
TObject); begin Edit1.Enabled := false; Edit2.Enabled :=
false; Edit3.Enabled := false; Edit4.Enabled :=
false; Edit5.Enabled := false; speedbutton1.Enabled :=
false; speedbutton2.Enabled := true; listbox1.Enabled :=
false;
Memo1.lines.add('Начало
сканирования'); go:=true; it:=0; lastIP:=strtoint(edit4.text); NextIP; s.Connect;
Memo1.lines.add('Сканирование завершено'); Edit1.Enabled :=
true; Edit2.Enabled := true; Edit3.Enabled := true; Edit4.Enabled
:= true; Edit5.Enabled := true; speedbutton2.Enabled :=
false; speedbutton1.Enabled := true; listbox1.Enabled :=
true; s.Disconnect; end;
Тут следует напомнить, что именем «s» я назвал powersock. Для
краткости. И еще – в общие переменные я поместил:
It,lastIP:integer; go:boolean;
В первой численной переменной будет храниться последний ip-адрес, а
значение go показывает, запущено сканирование или нет. Как вы наверное
заметили, при сканировании вызывается процедура NextIP. Вот ее код:
procedure TForm1.NextIP; begin s.disconnect; if
it=listbox1.Items.Count then begin inc(lastIP); s.Host :=
edit1.text +'.'+ edit2.text + '.'+ edit3.text +
'.'+ inttostr(lastIP); It:=1; s.port:=strtoint(listbox1.items.Strings[it-1]); end
else begin inc(It); s.port:=strtoint(listbox1.items.Strings[it-1]); end; statusbar1.SimpleText
:= 'Scanning '+s.Host+' : '+inttostr(s.port); end;
Именно она и производит скан портов, значения которых процедура берет
из листбокса. Со сканом разобрались. Теперь кнопка «Стоп», по нажатию
на которую сканирование останавливается.
procedure TForm1.Button2Click(Sender:
TObject); begin go:=false; memo1.Lines.Add('Сканирование
отменено'); statusbar1.Simpletext := ''; s.cancel;
Edit1.Enabled := true; Edit2.Enabled :=
true; Edit3.Enabled := true; Edit4.Enabled := true; Edit5.Enabled
:= true; speedbutton1.Enabled := true; speedbutton2.Enabled :=
false; listbox1.Enabled := true; end;
Как видите, тут все проще. Значение go становится равным false (то есть
ложь), в мемо добавляется надпись, а powersock’у делается cancel.
Теперь нужно прописать две процедуры для самого powersock’а: onConnect
и onConnectionFailed. Вот листинги:
procedure TForm1.sConnect(Sender: TObject); begin if not
go
then begin s.Disconnect; exit; end; memo1.lines.add('Connect
on '+s.host+' : '+inttostr(s.port)); NextIP; if
lastIP>strtoint(edit5.text) then begin memo1.Lines.Add('Scan
complete'); statusbar1.Simpletext := ''; go:=false; Edit1.Enabled
:= true; Edit2.Enabled := true; Edit3.Enabled :=
true; Edit4.Enabled := true; Edit5.Enabled :=
true; speedbutton1.Enabled := true; speedbutton2.Enabled :=
false; listbox1.Enabled := true; exit; end; if go then
s.connect else exit; end;
И соответственно, вторая процедура:
procedure TForm1.sConnectionFailed(Sender:
TObject); begin if not go
then begin s.disconnect; exit; end; NextIP; if
lastIP>strtoint(edit5.text)
then begin memo1.Lines.Add('Сканирование
завершено'); statusbar1.Simpletext :=
''; go:=false; Edit1.Enabled := true; Edit2.Enabled :=
true; Edit3.Enabled := true; Edit4.Enabled := true; Edit5.Enabled
:= true; speedbutton1.Enabled := true; speedbutton2.Enabled :=
false; listbox1.Enabled := true; exit; end; if go then
s.connect else exit; end;
Тут следует заметить, что когда идет строчка if go then… это
эквивалентно if go=true then…
Тут, надеюсь, все ясно. Будут вопросы – пишите. Теперь перейдем к
меню.
procedure TForm1.N121Click(Sender:
TObject); begin memo1.CopyToClipboard; end;
procedure TForm1.N131Click(Sender:
TObject); begin memo1.Clear; end;
Первая процедура – для копирования содержимого memo (там высвечиваются
данные о сканировании) в буфер обмена, а вторая очищает memo. Напомню, что
это было popupmenu1 . Теперь второе меню:
procedure TForm1.Add1Click(Sender:
TObject); begin listbox1.Items.Add(inputbox('Add
port...','Port:','')); end;
procedure TForm1.Delete1Click(Sender:
TObject); begin listbox1.Items.Delete(listbox1.itemindex); end;
Первая добавляет в листбокс новый порт с помощью вызова окошка
inputbox. Вторая удаляет выделенный порт из списка. Все просто, как два
пальца об асфальт! =)
Дважды кликни по форме – появится редактор кода. Тут нужно ввести
следующее:
procedure TForm1.FormCreate(Sender:
TObject); begin listbox1.Items.LoadFromFile('ports.txt'); memo1.clear; memo1.lines.add('Port
scanner by freetonik'); memo1.lines.add(''); end;
Внутри процедуры выполняется четыре действия – сначала в листбокс
грузится содержимое файла ports.txt. Затем очищается memo1. Тут же
добавляется строчка с описанием. Ее можно опустить или написать что-то
типа «Мой супер-сканер». И последним добавляется пустая строка в мемо.
При закрытии формы нужно сохранить новые добавленные порты в файл
ports.txt.
procedure TForm1.FormClose(Sender: TObject; var Action:
TCloseAction); begin listbox1.Items.SaveToFile('ports.txt'); end;
Все тут ясно? Вот и хорошо!
В шестом едите хранится значение паузы между коннектом. При изменении
нужно тут же посылать это значение:
procedure TForm1.Edit6Change(Sender: TObject); begin if
edit6.text='' then s.TimeOut:=0; if edit6.text='' then
exit; s.TimeOut := strtoint(edit6.text); end;
У компонента powersock (s) есть свойство timeout – это и есть пауза.
Вот мы и закончили! Неплохо накодили, да? Если тебе что-то непонятно –
то попробуй разобрать исходник, который идет вместе с журналом. Если есть
еще вопросы – пишите на tonik@mail.kz –
ответчу всем!
freetonik
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.
© 2005
|