.NET 異步封裝 WinDivert:輕松實現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)攔截與修改
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
前言WinDivert 是一個用于 Windows 操作系統(tǒng)的內(nèi)核模式驅(qū)動程序,允許用戶模式應(yīng)用程序攔截、修改和丟棄網(wǎng)絡(luò)數(shù)據(jù)包。 通過 WinDivert,可以實現(xiàn)各種高級網(wǎng)絡(luò)功能,如防火墻、流量分析工具和虛擬專用網(wǎng)絡(luò)(VPN)客戶端。
WinDivert介紹 WinDivert是windows下為數(shù)不多的非常優(yōu)秀網(wǎng)絡(luò)庫,非常適合用于開發(fā)抓包或修改包的應(yīng)用程序,其擁有以下能力:
同時WinDivert還提供了完整的loopback(回環(huán))IP、IPv6的支持,簡約而強(qiáng)大的Api、高級別的過濾語言(可以想象為sql一樣的東西)。 如此優(yōu)秀的項目自然有著各個語言的二次封裝項目,我在github上也找到了對應(yīng)多個的dotnet封裝項目,但無一例外,他們封裝的比較簡陋或太過于簡陋,下面是封裝項目的一些不足之處: 1、IPHeader、TcpHeader、UdpHeader等未提供網(wǎng)絡(luò)和主機(jī)的Endian轉(zhuǎn)換 2、局限于PInvoke,沒有意識使用dotnet的對象(比如IPv4直接聲明為uint類型) 3、沒有面向?qū)ο蟮姆庋b,甚至簡陋到只有聲明了static的PInvoke方法 4、過濾語言沒有任何處理,使用時要翻閱WinDivert的文檔(寫手sql一個感覺) 5、沒有異步IO封裝,都是清一色的IO同步阻塞(異步IO封裝難度大) WindivertDotnet介紹 WindivertDotnet是面向?qū)ο蟮腤inDivert的dotnet異步封裝,其保持著完整的底層庫能力,又提供dotnet的完美語法來操作: Filter對象支持Lambda構(gòu)建filter language,脫離字符串的苦海; 內(nèi)存安全的WinDivert對象,基于IOCP的ValueTask異步發(fā)送與接收方法; 內(nèi)存安全的WinDivertPacket對象,提供獲取包有效數(shù)據(jù)長度、解包、重構(gòu)chucksums等; WinDivertParseResult提供對解包的數(shù)據(jù)進(jìn)行精細(xì)修改,修改后對WinDivertPacket直接生效; 2.1、網(wǎng)絡(luò)和主機(jī)的Endian自動轉(zhuǎn)換 由于windows平臺是LittleEndian,而標(biāo)準(zhǔn)的IPHeader、TcpHeader、UdpHeader網(wǎng)絡(luò)定義都是BigEndian,如果未做任何處理,當(dāng)接收到一個SrcPort為80、DstPort為443的Tcp包時映射為結(jié)構(gòu)體時,你調(diào)式會看到如下結(jié)果: 由于沒有做Endian自動轉(zhuǎn)換,在調(diào)試時看到的數(shù)據(jù)甚至讓人抓狂,此時如果你把SrcPort改為我們理解為81端口,你是不能直接寫 WindivertDotnet項目花了很大的時間精力,為所有涉及的結(jié)構(gòu)體字段訪問時都做了必要的Endian讀取和寫入自動轉(zhuǎn)換,讓調(diào)用者不再為Endian問題費(fèi)腦子。 2.2、結(jié)合使用dotnet類型 IPv4地址占用4字節(jié),IPv6地址占用16字節(jié),所以一些封裝項目直接在結(jié)構(gòu)體聲明為 WindivertDotnet在聲明字段類型時,當(dāng)存在對應(yīng)的dotnet高級類型時,優(yōu)先使用這些高級類型,除了 2.3、面向?qū)ο蟮姆庋b WindivertDotnet將零散的過程式c-api,包裝為多種對象,而不是讓你面對滿天飛的各種靜態(tài)方法PInvoke調(diào)用IntPrt句柄和維護(hù)這些句柄的生命周期,例如WinDivertPacket對象,其本質(zhì)是一個非托管的緩沖區(qū)內(nèi)存,在沒有封裝之前,它就是一個csharp的
2.4、Filter filter language是WinDivert引以為豪的設(shè)計,對WinDivert來說就像是從0到1發(fā)明了sql一樣,它允許使用簡單的文本表達(dá)式來讓驅(qū)動層高性能地過濾得自己感興趣的數(shù)據(jù)包,比如 不足的是,人們在做dotnet封裝時,僅僅做了 WindivertDotnet提供Filter類型使用Lambda來構(gòu)造這個filter language,有了它您不再需要珍藏filter language葵花寶典了,就像使用了EF之后不會sql又何妨呢,因為如下的csharp代碼,每個人都打得出:
2.5、異步IO封裝沒有async和await的IO,那不是完美的IO,WinDivert提供了可選的 WindivertDotnet將
Api方法是簡單,但過程曲折,沒有資料,碰壁無數(shù),哪怕是小小的CancellationToken參數(shù),但它卻能讓pendding的IO操作撤銷下來。 總結(jié) 因FastGithub項目的需要,所以本項目才得以誕生,現(xiàn)在我是結(jié)合實際項目的中使用痛點(diǎn)來改進(jìn)本項目,甚至添加了一些WinDivert目前沒有的功能,相信本項目越來越好用。 項目地址 WinDivert:https://github.com/basil00/WinDivert WindivertDotnet:https://github.com/xljiulang/WindivertDotnet 作者:老九 閱讀原文:原文鏈接 該文章在 2024/12/30 15:24:00 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |