⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 通过核心交换机 检测局域网中的arp病毒
💻 PAS
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdTelnet, StdCtrls, ComCtrls,Commctrl,ScktComp, RzListVw,strtools, ImgList,
  AppEvnts, ToolWin, ExtCtrls,ShellAPI,winSock2;

type
  TIpMacRec=record  //如果修改了TIpRec结构,TGate.dat必须删除之后重新运行.
      ip:integer;
      macS:string[65];
      hostName:String[40];
  end;

  TForm1 = class(TForm)
    IdTelnet1: TIdTelnet;
    ListView1: TRzListView;
    ImageList1: TImageList;
    StatusBar1: TStatusBar;
    EchoSocket9999: TClientSocket;
    ToolBar1: TToolBar;
    tbStart: TToolButton;
    tbSave: TToolButton;
    tmFlashHost: TTimer;
    tbMerge: TToolButton;
    tbOpenIpMac: TToolButton;
    reIPMAC: TRichEdit;
    ToolButton1: TToolButton;
    Panel1: TPanel;
    reMemo1: TRichEdit;
    procedure WMASyncSMBEcho(var msg: TMessage); message UM_SMBEcho;
    procedure IdTelnet1DataAvailable(Sender: TIdTelnet;const Buffer: String);
    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn);
    procedure ListView1Compare(Sender: TObject; Item1, Item2: TListItem;Data: Integer; var Compare: Integer);
    procedure IdTelnet1Status(ASender: TObject; const AStatus: TIdStatus;const AStatusText: String);
    procedure EchoSocket9999Error(Sender: TObject; Socket: TCustomWinSocket;ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure FormCreate(Sender: TObject);
    procedure tbStartClick(Sender: TObject);
    procedure ListView1DblClick(Sender: TObject);
    procedure tbSaveClick(Sender: TObject);
    procedure tmFlashHostTimer(Sender: TObject);
    procedure tbOpenIpMacClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure tbMergeClick(Sender: TObject);
    procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure reMemo1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
  private
    procedure mySendCommand(cmd: String);
    procedure ciscoOk;
    { Private declarations }
  public
    { Public declarations }
  end;

var
   Form1: TForm1;
   ColumnToSortR:integer;
   SMBCount,telnetStatus,conputerCount:integer;
   textSY:String;
   inFlashHost:boolean;
   ht:PLVHitTestInfo;//得到鼠标点击的 listView 上的行号、列号用.
implementation

{$R *.dfm}
procedure TForm1.mySendCommand(cmd:String);
var
   i:integer;
begin
   for i:=1 to length(cmd) do IdTelnet1.SendCh(cmd[i]); //发送用户名
   IdTelnet1.SendCh(#13);
end;

procedure TForm1.IdTelnet1DataAvailable(Sender: TIdTelnet;const Buffer: String);
var
   i,pos0:integer;
   haveDataLine:boolean;
   s,sLine,text,IPs:string;
   item:TListItem;
begin
   text:=Buffer;    
   if pos('Username:',text)>0 then
   begin
      mySendCommand('cisco6509e'); //发送用户名
      exit;
   end;
   if (pos('Password:',text)>0) and (telnetStatus=0) then
   begin
      sleep(100);
      mySendCommand('dqcy7xxzx'); //发送密码
      telnetStatus:=1;
      exit;
   end;

   if (pos('CY7-C6509E-01>',text)>0) and (telnetStatus=1) then
   begin
      mySendCommand('enable');//进入特权用户
      telnetStatus:=2;
      exit;
   end;

   if telnetStatus=2 then
   begin
      mySendCommand('hunter_fan'); //发送密码
      telnetStatus:=3;
      exit;
   end;
   
   if telnetStatus=3 then
   begin
      mySendCommand('show arp');
      telnetStatus:=4;
   end;

   EchoSocket9999.Socket.SendText(text+'<<<<<'#13#10);
   if textSy<>'' then begin text:=textSy+text;textSy:='';end;//把上一行没有解释完的补到前面.
   haveDataLine:=false;
   while pos('Internet  ',text)>0 do
   begin
      pos0:=pos('Internet  ',text);     haveDataLine:=true;
      delete(text,1,pos0-1);  //Internet  10.64.194.173          25   0013.d38d.4900  ARPA   Vlan3........
      sLine:=cutStrWithStr(text,#13#10);
      if sLine='' then
      begin
         textSY:=text;
         text:=' --More-- ';
         break;
      end;
      item:=ListView1.Items.Add;     item.ImageIndex:=-1;
      conputerCount:=conputerCount+1;
      s:=cutString(sLine,' '); item.Caption:=format('%4d',[conputerCount]);//Internet
      s:=cutString(sLine,' '); item.SubItems.Add(s);IPS:=S;//IP
      s:=cutString(sLine,' '); item.SubItems.Add(s);//Age
      s:=cutString(sLine,' '); item.SubItems.Add(s);//MAC
      s:=cutString(sLine,' '); item.SubItems.Add(s);//Type
                               item.SubItems.Add(sLine);//InterFase
                               item.SubItems.Add('');//HostName
                               item.SubItems.Add('');//存放 HostName 解析请求是否发送成功.
      sLine:='';//该行已经解析完了,没有剩余.
   end;
   if not haveDataLine then exit;//没有真正的数据,仅仅是telenet 键盘字母的echo.
   if (pos(' --More-- ',text)=0) and (text<>'') then textSY:=text else textSY:=''; //'Internet  10.64.195.62          223   0013.d38d.053b  ARPA   Vlan4'#$D#$A'I' 的情况
   if pos(' --More-- ',textSy)=1 then begin textSY:='';text:=' --More-- ';end; //'Internet  10.64.195.62          223   0013.d38d.053b  ARPA   Vlan4'#$D#$A'I' 的情况

   EchoSocket9999.Socket.SendText('text='+text+#13#10);
   if (copy(text,1,10)=' --More-- ') then begin sleep(100);IdTelnet1.SendCmd(' ');end
   else
   try
      EchoSocket9999.Socket.SendText('text1='+text+#13#10);
      EchoSocket9999.Socket.SendText('textSy1='+textSy+#13#10);
      if pos('CY7-C6509E-01#',textSy)=0 then //真正的结束!
      begin
         if (textSy<>'') or (sLine='') then exit;//文本剩半截,或者一点没有剩,并且后面不是--more--,直接退出,等待后续数据的到来.
      end else if pos('cisco6509>exit',textSy)>0 then exit;//结束,一点也没有用上!

      IdTelnet1.WriteLn('exit');
      IdTelnet1.WriteLn('');
      statusbar1.Panels[1].Text:=format('line=%d  ---End!',[ListView1.Items.Count]);
      ciscoOk();
   except
   end;
end;

procedure TForm1.ciscoOk;
var
   i,j,count:integer;
   isErr:boolean;
   item:TListItem;
   ipS,macS,ageS:String;
begin
   ColumnToSortR:=3;
   ListView1.AlphaSort;//按照MAC排序.

   isErr:=false;  //与上行重复标志.
   reMemo1.Clear;
   i:=0;
   while i<ListView1.Items.Count-1 do
   begin
      item:=ListView1.Items[i];
      ipS:=item.SubItems[0]; macS:=item.SubItems[2];    ageS:=item.SubItems[1];//参照物MAC,向下比较
      
      if (ageS<>'-') and (pos('.',macS)<>0) then //不是网关,不是'Incomplete'
      begin
         count:=1;
         for j:=i+1 to ListView1.Items.Count-1 do 
         begin
            with ListView1.Items[j] do
            if SubItems[2]<>macS then break
            else
            begin
               ImageIndex:=0;         //当前行加图标
               item.ImageIndex:=0;    //上行加图标
               count:=count+1;
               i:=j;
            end;
         end;
         if count>3 then reMemo1.Lines.Add(format('%-15s %15s(%d)',[ipS,macS,count]));
      end;
      i:=i+1;
   end;
   tmFlashHost.Enabled:=true;//启动Host解析时钟.
end;

procedure TForm1.ListView1ColumnClick(Sender: TObject;Column: TListColumn);
begin
   ColumnToSortR:=Column.Index;
   (Sender as TCustomListView).AlphaSort;
end;

procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;Data: Integer; var Compare: Integer);
var
   m,n:integer;
   s1,s2:String;
begin
case ColumnToSortR of
  -1:Compare:=0;
  0:Compare:=CompareText(TListItem(Item1).Caption,TListItem(Item2).Caption);
  1:begin
       s1:=TListItem(Item1).SubItems[0];
       s2:=TListItem(Item2).SubItems[0];  
       Compare:=ntohl(inet_Addr(pChar(s2)))-ntohl(inet_Addr(pchar(s1)));
    end;   
  else //子列排序
      begin
         try
            m:=StrToIntDef(TListItem(Item1).SubItems[ColumnToSortR-1],0);
            n:=StrToIntDef(TListItem(Item2).SubItems[ColumnToSortR-1],0);
            Compare:=m-n;
            if ((m=0) and (TListItem(Item1).SubItems[ColumnToSortR-1]<>'0')) or
               ((n=0) and (TListItem(Item2).SubItems[ColumnToSortR-1]<>'0')) then
            Compare:=CompareText(TListItem(Item1).SubItems[ColumnToSortR-1],TListItem(Item2).SubItems[ColumnToSortR-1]);
         except
            Compare:=CompareText(TListItem(Item1).Caption,TListItem(Item2).Caption);
         end;
      end;
  end;

  if ColumnToSortR<>0 then Compare:=-Compare;
end;

procedure TForm1.IdTelnet1Status(ASender: TObject;const AStatus: TIdStatus; const AStatusText: String);
begin
   statusBar1.Panels[0].Text:=AStatusText;
end;

procedure TForm1.WMASyncSMBEcho(var msg: TMessage);
var
   i:integer;
   item:TListItem;
   ips,workGroup,HostName,userName,macAddress:String;
begin
   SMBCount:=SMBCount+1;  
   ansSMBEcho(ips,workGroup,HostName,userName,macAddress);
   for i:=0 to listView1.Items.Count-1 do
   begin
      item:=ListView1.Items[i];
      if item.SubItems[0]=ips then
      begin
         item.SubItems[5]:=format('%s|%s|%s',[workGroup,HostName,userName]);
      end;
   end;
end;

procedure TForm1.EchoSocket9999Error(Sender: TObject;Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;var ErrorCode: Integer);
begin
   ErrorCode:=0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   new(ht);
   initSMB(handle,0,6969);//初始化,用于得到主机名,网卡地址用
end;

procedure TForm1.tbStartClick(Sender: TObject);
begin
   EchoSocket9999.Active:=true;       inFlashHost:=false;
   telnetStatus:=0;
   conputerCount:=0;   SMBCount:=0;ListView1.Clear;
   if IdTelnet1.Connected then IdTelnet1.Disconnect;
   IdTelnet1.Host:='10.64.192.1';    IdTelnet1.Port:=23;
   IdTelnet1.Terminal:='';  textSY:='';
   IdTelnet1.Connect();
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
var
   row,pos0:integer;
   MACS:String;
begin
   row:=ListView1.ItemIndex;//点击的行数.
   if row<0 then exit;//非行点击
   MACS:=ListView1.Selected.SubItems.Strings[2]+' ';//得到MAC地址.
   //匹配用户点击的IP或者MAC地址,在reIpMac文本中
   pos0:=pos(MACS,reIPMAC.Text);        if pos0<0 then pos0:=0;
   reIPMAC.SelStart := pos0;
   SendMessage(reIPMAC.Handle, EM_SCROLLCARET, 0, 0); //滚动到光标处(只能保证光标出现在窗口中)
   row:= SendMessage(reIPMAC.Handle, EM_LINEFROMCHAR, reIPMAC.SelStart, 0);//得到当前行
   SendMessage(reIPMAC.Handle, EM_LINESCROLL, 0, row - SendMessage(reIPMAC.Handle, EM_GETFIRSTVISIBLELINE, 0, 0));
end;

procedure TForm1.tbSaveClick(Sender: TObject);
var
   i:integer;
   item:TListItem;
   ss:TStrings;
   cc,sn:string;
begin
   ss:=TStringList.Create;
   //  389  10.64.194.11     51   0800.20fe.d74c    ARPA   Vlan3  ||
   ss.add('  No.      IP           Age       MAC          type Interface  Name');
   for i:=0 to ListView1.Items.Count-1 do
   begin
      item:=ListView1.Items[i]; if item.ImageIndex<>-1 then cc:='*' else cc:=' ';
      if item.SubItems[2]='Incomplete' then continue;//没有网卡地址,忽略.
      ss.Add(format('%s%4s  %-15s  %-4s %-15s   %-4s %-8s %-s',[cc,item.Caption,item.SubItems[0],item.SubItems[1],item.SubItems[2],item.SubItems[3],item.SubItems[4],item.SubItems[5]]));
   end;
   sn:=formatDateTime('YYYYMMDD hhmmss',now);
   ss.Add(sn+'   '+statusbar1.Panels[1].Text);      //20070301 072942   line=971  ---End!
   ss.SaveToFile(sn+'.out');
   if not FileExists('Ip_MAC.TXT') then ss.SaveToFile('Ip_MAC.TXT');
end;

procedure TForm1.tmFlashHostTimer(Sender: TObject);
var
   i,waitCount:integer;
   item:TListItem;
begin
   if inFlashHost then exit;
   inFlashHost:=true;      waitCount:=0;
   for i:=0 to ListView1.Items.Count-1 do
   begin
      item:=ListView1.Items[i];
      if item.SubItems[2]='Incomplete' then continue;//没有网卡地址,忽略.
      if item.SubItems[6]<>'v' then
      begin
         waitCount:=waitCount+1;
         if not SendMacReqOk(item.SubItems[0]) then break else item.SubItems[6]:='v';
         if waitCount mod 25=0 then break;  //发送多了就会丢失.
      end;
   end;
   inFlashHost:=false;
   if waitCount=0 then
   begin
      tmFlashHost.Enabled:=false;
      IdTelnet1.Disconnect;
   end;
end;

procedure TForm1.tbOpenIpMacClick(Sender: TObject);
begin
   ShellExecute(Handle,   'open',   'notepad.exe',   'IP_MAC.txt',   nil,   SW_SHOW);
end;

function Compare(ip:LongInt;port:word;Item:Pointer):integer;
var
   pp:^TIpMacRec;
   ul1,ul2:u_long;
begin
   pp:=Item;       ul1:=ntohl(ip);
   ul2:=ntohl(pp.ip);//-StrLComp(PChar(@key),PChar(@pp.ip),4);
   if ul1=ul2 then result:=0
   else if ul1>ul2 then result:=-1
   else result:=1;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
   if fileExists('IP_MAC.txt') then reIPMAC.Lines.LoadFromFile('IP_MAC.txt');
end;

procedure TForm1.tbMergeClick(Sender: TObject);
var
   i,pos0,count:integer;
   item:TListItem;
   theMac:string;
   cc:Char;
begin
   statusBar1.Panels[0].Text:='资料保存,稍等......';
   Application.ProcessMessages;
   count:=0;
   for i:=0 to ListView1.Items.Count-1 do //遍历每一行,与内存中的reIpMAcList对比,没有该ip,就在reIpMAC后面插入一行.
   begin
      item:=ListView1.Items[i];
      theMac:=item.SubItems[2]+' ';
      if theMac='Incomplete ' then continue;//没有网卡地址,忽略.
      pos0:=pos(theMAC,reIPMac.Text);
      if (pos0<=0) then //不是重复的网卡,在ip_MAC.txt中没有登记!
      begin
         if (item.ImageIndex<>0) then cc:=' ' else cc:='*';
         reIPMAC.lines.Add(format('%s%4s  %-15s  %-4s %-15s   %-4s %-8s %-s',[cc,item.Caption,item.SubItems[0],item.SubItems[1],item.SubItems[2],item.SubItems[3],item.SubItems[4],item.SubItems[5]]));
         count:=count+1;
      end;
   end;
   reIPMAC.lines.SaveToFile('ip_mac.txt');//?????????????写  ipMacLists===>ipmac.txt
   statusBar1.Panels[0].Text:=format('新增 %d 个记录!',[count]);
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
   ht.pt.x   :=   X;    ht.pt.Y   :=   Y;
   ListView_SubItemHitTest(ListView1.Handle,   ht);
   //ShowMessage(IntToStr(ht.iItem));                                     //行号
   //ShowMessage(IntToStr(ht.iSubItem));                               //列号
end;

procedure TForm1.reMemo1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
var
   i,line:integer;
   ipS:String;
begin
   line:=SendMessage(reMemo1.Handle, EM_LINEFROMCHAR, reMemo1.SelStart, 0);
   ips:=reMemo1.Lines[line];
   ipS:=cutString(ips,' ');
   for i:=0 to listView1.Items.Count-1 do
   if TListItem(listView1.Items[i]).SubItems[0]=ipS then
   begin
      listView1.SetFocus;
      listView1.ItemIndex:=i;
      listView1.Items[i].MakeVisible(true);
      break;
   end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -