<ruby id="z6k00"><option id="z6k00"></option></ruby>
  • <ol id="z6k00"></ol>
      <span id="z6k00"></span><dd id="z6k00"><output id="z6k00"><strike id="z6k00"></strike></output></dd>

    1. <optgroup id="z6k00"></optgroup>

          新疆軟件開發

          本站首頁 軟件開發 成功案例 公司新聞 公司簡介 客服中心 軟件技術 網站建設
            您現在的位置: 新疆二域軟件開發公司 >> 開發語言 >> 文章正文

          delphi實現利用arp欺騙來實現計費功能

            
               前段時間接到一個項目,該項目要求在局域網內的任何一臺計算機上安裝一套計費軟件,其他的客戶端不用安裝任何軟件,只要客戶插入網線就可以計費。以前接觸到的計費軟件都是安裝在網關上的,要么就是要安裝客戶端軟件,如何實現這樣的功能呢?研究了一下,發現用arp欺騙的原理可以實現計費的功能,原理是在未開通上網功能的客戶端插入網線后,先禁止局域網內的該計算機上網,等該客戶端要求管理員開通上網功能后再解除對該客戶端的阻止并開始計費。arp欺騙相信大家的都不陌生,網上有好多介紹arp欺騙的文章,也有好多arp欺騙的病毒,在這里就不再重復arp欺騙的原理了。

                如何阻止局域網指定的客戶端上網呢?
          用偽造的arp的請求包刷新要阻止機器的arp表,使之認為網關的mac地址為一個不存在的mac地址,這樣的話就可以阻止該機器上網了。

          假設要阻止的計算機是A,安裝計費軟件的計算機是B,網關是C

          A機器  MAC:AA-AA-AA-AA-AA-AA  IP地址:192.168.1.1

          B機器  MAC:BB-BB-BB-BB-BB-BB  IP地址:192.168.1.2

          C網關  MAC:CC-CC-CC-CC-CC-CC  IP地址:192.168.1.253


          在網上有好多arp例子都是c的,我用delphi和Winpcap實現代碼如下:
           
          安裝Winpcap,引用:winsock,Packet32,shellapi單元

          類型和常量定義:
          type
            TMacAddr = array [0..5] of byte ;
            TEHHDR=packed record
               Ether_Dest: TMacAddr ;  {目的地址 }
               Ether_Src: TMacAddr ;   {源地址 }
               Ether_Type:Word;        {類型 }
            end;
            PEHHDR=^TEHHDR;
            TEtherData=packed record      {Ethernet packet data}
             Ether_hrd:WORD;       {hardware address }
             Ether_pro:WORD; {format of protocol address }
             Ether_hln: byte; {byte length of each hardware address }
             Ether_pln: byte; {byte length of each protocol address}
              Ether_op:WORD; { ARP or RARP }
               Ether_sha:TMacAddr; {hardware address of sender}
               Ether_spa:LongWord; {protocol address of sender}
               Ether_tha:TMacAddr; {hardware address of target}
               Ether_tpa:LongWord;   {protocol address of target}
            end;
            PARPHDR=^TEtherData;

            TARPPACKET=packed record
                EHHDR:Tehhdr;
                EtherData:TEtherData;
             end ;
           PARPPACKET=^TARPPACKET;

          const
           INADDR_NONE = $FFFFFFFF;
           EPT_IP  = $0800;
           EPT_ARP = $0806 ;
           EPT_RARP =$8035 ;
           ARP_REPLY =$0002 ;
           ARP_REQUEST =  $0001 ;
           ARP_HARDWARE =$0001 ; 

           function inet_addr(const cp: PChar): DWord; stdcall; external 'WS2_32.DLL' name 'inet_addr';

          //別人的代碼
          function     HexStrtoInt(var   Buf:   string):   dword;
            //將十六進制的字符串轉成整型
                //判斷是否是十六進制數
                function   IsHexChar(Chr:   char):   boolean;
                begin
                    Result   :=   (Chr   in   ['0'..'9'])   or   (Chr   in   ['A'..'F']);
                end;
                //將一個十六進制字符轉換成數
                function   HexChrtoInt(Chr:   char):   byte;
                begin
                    Result   :=   0;
                    case   Chr   of
                        '0'..'9'   :   Result   :=   Strtoint(Chr);
                        'A'             :   Result   :=   10;
                        'B'             :   Result   :=   11;
                        'C'             :   Result   :=   12;
                        'D'             :   Result   :=   13;
                        'E'             :   Result   :=   14;
                        'F'             :   Result   :=   15;
                    end;
                end;
            var
                BufLength:   dword;
                TempBuf:   string;  
                Count0:   dword;  
            begin
                Result   :=   0;  
                BufLength   :=   Length(Buf);
                TempBuf   :=   '';  
                if   BufLength   >   0   then   begin
                    Buf   :=   Uppercase(Buf);  
            //         for   Count0   :=   1   to   BufLength  
                    if   BufLength   mod   2   =   1   then   begin  
                        Buf   :=   '0'   +   Buf;  
                        BufLength   :=   Length(Buf);
                    end;
                    for   Count0   :=   1   to   BufLength   div   2   do  
                        if   IsHexChar(Buf[Count0   *   2   -   1])   then   begin  
                            if   IsHexChar(Buf[Count0   *   2])   then   begin  
                                TempBuf   :=   TempBuf   +   inttostr(HexChrtoInt(Buf[Count0   *   2   -   1])

            *   16   +   HexChrtoInt(Buf[Count0   *   2]));
                            end   else   begin
                                Result   :=   Count0   *   2;  
                                Break;  
                            end;  
                        end   else   begin
                            Result   :=   Count0   *   2   -   1;  
                            Break;  
                        end;
                    if   Result   =   0   then   Buf   :=   TempBuf;
                end;
            end;

          //MAC轉換
          procedure GetMac(s : string;var Mac : TMacAddr);

            var
            hs : string;
            p : integer;
            i,j:integer;

          begin
           FillChar (Mac, SizeOf (Mac), 0) ;

            i:=0;
            if Length(s)=0 then
              Exit;
            p:=Pos('-',s);
            while P<>0 do
            begin
              hs:=Copy(s,1,p-1);
              HexStrtoInt(hs);
              Mac[i]:=  strtoint(hs) ;
              Delete(s,1,p);
              p:=Pos('-',s);
              i:=i+1;
            end;
            if Length(s)>0 then
            begin
               HexStrtoInt(s);
               Mac[i]:=strtoint(s);
            end;
          end;

           

          {禁止上網,發送arp請求包,這里的C_mac為偽造的C的mac地址}
          procedure SendArp(A_ip:string;A_mac:string;B_ip:string;B_mac:string;C_IP:string;C_mac:string);
          var
          ulMACAddr: TMacAddr;
          EHHDR:TEHHDR;
          EtherData:TEtherData;
          pp:pPacket;
          lpAdapter:Padapter;
          BUF:Array [0..512] of char ;

          begin
              //以太網包首部
              GetMac(A_mac,ulMACAddr);
              Move(ulMACAddr , EHHDR.Ether_Dest,6);//目的地址-A計算機的地址
              GetMac(C_mac,ulMACAddr);
              Move(ulMACAddr , EHHDR.Ether_Src,6);//偽造的源地址-C計算機的地址
              EHHDR.Ether_Type  := htons(EPT_ARP);//arp包
             
              //構造以太網包數據
              EtherData.Ether_hrd := htons(ARP_HARDWARE);
              EtherData.Ether_pro := htons(EPT_IP);
              EtherData.Ether_hln := 6;
              EtherData.Ether_pln := 4;
              EtherData.Ether_op  := htons(ARP_REQUEST);//arp請求包
              GetMac(C_mac,ulMACAddr);
              Move(ulMACAddr , EtherData.Ether_sha,6);
              EtherData.Ether_spa := inet_addr(Pchar(B_IP)); 
              GetMac(B_mac,ulMACAddr);
              Move(ulMACAddr , EtherData.Ether_tha,6);
              EtherData.Ether_tpa := inet_addr(Pchar(B_ip)); 


               lpAdapter := PacketOpenAdapter('\Device\NPF_{E00872C1-37C0-47CE-8472-313A5A23F896}');  // 根據

          你網卡名字打開網卡,這是我網卡的設備名
               fillchar(BUF,sizeof(BUF),0);

               CopyMemory(@BUF,@EHHDR,SIZEOF(EHHDR));
               CopyMemory(Pointer(LongWord(@BUF)+SIZEOF(EHHDR)),@EtherData,SIZEOF(EtherData));
                 // 分配內存
               pp := PacketAllocatePacket();            

               //初始化結構指針
               PacketInitPacket(pp, @BUF,512);
               //發arp應答包
               PacketSendPacket(lpAdapter, pp, true);
              
               // 釋放內存
               PacketFreePacket(pp);
               PacketCloseAdapter(lpAdapter);

          end;

          //調用示例
            SendArp('192.168.1.1','AA-AA-AA-AA-AA-AA','192.168.1.2','BB-BB-BB-BB-BB-BB','192.168.1.253','00-00-00-00-00-00');


          {解除阻止,發送arp應答包,這里的C_mac為真實的C的mac地址}
          procedure SendArpReply(A_ip:string;A_mac:string;C_ip:string;C_mac:string;B_mac:string);
          var
          ulMACAddr: TMacAddr;
          EHHDR:TEHHDR;
          EtherData:TEtherData;
          pp:pPacket;
          lpAdapter:Padapter;
          BUF:Array [0..512] of char ;

          begin
              GetMac(A_mac,ulMACAddr);
              Move(ulMACAddr , EHHDR.Ether_Dest,6);
              GetMac(B_mac,ulMACAddr);
              Move(ulMACAddr , EHHDR.Ether_Src,6);
              EHHDR.Ether_Type  := htons(EPT_ARP);
              EtherData.Ether_hrd := htons(ARP_HARDWARE);
              EtherData.Ether_pro := htons(EPT_IP);
              EtherData.Ether_hln := 6;
              EtherData.Ether_pln := 4;
              EtherData.Ether_op  := htons(ARP_REPLY);//arp應答包
              GetMac(C_mac,ulMACAddr);
              Move(ulMACAddr , EtherData.Ether_sha,6);
              EtherData.Ether_spa := inet_addr(Pchar(C_ip));  
              GetMac(A_mac,ulMACAddr);
              Move(ulMACAddr , EtherData.Ether_tha,6);
              EtherData.Ether_tpa := inet_addr(Pchar(A_ip)); 

               // 根據自己網卡的設備名打開網卡
               lpAdapter := PacketOpenAdapter('\Device\NPF_{E00872C1-37C0-47CE-8472-313A5A23F896}');
             
               fillchar(BUF,sizeof(BUF),0);
               CopyMemory(@BUF,@EHHDR,SIZEOF(EHHDR));
               CopyMemory(Pointer(LongWord(@BUF)+SIZEOF(EHHDR)),@EtherData,SIZEOF(EtherData));

               // 分配內存
               pp := PacketAllocatePacket();            

               //初始化結構指針
               PacketInitPacket(pp, @BUF,512);
               //發arp應答包
               PacketSendPacket(lpAdapter, pp, true);
              
               // 釋放內存
               PacketFreePacket(pp);
               PacketCloseAdapter(lpAdapter);
          end;

          //調用示例
           SendArpReply('192.168.1.1','AA-AA-AA-AA-AA-AA','192.168.1.253','CC-CC-CC-CC-CC-CC','BB-BB-BB-BB-BB-BB');

          需要注意的是,發出偽造的arp請求包過一段時間后會被刷新為正確的,所以每隔一段時間要向被阻止的機器發送一個arp包,這樣才能達到阻止上網的目的。

           本文來源于 新疆二域軟件開發網  http://www.fivestartaxiservice.com  轉載請注明出處

          作者:xjzcg | 文章來源:本站原創 | 更新時間:2008-3-21 15:45:14

        1. 上一篇文章:

        2. 下一篇文章:

        3. 相關文章:
          一個delphi開發托盤程序的例子
          了解delphi過程類型/過程類型學習
          BLOB是如何使用的
          GB/Unicode/GBK之間的轉換
          delphi使用技藝大全
          在桌面中嵌入窗體
          軟件技術
          · 開發語言
          · Java技術
          · .Net技術
          · 數據庫開發
          最新文章  
          ·搜集整理的asp.net的驗證方
          ·各種FOR循環結構的整理
          ·軟件項目開發中應該考慮那
          ·搜集整理的javascript sel
          ·軟件開發中項目經理有那些
          ·學習如何在Lambda表達式進
          ·C++基礎知識:結構體數據的
          ·C#實現短信發送程序的例子
          ·sun最近修補了一部分java的
          ·rss定制的另外一種實現方式
          ·delphi實現利用arp欺騙來實
          ·基礎學習:基于WF的流程框
          ·網絡編程中怎樣得知一次數
          ·如何逆序輸出單鏈表?
          ·軟件開發過程中的性能設計
          關于我們 | 軟件開發 | 下載試用 | 客服中心 | 聯系我們 | 友情鏈接 | 網站地圖 | 新疆電子地圖 | RSS訂閱
          版權所有 © 2016 新疆二域軟件開發網 www.fivestartaxiservice.com All Rights Reserved 新ICP備14003571號
          新疆軟件開發總機:0991-4842803、4811639.
          客服QQ:596589785 ;地址:新疆烏魯木齊北京中路華聯大廈A-5C 郵編:830000
           
          日本a级作爱片一
          <ruby id="z6k00"><option id="z6k00"></option></ruby>
        4. <ol id="z6k00"></ol>
            <span id="z6k00"></span><dd id="z6k00"><output id="z6k00"><strike id="z6k00"></strike></output></dd>

          1. <optgroup id="z6k00"></optgroup>