详谈调用winpcap驱动写arp多功能工具
??一、winpcap驅動簡介
winpcap(windows packet capture)是windows平臺下一個免費,公共的網絡訪問系統。
(編者注:WinpCap開發包可以到以下兩個網址下載: (1)http://winpcap.polito.it/?, (2)VC知識庫工具欄目?)
開發winpcap這個項目的目的在于為win32應用程序提供訪問網絡底層的能力。它提供了以下的各項功能:
1> 捕獲原始數據報,包括在共享網絡上各主機發送/接收的以及相互之間交換的數據報;
2> 在數據報發往應用程序之前,按照自定義的規則將某些特殊的數據報過濾掉;
3> 在網絡上發送原始的數據報;
4> 收集網絡通信過程中的統計信息。
winpcap的主要功能在于獨立于主機協議(如TCP-IP)而發送和接收原始數據報。也就是說,winpcap不能阻塞,過濾或控制其他應用程序數據報的發收,它僅僅只是監聽共享網絡上傳送的數據報。因此,它不能用于QoS調度程序或個人防火墻。
目前,winpcap開發的主要對象是windows NT/2000/XP,這主要是因為在使用winpcap的用戶中只有一小部分是僅使用windows 95/98/Me,并且M$也已經放棄了對win9x的開發。因此本文相關的程序T-ARP也是面向NT/2000/XP用戶的。其實winpcap中的面向9x系統的概念和NT系統的非常相似,只是在某些實現上有點差異,比如說9x只支持ANSI編碼,而NT系統則提倡使用Unicode編碼。
本文討論的是packet.dll所提供的各種函數,因為它們完全可以實現本文所希望的各項要求。但是如果你有其他特別的或更高級的要求,winpcap也提供了另一個動態連接庫wpcap.dll。雖然wpcap.dll依靠于packet.dll,但是它卻提供了一種更簡單,直接,有力的方法來更好的利用編程環境。比如捕獲一個數據報,創建一個數據報過濾裝置或將監聽到的數據報轉存到某個文件等,wpcap.dll都會為你提供更加安全的實現方法。
?二、Packet.dll相關數據結構及函數?
本文的目的之一在于介紹如何利用winpcap驅動寫ARP工具,因此有必要介紹一些相關的數據結構和函數,要不然看著一行行代碼和函數,也許會有些不知所云。
首先介紹一些相關的數據結構:
1. typedef struct _ADAPTER ADAPTER //描述一個網絡適配器;
2. typedef struct _PACKET PACKET //描述一組網絡數據報的結構;
3. typedef struct NetType NetType //描述網絡類型的數據結構;
4. typedef struct npf_if_addr npf_if_addr //描述一個網絡適配器的ip地址;
5. struct bpf_hdr //數據報頭部;
6. struct bpf_stat //當前捕獲數據報的統計信息。
下面,將介紹T-ARP用到的各個函數,他們都是在packet.dll中定義的:
1> LPPACKET PacketAllocatePacket(void)
如果運行成功,返回一個_PACKET結構的指針,否則返回NULL。成功返回的結果將會傳送到PacketReceivePacket()函數,接收來自驅動的網絡數據報。
2> VOID PacketCloseAdapter(LPADAPTER lpAdapter)
關閉參數中提供的網絡適配器,釋放相關的ADAPTER結構。
3> VOID PacketFreePacket(LPPACKET lpPacket)
釋放參數提供的_PACKET結構。
4> BOOLEAN PacketGetAdapterNames(LPSTR pStr,PULONG BufferSize)
返回可以得到的網絡適配器列表及描述。
5> BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterNames,npf_ip_addr *buff, PLONG NEntries)
返回某個網絡適配器的全面地址信息。
其中npf_ip_addr結構包含:IPAddress,SubnetMask,Broadcast
IPAddress: ip地址
SubnetMask: 子網掩碼
Broadcast: 廣播地址
6> BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)
返回某個網絡適配器的MAC類型。
NetType結構里包含了LinkSpeed(速度)和LinkType(類型)。其中LinkType包含以下幾種情況:
NdisMedium802_3: Ethernet(802.3)
NdisMediumWan: WAN
NdisMedium802_5: Token Ring(802.5)
NdisMediumFddi: FDDI
NdisMediumAtm: ATM
NdisMediumArcnet878_2: ARCNET(878.2)
7> BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
返回幾個關于當前捕獲報告的統計信息。
其中bpf_stat結構包含:bs_recv, bs_drop,ps_ifdrop,bs_capt
bs_recv: 從網絡適配器開始捕獲數據報開始所接收到的所有數據報的數目,包括丟失的數據報;
bs_drop: 丟失的數據報數目。在驅動緩沖區已經滿時,就會發生數據報丟失的情況。
8> PCHAR PacketGetVersion()
返回關于dll的版本信息。
9> VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length)
初始化一個_PACKET結構。
10> LPADAPTER PacketOpetAdapter(LPTSTR AdapterName)
打開一個網絡適配器。
11> BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
從NPF驅動程序讀取網絡數據報及統計信息。
數據報編碼結構: |bpf_hdr|data|Padding|bpf_hdr|data|Padding|
12> BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket, BOOLEAN Sync)
發送一個或多個數據報的副本。
13> BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
設置捕獲數據報的內核級緩沖區大小。
14> BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter)
為接收到的數據報設置硬件過濾規則。
以下為一些典型的過濾規則:
NDIS_PACKET_TYPE_PROMISCUOUS: 設置為混雜模式,接收所有流過的數據報;
NDIS_PACKET_TYPE_DIRECTED: 只有目的地為本地主機網絡適配器的數據報才會被接收;
NDIS_PACKET_TYPE_BROADCAST: 只有廣播數據報才會被接收;
NDIS_PACKET_TYPE_MULTICAST: 只有與本地主機網絡適配器相對應的多播數據報才會被接收;
NDIS_PACKET_TYPE_ALL_MULTICAST: 所有多播數據報均被接收;
NDIS_PACKET_TYPE_ALL_LOCAL: 所有本地數據報均被接收。
15> BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
設置調用PacketSendPacket()函數發送一個數據報副本所重復的次數。
16> BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
設置在接收到一個數據報后“休息”的時間。
以上就是T-ARP所調用的各個函數,它包含了packet.dll里的大部分函數。如果你想更深層的了解winpcap,請訪問相關網站,主頁地址: http://winpcap.polito.it
?三、T-ARP功能及原理介紹
準備工作:?
1. 安裝winpcap驅動,目前最新的版本為winpcap_3.0_alpha, 穩定版本為winpcap_2.3;
2. 使用ARP欺騙功能前,必須啟動ip路由功能,修改(添加)注冊表選項:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter = 0x1
選項:?
-m 主機掃描,獲得局域網內指定ip段中存活主機的ip地址和mac地址;
-a 反嗅探掃描,獲得局域網內指定ip段中嗅探主機的ip地址和mac地址;
-s ARP欺騙,欺騙局域網內指定的兩臺主機,使其相互發送接收的數據報均通過本地主機;
網絡嗅探,如果你選擇欺騙的兩臺主機均是本地主機,那么將會監聽到所有流過本地主機的數據報;
IP沖突,如果你選擇欺騙的兩臺主機是同一臺非本地主機,那么就會發起ip沖突攻擊;
-r 重置被欺騙主機,使被欺騙的兩臺主機恢復正常的工作狀態。
原理及實現過程:
無論什么選項,第一件事就是獲得本地主機的mac地址及相關網絡設置。我們以一個特殊的ip地址(112.112.112.112)向本地主機發送一個ARP Request(ARP請求)數據報,當本地主機接收到后,就會發送一個ARP Reply(ARP應答)數據報來回應請求,這樣我們就可以獲得本地主機的mac地址了。至于相關的網絡設置可以通過PacketGetNetInfoEx()和PacketGetNetType()獲得。
-m 以本地主機的名義(本地主機的ip和mac)向指定ip網段內的所有主機發送廣播(ff:ff:ff:ff:ff:ff)ARP Request數據報,存活的主機就會發送ARP Reply數據報,這樣就可以獲得當前存活主機的列表。因為在很多網關上都對ARP Request做了限制--非內網ip發送的ARP Request數據報不會得到網關的回應,如果你用內網的其他某臺主機的ip來發送ARP Request數據報,如果填寫的mac地址和相應的ip不合,就會出現ip沖突。所以最好還是用自己的ip和mac地址來發送請求。
-a 以本地主機的名義(本地主機的ip和mac)向指定ip網段內的所有主機發送31位偽廣播地址(ff:ff:ff:ff:ff:fe)的ARP Request數據報,只有正在嗅探的主機才會發送ARP Reply數據報,這樣就可以獲得當前存活主機的列表。嗅探中的win2000系統還會對16位偽廣播地址(ff:ff:00:00:00:00)做出回應;而嗅探中的win95/98/me不僅會回應16位偽廣播地址,而且也會回應8位偽廣播地址(ff:00:00:00:00:00),而*NIX系統對各種廣播地址所做出的反應卻有些不同。在此我們選擇31位偽廣播地址,是因為絕大多數的系統在嗅探時都會對它做出回應。而正常狀況下的各種系統,都不會對31位偽廣播地址做出回應。
-s (ARP欺騙spoof) 需要強調的是在某些局域網(如以太網)內,數據報的發送與接收是基于硬件地址的,這是我們實現欺騙的基礎。首先獲得指定的兩臺主機(假設為 A 和 B)的mac地址,然后向A發送ARP Reply數據報,其中的源ip地址為B的ip地址,但是源mac地址卻是本地主機的mac地址,這樣主機A就會認為主機B的mac地址是本地主機的mac地址,所以主機A發送到主機B的數據報都發送到本地主機了。同理向主機B發送ARP Reply數據報,通知它主機A的mac地址為本地主機的mac地址。這樣主機A和主機B就會把目的主機的mac地址理解為本地主機的mac地址,于是他們之間相互發送的數據報都首先到達了本地主機,而先前我們已經將本地主機設置了ip路由功能,系統會自動將數據報轉發到真正的目的主機。其間,你就可以監聽它們通信的各種數據報了。
-s (網絡嗅探sniff) 如果指定的兩個目的主機均為本地主機,那么就只是將網絡適配器設置為混雜模式,這樣就可以監聽到流過本地主機網絡適配器的各種數據。
-s (ip沖突shock) 如果你選擇欺騙的兩臺主機是同一臺非本地主機(假如是主機C),那么就會不斷地向主機C發送ARP Reply數據報,報文中的源ip地址就是主機C的ip地址,但是源mac地址卻是本地主機的mac地址,因此主機C就會發現有另一臺主機同時擁有和自己相同的ip,這就是ip沖突攻擊。如果是非xp系統,都會跳出一個ip沖突的提示窗口,而xp系統也會有類似的警告。但是請注意,在主機C的系統事件查看器中,會留下本地主機的mac地址與之沖突的惡心記錄,所以你最好不要濫用這個功能。
-r 在實現了ARP欺騙的情況下,向主機A和B發送ARP Reply數據報,通知主機A(B)注意主機B(A)的mac地址為主機B(A)自己的mac地址,這樣主機A和B就會更新他們的ARP緩存,實現正常的數據通信。
?四、T-ARP主要代碼分析
1> 自定義函數:
int getmine() //發送ARP Request數據報,請求獲得本地主機的mac地址;
void getdata(LPPACKET lp,int op) //分類處理接收到的數據報;
DWORD WINAPI sniff(LPVOID no) //將網絡適配器設置為混雜模式,接收所有流過的數據報;
DWORD WINAPI sendMASR(LPVOID no) //發送ARP Request數據報,請求獲得指定ip的mac地址;
DWORD WINAPI sendSR(LPVOID no) //發送ARP Reply進行ARP欺騙,或是更新主機的ARP緩存。
2> 主要代碼分析
printf("\nLibarary Version: %s",PacketGetVersion()); //輸出dll的版本信息;
PacketGetAdapterNames((char *)adaptername,&adapterlength) //獲得本地主機的網絡適配器列表和描述;
lpadapter=PacketOpenAdapter(adapterlist[open-1]); //打開指定的網絡適配器;
PacketGetNetType(lpadapter,&ntype) //獲得網絡適配器的MAC類型;
PacketGetNetInfoEx(adapterlist[open-1],&ipbuff,&npflen) //獲得指定網絡適配器的相關信息;
rthread=CreateThread(NULL,0,sniff,(LPVOID)&opti,0,&threadrid); //創建一個新線程來監聽網絡數據報;
PacketSetHwFilter(lpadapter,NDIS_PACKET_TYPE_PROMISCUOUS) //將網絡適配器設置為混雜模式,這樣才可以監聽流過本地主機的數據報;
PacketSetBuff(lpadapter,500*1024) //自定義網絡適配器的內核緩存的大小為 500*1024;
PacketSetReadTimeout(lpadapter,1) //設置接收一個數據報后等待的時間為1毫秒;
PacketReceivePacket(lpadapter,lppacketr,TRUE) //在設置為混雜模式后,接收所有的數據報;
sthread=CreateThread(NULL,0,sendMASR,(LPVOID)&opti,0,&threadsid);
sthread=CreateThread(NULL,0,sendSR,(LPVOID)&opti,0,&threadsid); //創建一個新線程發送特定的ARP數據報
PacketSetNumWrites(lpadapter,2) //在發送一個數據報時,重復發送兩次;
PacketSendPacket(lpadapter,lppackets,TRUE) //發送自定義數據報;
WaitForSingleObject(sthread,INFINITE); //等待發送ARP數據報的線程結束;
PacketGetStats(lpadapter,&stat) //獲得網絡適配器的統計信息;
?五、T-ARP源代碼
}
本文轉hackfreer51CTO博客,原文鏈接:http://blog.51cto.com/pnig0s1992/674834,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的详谈调用winpcap驱动写arp多功能工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Html中的次方符号怎么写
- 下一篇: 我看产品