Esse artigo faz parte da revista Clube Delphi edição 42. Clique aqui para ler todos os artigos desta edição

Atenção: por essa edição ser muito antiga não há arquivo PDF para download. Os artigos dessa edição estão disponíveis somente através do formato HTML. 

 

Conexões Multithreaded

IP/Port Scan e técnicas de otimização

Você já deve ter ouvido falar em um IP scan ou um Port scan. Basicamente eles têm a função de encontrar em uma rede IPs que estejam com uma determinada porta aberta, e encontrar todas as portas abertas em um determinado IP, respectivamente. Ao longo deste artigo, demonstraremos a implementação de um utilitário com esse propósito.

Visão geral

Desenvolveremos nosso aplicativo dividindo-o em três partes bem definidas, são elas: o "kernel", um componente e a interface gráfica. No kernel, residirá a parte mais interessante de nosso código – ele encapsula uma thread responsável por realizar a conexão. O componente fica encarregado de gerenciar as threads, de acordo com as configurações especificadas, além de notificar a interface gráfica o estado atual de seu trabalho. A interface, por sua vez, exemplificará o uso do componente criado apresentando informações sobre o andamento do processo.

Nosso aplicativo poderá ser utilizado para os mais variados fins. Poderemos usá-lo, por exemplo, para descobrir quais máquinas numa rede são servidores FTP. Para isso, basta que façamos uma pesquisa pelos hosts que estão com a porta 21 aberta, por exemplo. Ainda podemos verificar o comportamento de algum aplicativo suspeito, colocá-lo em execução e verificar se ele abriu alguma nova porta. Poderíamos listar muitas outras possibilidades...

Metodologia

Para verificar se uma determinada porta está aberta, apenas tentaremos nos conectar a ela. Caso a conexão seja estabelecida, contabilizaremos um sucesso; caso contrário, uma exceção será levantada e tratada.

Muitas vezes existe uma dificuldade em identificar se uma aplicação deve ou não utilizar múltiplas threads. Nesse exemplo, veremos a vantagem da dividir o processamento em várias threads – o uso de apenas uma imporia uma grande perda de tempo, pois as tentativas de conexão teriam de esperar "em fila". Essa é a chave do processo: como não há dependências entre as conexões, podemos fazê-las em paralelo, aumentando o desempenho da aplicação.

O kernel

O "kernel", a parte principal da aplicação, é a classe TScan. Para iniciar o exemplo, faça o seguinte: caso o Delphi esteja aberto clique em File | Close All. Crie um novo pacote no Delphi, clicando em File|New|Other>Package (salve-o como “pkScan.dpk”), crie uma unit e salve-a como “untScan.pas”. Veja o conteúdo da unit na Listagem 1.

 

Listagem 1. untScan.pas

unit untScan;

 

interface

 

uses

  Classes, SysUtils, SyncObjs, StdCtrls,

  IdBaseComponent, IdComponent, IdTCPConnection,

  IdTCPClient;

 

type

  TFoundEvent = procedure (Source : TObject; const IP : String;

      const Porta : Integer) of object;

  TThreadTerminate = TNotifyEvent;

 

  TScan = class(TThread)

  private

    FSkt : TIdTCPClient;

    FTimeOut : Integer;

    FFoundEvent : TFoundEvent;

    FFimEvent : TThreadTerminate;

    procedure DoFim;

    procedure Fim(Sender : TObject);

    procedure DoConnect(Sender: TObject);

  protected

    procedure Execute; override;

  public

    constructor CreateSetting

      (FoundEvent : TFoundEvent; FimEvent : TThreadTerminate;

        const IP : String; const Porta, TimeOut : Longint);

    property TimeOut : Integer read FTimeOut write FTimeOut;

  end;

 

implementation

 

constructor TScan.CreateSetting

  (FoundEvent : TFoundEvent; FimEvent : TThreadTerminate;

  const IP: String; const Porta, TimeOut: Integer);

...

Quer ler esse conteúdo completo? Tenha acesso completo