|
N-Byte網(wǎng)絡(luò)守望者是一款單機(jī)版網(wǎng)絡(luò)安全工具,簡(jiǎn)言之,就是一個(gè)用.NET開發(fā)的個(gè)人版防火墻。在N-Byte網(wǎng)絡(luò)守望者1.0版的開發(fā)中,使用了NDIS Hook Driver技術(shù)來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)封包過(guò)濾功能,這使N-Byte網(wǎng)絡(luò)守望者能夠在網(wǎng)絡(luò)層過(guò)濾網(wǎng)絡(luò)封包,從而實(shí)現(xiàn)強(qiáng)大的功能。 由于軟件的主程序是用C#寫的,C#中沒有提供具有類似DeviceIoControl函數(shù)功能的驅(qū)動(dòng)設(shè)備控制函數(shù),而NDIS Hook Driver技術(shù)下的驅(qū)動(dòng)程序是用DDK下的C語(yǔ)言寫的,為了能夠?qū)崿F(xiàn)主程序?qū)︱?qū)動(dòng)程序的控制和相互通信,采用了以下設(shè)計(jì)方案: 在以上方案中,需要一個(gè)負(fù)責(zé)主程序與NDIS Hook Driver驅(qū)動(dòng)程序通信與控制的模塊DriverDll.dll,并用C#編寫的一個(gè)封裝驅(qū)動(dòng)程序中封包信息的模塊,可以發(fā)送這個(gè)驅(qū)動(dòng)程序信息到主程序,主程序可識(shí)別并操作模塊中的數(shù)據(jù)類型。 在.NET應(yīng)用程序使用驅(qū)動(dòng)程序的問(wèn)題上,面臨著兩個(gè)問(wèn)題: 1.怎樣實(shí)現(xiàn).NET應(yīng)用程序控制驅(qū)動(dòng)程序的功能? 2.怎樣從驅(qū)動(dòng)程序向.NET應(yīng)用程序傳遞非托管的數(shù)據(jù)類型? 以下是我們就這些問(wèn)題的詳細(xì)解決方法: 怎樣實(shí)現(xiàn).NET應(yīng)用程序控制驅(qū)動(dòng)程序的功能? 使用托管C++編寫的DriverDll.dll來(lái)實(shí)現(xiàn)對(duì)驅(qū)動(dòng)程序的直接控制,而主程序通過(guò)調(diào)用其中的方法來(lái)實(shí)現(xiàn)對(duì)驅(qū)動(dòng)程序的間接控制。比如在NByte.h文件中定義了START_IP_HOOK常數(shù)用來(lái)作為傳給驅(qū)動(dòng)程序用來(lái)開啟驅(qū)動(dòng)程序封包過(guò)濾功能的參數(shù),下面在托管C++模塊中定義了IoCtrl托管類并定義了下面的向緩沖區(qū)寫入?yún)?shù)的方法: //向緩沖區(qū)寫入數(shù)據(jù)。 DWORD WriteIo(DWORD code,PVOID buffer,DWORD count) { if(hDriverHandle == NULL) return ERROR_DRIVER_HANDLE; DWORD bytesReturned; BOOL returnCode = DeviceIoControl(hDriverHandle, code, buffer, count, NULL, 0, &bytesReturned, NULL);
if(!returnCode) return ERROR_IO_CTRL; return SUCCESS; } 當(dāng)然直接使用這個(gè)方法不太方便,所以定義一個(gè)公有函數(shù),用來(lái)提供給主程序調(diào)用: //開始進(jìn)行封包過(guò)濾 bool StartIpHook() { 這樣,只要在主程序中聲明IoCtrl的對(duì)象ic,就可以通過(guò)ic.StartIpHook()就可以實(shí)現(xiàn)對(duì)驅(qū)動(dòng)程序過(guò)濾功能的開啟,用同樣的方法也可以實(shí)現(xiàn)對(duì)驅(qū)動(dòng)程序進(jìn)行其它操作,比如添加、修改封包過(guò)濾規(guī)則等。 怎樣從驅(qū)動(dòng)程序向.NET應(yīng)用程序傳遞非托管的數(shù)據(jù)類型? 為了能夠輸出安全日志,必須讓主程序獲得驅(qū)動(dòng)程序中的封包信息。使用信號(hào)量機(jī)制可以很方便的實(shí)現(xiàn)驅(qū)動(dòng)程序和非托管代碼間的信息傳遞,那么對(duì)托管代碼呢?這需要向.NET應(yīng)用程序傳遞非托管的數(shù)據(jù)類型ACCESS_INFO。在NByte.h中,是這樣定義這個(gè)ACCESS_INFO結(jié)構(gòu)的: typedef struct _ACCESS_INFO { 顯然,直接傳遞非托管數(shù)據(jù)類型是不可以的,需要轉(zhuǎn)換一下。首先,在IoCtrl類中定義了幾個(gè)要傳遞的封包信息參數(shù): public __gc class IoCtrl 然后,在GetAccessInfo()函數(shù)中來(lái)給這些參數(shù)賦值: void GetAccessInfo() 既然在IoCtrl類中獲得了這些信息,但是需要把它們封裝成主程序容易處理的數(shù)據(jù)類型,這樣,用C#實(shí)現(xiàn)了InfoEvent類用來(lái)封裝這些信息: //本類封裝了數(shù)據(jù)包的詳細(xì)信息,可以通過(guò)事件實(shí)現(xiàn)對(duì)它的模塊間傳遞。 public class InfoEvent:EventArgs 下面在用托管C++實(shí)現(xiàn)的InfoProvider驅(qū)動(dòng)程序信息提供者類中把個(gè)InfoEvent類的對(duì)象傳遞給主程序,需要使用一個(gè)委托生成一個(gè)事件: //聲明委托事件,用來(lái)向主程序傳遞數(shù)據(jù)。 __delegate void DriverInfo(Object* sender, InfoEvent* e); //聲明響應(yīng)事件函數(shù)。 __event DriverInfo* OnDriverInfo; 然后在InfoProvider驅(qū)動(dòng)程序信息提供者類中定義一個(gè)方法,在主程序中以線程的方式運(yùn)行這個(gè)方法,在這個(gè)方法中使用了事件函數(shù)OnDriverInfo: //用來(lái)獲得驅(qū)動(dòng)程序信息的進(jìn)程,在主程序中將開啟該進(jìn)程。 void GetInfoThreadProc() while(true) OnDriverInfo(this,ie); ic->CloseDriverHandle(); 在主程序中,會(huì)開啟這個(gè)進(jìn)程并定義了OnDriverInfo的處理函數(shù)DealWithInfo: pInfo=new InfoProvider(); //開啟與驅(qū)動(dòng)交換信息的進(jìn)程 FilterThread=new Thread(new ThreadStart(pInfo.GetInfoThreadProc)); 這樣主程序就可以在DealWithInfo函數(shù)中加入對(duì)InfoEvent對(duì)象的處理了。可見,通過(guò)中間模塊IoCtrl的轉(zhuǎn)換,便實(shí)現(xiàn)了.NET主程序?qū)︱?qū)動(dòng)程序中非托管數(shù)據(jù)類型的獲取和處理。 |
溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!