IP过滤-驱动和应用程序通信
生活随笔
收集整理的這篇文章主要介紹了
IP过滤-驱动和应用程序通信
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前段時間寫一個IP過濾的驅(qū)動,以前沒有接觸過驅(qū)動,Google一把,網(wǎng)上有很多例子,不過都不能滿足自己的需求,所以就參考大家的資料自己研究一下。呵呵。程序用了三層:第一層就是驅(qū)動來負(fù)責(zé)過濾數(shù)據(jù)包并把攔截的結(jié)果返回給應(yīng)用程序。第二層VC動態(tài)鏈接庫來負(fù)責(zé)加載卸載驅(qū)動,和驅(qū)動通信。并提供接口給第三層調(diào)用。第三層C#Winform,調(diào)用VC動態(tài)鏈接庫提供的接口,間接和驅(qū)動通信,并顯示驅(qū)動返回結(jié)果。
用到最多的就是DeviceIoControl這個函數(shù),可以通過這個函數(shù)向驅(qū)動程序發(fā)送消息,還可以從驅(qū)動程序獲取消息,下面讓我們來看一下這個函數(shù)的結(jié)構(gòu)吧: BOOL DeviceIoControl( HANDLE hDevice, //創(chuàng)建的驅(qū)動設(shè)備句柄 DWORD dwIoControlCode, //應(yīng)用程序調(diào)用驅(qū)動程序的控制命令 LPVOID lpInBuffer, //應(yīng)用程序傳遞給驅(qū)動程序的數(shù)據(jù)緩沖區(qū)地址 DWORD nInBufferSize, //應(yīng)用程序傳遞給驅(qū)動程序的數(shù)據(jù)緩沖區(qū)大小,字節(jié)數(shù) LPVOID lpOutBuffer, //驅(qū)動程序返回給應(yīng)用程序的數(shù)據(jù)緩沖區(qū)地址 DWORD nOutBufferSize, //驅(qū)動程序返回給應(yīng)用程序的數(shù)據(jù)緩沖區(qū)大小,字節(jié)數(shù) LPDWORD lpBytesReturned, //驅(qū)動程序?qū)嶋H返回給應(yīng)用程序的數(shù)據(jù)字節(jié)數(shù)地址 LPOVERLAPPED lpOverlapped//重疊操作結(jié)構(gòu) 一般設(shè)為NULL ); 向驅(qū)動發(fā)消息: DWORD WriteIo(DWORD code, PVOID buffer, DWORD count) { if(driverHandle == NULL) return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned; BOOL returnCode = DeviceIoControl(driverHandle, ?????? ?code, ??????? buffer, ??????? count, ???????NULL, ??????? 0, ???????&bytesReturned, ??????? NULL); if(!returnCode) return DRV_ERROR_IO; return DRV_SUCCESS; }
從驅(qū)動獲取消息:
DWORD ?ReadIo(DWORD code, PVOID buffer, DWORD count) { if(driverHandle == NULL) return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned; BOOL retCode = DeviceIoControl(driverHandle, ? code, ? NULL, ? 0, ? buffer, ? count, ? &bytesReturned, ? NULL);
if(!retCode) return DRV_ERROR_IO;
return DRV_SUCCESS; }
有了這兩個函數(shù)我們就可以向驅(qū)動發(fā)消息和從驅(qū)動獲取數(shù)據(jù)了。我們可以通過Writeto 把要添加或刪除的Ip過濾規(guī)則發(fā)給驅(qū)動程序。下一步我們要做的就是當(dāng)驅(qū)動攔截到添加的IP過濾規(guī)則后怎么通知應(yīng)用程序。這里用到了CreateEvent,然后把這個m_hCommEvent 通過Writeto?通知給驅(qū)動, BOOL ??CreateFilterEvent(DWORD code) {? m_hCommEvent= CreateEvent(NULL, false, false, NULL); if(driverHandle == NULL) { MessageBox(NULL,TEXT("driverHandle is null"),NULL,MB_OK);? //return FALSE; }? DWORD dwReturn; //download event object to device driver BOOL retCode = DeviceIoControl(driverHandle,? code,? ?? ? ? &m_hCommEvent, sizeof(m_hCommEvent),? NULL,? 0,? &dwReturn,? NULL); if(retCode) { ? return TRUE; } else { return FALSE; } } 然后通過CreateThread創(chuàng)建一下線程來接受驅(qū)動的消息, 在線程函數(shù)里寫: while(threadFlag) { ? if(m_hCommEvent) { WaitForSingleObject(m_hCommEvent,INFINITE); ? //收到驅(qū)動的通知 //從驅(qū)動取數(shù)據(jù) //通知C#窗體 ResetEvent(m_hCommEvent); } } 驅(qū)動里做一下處理: HANDLE hEvent =*(PHANDLE)ioBuffer; NTSTATUS status = ObReferenceObjectByHandle( hEvent, GENERIC_ALL, NULL, KernelMode, &gpEventObject, &objHandleInfo); if(!NT_SUCCESS(status)) ?? ? ?{? ? ?if(gpEventObject) { ?ObDereferenceObject(gpEventObject); } if(hEvent) {
} ?? ? ? ? ? ? ?Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; } if(status != STATUS_SUCCESS) { DbgPrint("ObReferenceObjectByHandle failed! status = %x\n", status); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } 當(dāng)驅(qū)動攔截到過濾的IP數(shù)據(jù)包的時候: if(gpEventObject) ?? ? ??{? //一個變量賦值等應(yīng)用程序收到通知的時候來去這個數(shù)據(jù) ?? ? ? ? ? ??KeSetEvent(gpEventObject, 0,FALSE);//by Fs.song ?? ? ?}
只是程序記錄。
用到最多的就是DeviceIoControl這個函數(shù),可以通過這個函數(shù)向驅(qū)動程序發(fā)送消息,還可以從驅(qū)動程序獲取消息,下面讓我們來看一下這個函數(shù)的結(jié)構(gòu)吧: BOOL DeviceIoControl( HANDLE hDevice, //創(chuàng)建的驅(qū)動設(shè)備句柄 DWORD dwIoControlCode, //應(yīng)用程序調(diào)用驅(qū)動程序的控制命令 LPVOID lpInBuffer, //應(yīng)用程序傳遞給驅(qū)動程序的數(shù)據(jù)緩沖區(qū)地址 DWORD nInBufferSize, //應(yīng)用程序傳遞給驅(qū)動程序的數(shù)據(jù)緩沖區(qū)大小,字節(jié)數(shù) LPVOID lpOutBuffer, //驅(qū)動程序返回給應(yīng)用程序的數(shù)據(jù)緩沖區(qū)地址 DWORD nOutBufferSize, //驅(qū)動程序返回給應(yīng)用程序的數(shù)據(jù)緩沖區(qū)大小,字節(jié)數(shù) LPDWORD lpBytesReturned, //驅(qū)動程序?qū)嶋H返回給應(yīng)用程序的數(shù)據(jù)字節(jié)數(shù)地址 LPOVERLAPPED lpOverlapped//重疊操作結(jié)構(gòu) 一般設(shè)為NULL ); 向驅(qū)動發(fā)消息: DWORD WriteIo(DWORD code, PVOID buffer, DWORD count) { if(driverHandle == NULL) return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned; BOOL returnCode = DeviceIoControl(driverHandle, ?????? ?code, ??????? buffer, ??????? count, ???????NULL, ??????? 0, ???????&bytesReturned, ??????? NULL); if(!returnCode) return DRV_ERROR_IO; return DRV_SUCCESS; }
從驅(qū)動獲取消息:
DWORD ?ReadIo(DWORD code, PVOID buffer, DWORD count) { if(driverHandle == NULL) return DRV_ERROR_INVALID_HANDLE;
DWORD bytesReturned; BOOL retCode = DeviceIoControl(driverHandle, ? code, ? NULL, ? 0, ? buffer, ? count, ? &bytesReturned, ? NULL);
if(!retCode) return DRV_ERROR_IO;
return DRV_SUCCESS; }
有了這兩個函數(shù)我們就可以向驅(qū)動發(fā)消息和從驅(qū)動獲取數(shù)據(jù)了。我們可以通過Writeto 把要添加或刪除的Ip過濾規(guī)則發(fā)給驅(qū)動程序。下一步我們要做的就是當(dāng)驅(qū)動攔截到添加的IP過濾規(guī)則后怎么通知應(yīng)用程序。這里用到了CreateEvent,然后把這個m_hCommEvent 通過Writeto?通知給驅(qū)動, BOOL ??CreateFilterEvent(DWORD code) {? m_hCommEvent= CreateEvent(NULL, false, false, NULL); if(driverHandle == NULL) { MessageBox(NULL,TEXT("driverHandle is null"),NULL,MB_OK);? //return FALSE; }? DWORD dwReturn; //download event object to device driver BOOL retCode = DeviceIoControl(driverHandle,? code,? ?? ? ? &m_hCommEvent, sizeof(m_hCommEvent),? NULL,? 0,? &dwReturn,? NULL); if(retCode) { ? return TRUE; } else { return FALSE; } } 然后通過CreateThread創(chuàng)建一下線程來接受驅(qū)動的消息, 在線程函數(shù)里寫: while(threadFlag) { ? if(m_hCommEvent) { WaitForSingleObject(m_hCommEvent,INFINITE); ? //收到驅(qū)動的通知 //從驅(qū)動取數(shù)據(jù) //通知C#窗體 ResetEvent(m_hCommEvent); } } 驅(qū)動里做一下處理: HANDLE hEvent =*(PHANDLE)ioBuffer; NTSTATUS status = ObReferenceObjectByHandle( hEvent, GENERIC_ALL, NULL, KernelMode, &gpEventObject, &objHandleInfo); if(!NT_SUCCESS(status)) ?? ? ?{? ? ?if(gpEventObject) { ?ObDereferenceObject(gpEventObject); } if(hEvent) {
} ?? ? ? ? ? ? ?Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; } if(status != STATUS_SUCCESS) { DbgPrint("ObReferenceObjectByHandle failed! status = %x\n", status); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } 當(dāng)驅(qū)動攔截到過濾的IP數(shù)據(jù)包的時候: if(gpEventObject) ?? ? ??{? //一個變量賦值等應(yīng)用程序收到通知的時候來去這個數(shù)據(jù) ?? ? ? ? ? ??KeSetEvent(gpEventObject, 0,FALSE);//by Fs.song ?? ? ?}
只是程序記錄。
轉(zhuǎn)載于:https://www.cnblogs.com/henusfs/archive/2009/08/13/1545161.html
總結(jié)
以上是生活随笔為你收集整理的IP过滤-驱动和应用程序通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSONNull
- 下一篇: 一个人有没有大数据思维,主要体现在哪两个