понедельник, 30 декабря 2013 г.

Сканер портов на TCPClient

Сегодня я хочу рассказать о так называемых сканерах портов. Если кто-то не в курсе, то эта специальная программа для определения открытых портов на удаленной машине.
Как это будет работать.
Программа пытается подключиться к какому-то порту из заданного диапазона. Если подключение произошло, то говорим пользователю что порт открыт, в противном же случае, говорим что нет, после переходим к следующему порту.
Практика.
Для начала нам необходимо бросить на форму следующие компоненты: 2 Label'а, 2 Edit'а, одну кнопку, компонент Memo для вывода информации о открытых (закрытых) портах, и наконец начинку нашей программы - компонент TCPClient, с закладки Internet. Измените свойство Caption у Label'ов следующим образом: Label1 - Начальный порт, Label2 - Конечный порт. Напротив каждого из Label'ов расположите Edit'ы... Надпись на кнопке можете сделать какую хотите... Итак, осталось написать лишь сам код программы... Весь код нашей программы будет состоять лишь из одного метода (процедуры). Кликните дважды на кнопке, перед вами появится окно с исходным кодом. Вот как она должна выглядеть:

procedure TForm1.Button1Click(Sender: TObject);
var
  i:Integer;
  ip:String;
begin
  ip:='127.0.0.1'; //По умолчанию сканируем себя
  if not InputQuery('Attention','Enter IP-address',ip) then exit; //Запрашиваем адрес компа.
  for i:=StrToInt(Edit1.Text) to StrToInt(Edit2.Text) do //Запускаем цикл
  begin
    TcpClient1.RemotePort:=IntToStr(i); //Устанавливаем порт
    TcpClient1.Open; //Пытаемся его открыть
    if TcpClient1.Connected then Memo1.Lines.Add(IntToStr(i)+' open'); //Если удалось, то сообщаем об этом
    TcpClient1.Close; //Закрываем порт.
  end;
end;


Вот и готов наш простейший сканер портов! Введите начальный порт, конечный порт, жмите кнопку, в появившемся окне набирайте IP-адрес жертвы и в бой.

четверг, 26 декабря 2013 г.

Запрет запуска второй копии программы

program Project1;
 
uses
  Windows, Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};
 
{$R *.res}
 
procedure BringItToFront(hWindow : HWND);
var
   fgThread : Cardinal;
   myAppThread : Cardinal;
begin
   fgThread := GetWindowThreadProcessId(GetForegroundWindow, nil);
   myAppThread := GetCurrentThreadId;
 
   AttachThreadInput(fgThread, myAppThread, True);
   ShowWindow(hWindow, SW_RESTORE);
   BringWindowToTop(hWindow); // Это будет работать гарантированно
   AttachThreadInput(fgThread, myAppThread, False);
end;
 
const
   MainFormCaption = 'Test';
var
   hMutex : THandle;
   hPrevWin : HWND;
begin
   ReportMemoryLeaksOnShutdown := True;
 
   Application.Initialize;
   Application.Title := 'MyProgram';
 
   hMutex := CreateMutex(nil, True, PChar(Application.Title));
   if (GetlastError = ERROR_ALREADY_EXISTS) or (GetlastError = ERROR_ACCESS_DENIED) then
   begin
      Application.MessageBox('Программа уже работает!', PChar(Application.Title),
         MB_ICONWARNING or MB_OK);
 
      // Ищем не Application.Title, а заголовок формы
      hPrevWin := FindWindow('TForm1', MainFormCaption);
      if hPrevWin <> 0 then BringItToFront(hPrevWin);
      Exit;
    end;
 
   Application.MainFormOnTaskbar := True;
   Application.CreateForm(TForm1, Form1);
   Application.CreateForm(TForm2, Form2);
   Application.Run;
end.

вторник, 3 декабря 2013 г.

Необязательный параметр в процедуре (Вариант 3. Значение по умолчанию)

Иногда, Вы можете избежать потребности в перезагрузке методом OVERLOAD, давая значения конечных параметров по умолчанию. Вызывающая программа может тогда вызвать с или без этих конечных параметров.

procedure MyProc(a : Byte; b : Byte = 23);

Может быть вызвана 2-мя способами:

MyProc(15, 16);
MyProc(45); // По умолчанию b будет равно 23

Необязательный параметр в процедуре (Вариант 2. Использование Overload)

Директива Overload позволяет Вам иметь различные версии одинаково названной функции или процедуры с различными параметрами. Это полезно, когда есть множество путей, которыми код может захотеть использовать подпрограмму. Например, если подпрограмма - конструктор класса, Вы можете хотеть иметь одну версию Create, которая устанавливает значения по умолчанию, и другую, которая берет эти значения как параметры. 

Вы должны закодировать директиву Overload перед любыми другими директивами. 

При запросе перезагруженной (overloaded) подпрограммы, Delphi выбирает соответствующую версию, основанную сначала на номере параметров, затем на типах параметра. Если он не может принять решение, он выдаёт исключение. 

Когда количество параметров такое же, он всегда сначала пробует удовлетворить самые простые/наименьшие типы данных - например, вышеупомянутое значение 23 удовлетворил бы параметр Byte, чемInteger параметр. 

Пример использования

function Summ(A, B: integer): integer; overload;       // Версия 1 функции Summ
begin
  result:= A+B;
end;

function Summ(A,B,C: Integer): integer; overload;  // Версия 2 функции Summ
begin
 result:=A+B+C;
end;

Function ShowSumm;
begin
  ShowMessage(Summ(5,10));      // Используется версия 1 функции Summ
  ShowMessage(Summ(3,7,12));   // используется версия 2 функции Summ
end;

Если позволяет ситуация и чтобы не писать много одинакового кода, можно модернизировать версию 1 примера.

function Summ(A, B: integer): integer; overload;       // Измененная версия 1 функции Summ
begin
  result:= Summ(A,B, 0);
end;

В данном случае, мы вызываем версию с 3-мя параметрами, передавая два числа и 0, который не влияет на сумму). Но это частный случай.

Необязательный параметр в процедуре (Вариант 1. Открытые массивы)

Рассмотрим открытые массивы, которые позволяют передавать в функцию или процедуру различное количество параметров. В качестве параметров можно передать либо открытый массив элементов одинакового типа, либо массивы констант различного типа. В приведенном ниже примере объявляется функция, которой в качестве параметра должен передаваться открытый массив целых чисел. 


function AddEmUp( A: array of integer ): integer;


В открытом массиве можно передавать переменные, константы или выражения из констант. Ниже приведен пример, который демонстрирует вызов функции AddEmUp с передачей ей нескольких различных элементов. 


const
  j = 23;
var
  i, Rez: integer;
begin
   i := 8;
   Rez := AddEmUp( [i, 20, j, 43] );
end; 


Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf. Для иллюстрации их использования ниже приведен текст функции AddEmUp, которая возвращает сумму всех переданных ей элементов массива A. 


function AddEmUp( A: array of integer ): integer;
var
   i: integer;
begin
   Result := 0;
   for i := Low(A) to High(A) do
       Inc( Result, A[i] );
end; 


Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий: 

procedure WhatHaveIGot( A: array of const ); 


Вызвать объявленную выше функцию можно, например, с помощью такого оператора:


procedure WhatHaveIGot( ['Text', 10, 5.5, @WhatHaveIGot, 3.14, true, 'c'] ); 


При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом: 


PVarRec = ^TVarRec;
TVarRec = record case
  Byte of vtInteger: (VInteger: Integer; VType: Byte);
        vtBoolean: (VBoolean: Boolean);
        vtChar: (VChar: Char);
        vtExtended: (VExtended: PExtended);
        vtString: (VString: PShortString);
        vtPointer: (VPointer: Pointer);
        vtPChar: (VPChar: PChar);
        vtObject: (VObject: TObject);
        vtClass: (VClass: TClass);
        vtWideChar: (VWideChar: WideChar);
        vtPWideChar: (VPWideChar: PWideChar);
        vtAnsiString: (VAnsiString: Pointer);
        vtCurrency: (VCurrency: PCurrency);
        vtVariant: (VVariant: PVariant);
        vtInterface: (VInterface: Pointer);
        vtWideString: (VWideString: Pointer);
        vtInt64: (VInt64: PInt64);
end;


Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно из ниже приведенных значений.

const
  vtInteger = 0;
  vtBoolean = 1;
  vtChar = 2;
  vtExtended = 3;
  vtString = 4;
  vtPointer = 5;
  vtPChar = 6;
  vtObject = 7;
  vtClass = 8;
  vtWideChar = 9;
  vtPWideChar = 10;
  vtAnsiString = 11;
  vtCurrency = 12;
  vtVariant = 13;
  vtInterface = 14;
  vtWideString = 15;
  vtInt64 = 16; 


Поскольку массив констант способен передавать данные разных типов, это может вызвать определенные затруднения при создании обрабатывающей полученные параметры функции или процедуры. В качестве примера работы с таким массивом рассмотрим реализацию процедуры WhatHaveIGot, которая просматривает элементы полученного массива параметров и выводит их тип. 


procedure WhatHaveIGot( A: array of const );
var
   i: integer; TypeStr: string;
begin
   for i := Low(A) to High(A) do begin
     case A[i].VType of
          vtInteger : TypeStr := 'Integer';
          vtBoolean : TypeStr := 'Boolean';
          vtChar : TypeStr := 'Char';
          vtExtended : TypeStr := 'Extended';
          vtString : TypeStr := 'String';
          vtPointer : TypeStr := 'Pointer';
          vtPChar : TypeStr := 'PChar';
          vtObject : TypeStr := 'Object';
          vtClass : TypeStr := 'Class';
          vtWideChar : TypeStr := 'WideChar';
          vtPWideChar : TypeStr := 'PWideChar';
          vtAnsiString : TypeStr := 'AnsiString';
          vtCurrency : TypeStr := 'Currency';
          vtVariant : TypeStr := 'Variant';
          vtInterface : TypeStr := 'Interface';
          vtWideString : TypeStr := 'WideString';
          vtInt64 : TypeStr := 'Int64';
    end;
   ShowMessage( Format( 'Array item %d is a %s', [i, TypeStr] ) );
  end;
end;

Найдено на http://programmersforum.ru/