謝秀維
中國人民銀行滄州中心支行科技科 河北 061001
隨著Internet不斷的發(fā)展和普及,網(wǎng)絡(luò)信息安全問題越來越受到人的關(guān)注,時(shí)常讓人擔(dān)憂。攻擊者利用計(jì)算機(jī)硬件、軟件、網(wǎng)絡(luò)設(shè)備等安全漏洞進(jìn)行攻擊。攻擊事件一旦發(fā)生就可能導(dǎo)致有關(guān)的服務(wù)中斷、重要商業(yè)信息失竊、研究機(jī)構(gòu)的重要數(shù)據(jù)丟失甚至涉及到國家機(jī)密等,其災(zāi)難性后果不言而喻。防火墻是網(wǎng)絡(luò)信息安全的主要技術(shù)手段之一,個(gè)人防火墻得到了廣泛應(yīng)用。
由于防火墻涉及系統(tǒng)文件SYS、動(dòng)態(tài)連接庫DLL和用戶界面應(yīng)用程序EXE,因此,不同進(jìn)程間數(shù)據(jù)共享就變得至關(guān)重要。DLL安裝在應(yīng)用程序和驅(qū)動(dòng)程序之間,為上層應(yīng)用程序提供網(wǎng)絡(luò)連接服務(wù)。
DLL與EXE及其它調(diào)用它的進(jìn)程都需要共享控管規(guī)則數(shù)據(jù),但這些數(shù)據(jù)都不是固定長度的,因此選用了內(nèi)存映射的方法。此外,由于DLL和SYS都是對截獲的封包緩沖區(qū)進(jìn)行操作,如采用全局變量則會降低模塊的獨(dú)立性,而采用內(nèi)存映射正好解決了這一問題。
因?yàn)?Windows2000不允許應(yīng)用層的程序直接訪問系統(tǒng)內(nèi)存的地址空間,為了在EXE,DLL和SYS之間共享內(nèi)存,實(shí)現(xiàn)內(nèi)存共享的原理是:首先用驅(qū)動(dòng)程序(SYS)申請內(nèi)存空間,SYS中申請的內(nèi)存在系統(tǒng)地址空間(>=0x80000000),為了讓EXE和DLL能夠訪問這個(gè)空間,需要將系統(tǒng)地址空間映射到用戶地址空間(<0x80000000),具體的步驟是:
(1) 在SYS中申請內(nèi)存空間,代碼如下:
SystemVirtualAddress=MmAllocateContiguousMemory(NumberOfBytes,HighestAcceptableAddress );
(2) 申請一個(gè)MDL結(jié)構(gòu),代碼如下:
Mdl = IoAllocateMdl (SystemVirtualAddress, NumberOfBytes,FALSE,FALSE, NULL);
(3) 在MDL結(jié)構(gòu)中標(biāo)識內(nèi)存頁
①如果申請內(nèi)存時(shí)使用了非分頁池(non-paged pool),使用下面的代碼:
MmBuildMdlForNonPagedPool (Mdl);
②如果申請內(nèi)存時(shí)使用了分頁池(paged pool),使用下面的代碼:
MmProbeAndLockPages (Mdl, KernelMode, IoWriteAccess);
(4) 將鎖定的內(nèi)存頁映射到應(yīng)用層(EXE或DLL)的用戶地址空間,代碼如下:
UserVirtualAddress=MmMapLockedPages (Mdl, UserMode);
上面的4個(gè)步驟可以在DriverEntry或者DispatchRoutine中運(yùn)行。
釋放內(nèi)存大致是執(zhí)行與上面相反的過程。步驟如下:
(1) 在用戶進(jìn)程上下文環(huán)境中執(zhí)行下面的代碼,解除到用戶地址空間的映射:
MmUnmapLockedPages (UserVirtualAddress, Mdl);
(2) 如果使用MmProbleAndLockPages鎖定了內(nèi)存空間,使用下面的代碼解鎖:
MmUnlockPages (Mdl);
(3) 釋放MDL,代碼如下: IoFreeMdl (Mdl);
(4) 釋放系統(tǒng)空間,代碼如下:
MmFreeContiguousMemory (SystemVirtualAddress);
或者:ExFreePool (SystemVirtualAddress);
在上述四個(gè)步驟中,第一步必須在用戶進(jìn)程上下文環(huán)境中執(zhí)行,2, 3, 4步可以在DriverEntry或者DispatchRoutine中運(yùn)行。
NETLAB.EXE與NETLAB.DLL主要需要進(jìn)行控管規(guī)則數(shù)據(jù)和封包數(shù)據(jù)的共享,另外需要一些其它輔助操作。它之間的接口函數(shù)為XfIoControl,此函數(shù)在NETLAB.DLL的TCPIPDOG.CPP模塊。
NETLAB.EXE通過LoadLibrary打開NETLAB.DLL,然后通過GetProcAddress得到XfIoControl函數(shù)的地址,以后NETLAB.EXE便通過XfIoControl函數(shù)完成與NETLAB.DLL的通信。XfIoControl支持的操作如下:
(1) 控制代碼:IO_CONTROL_SET_NETLAB_PROCESS_ID
參數(shù)含義:IoControl->DWord:進(jìn)程ID
IoControl->DWord2:進(jìn)程完整路徑指針
(2) 控制代碼:IO_CONTROL_SET_WORK_MODE
參數(shù)含義:IoControl->Byte:總工作模式
(3) 控制代碼:IO_CONTROL_GET_SESSION_FILE_HANDLE
參數(shù)含義:IoControl->DWord:返回封包緩沖區(qū)的地址
作用:NETLAB.EXE從NETLAB.DLL得到封包緩沖區(qū)的地址,由于內(nèi)存映射文件不同進(jìn)程映射的地址不同,所以此參數(shù)不能真正作為地址來用,只是用來區(qū)分NETLAB.DLL是否成功創(chuàng)建了封包緩沖區(qū),等于0表示否定,大于0表示肯定。
驅(qū)動(dòng)程序模塊或者NETLABPCK.SYS與NETLAB.EXE和NETLAB.DLL之間主要需要進(jìn)行控管規(guī)則數(shù)據(jù)、封包數(shù)據(jù)、網(wǎng)上鄰居名字列表等數(shù)據(jù)的共享,另外需要一些其它輔助操作。它們之間的接口函數(shù)為OnW32DeviceIoControl,此函數(shù)在NETLABPCK 的NETLABPCK.C模塊。
NETLAB.EXE通過CreateFile打開NETLABPCK.SYS,然后通過DeviceIoControl完成與NETLABPCK的通信。
Typedef struct tagIOCTLParams {
DWORD dioc_IOCtICode;
PVOID dioc_InBuf;
DWORD dioc_c_cblnBuf;
PVOID dioc_OutBuf;
DWORD dioc_c_bOutBuf;
} IOCTLPARAMS,* PIOCTLPARAMS
設(shè)備輸入輸出處理函數(shù)為OnW32Deviceiocontrol(PIOCT LPARAMS,pVtoolsD),根據(jù)pVtoolsD-> dioc_IOCtICode不同而進(jìn)行不同操作,具體分為以下情況:
(1) 控制代碼:IOCTL_NETLABPCK_MALLOC_ACL_BUFFER
參數(shù)含義:
pVtoolsD->dioc_InBuf: 指向DWORD的指針,需要申請的控管規(guī)則內(nèi)存空間大小。
(2) 控制代碼:IOCTL_NETLABPCK_FREE_ACL_BUFFER
作用:NETLAB.EXE通知NETLABPCK釋放為控管規(guī)則申請的內(nèi)存空間。
(3)控制代碼:IOCTL_NETLABPCK_GET_BUFFER_POINT
參數(shù)含義:
pVtoolsD->dioc_dioc_OutBuf:指向 PACKET_BUFFER_POINT結(jié)構(gòu)的緩沖區(qū)指針,用來返回封包緩沖區(qū)的地址、讀/寫緩沖區(qū)的索引地址和封包緩沖區(qū)能容納封包記錄的最大個(gè)數(shù)。
作用:NETLAB.EXE通過這個(gè)控制代碼,從NETLABPCK取得封包緩沖區(qū)的地址。封包緩沖區(qū)由NETLABPCK生成和維護(hù),NETLAB.EXE負(fù)責(zé)提取信息并用來顯示、詢問、報(bào)警和保存日志。
(4) 控制代碼:IOCTL_NETLABPCK_DELETE_SPI_PORT
參數(shù)含義:
pVtoolsD->dioc_InBuf:指向WORD類型的指針,保存要?jiǎng)h除的SPI端口。
作用:NETLAB.DLL通過NETLABPCK刪除共享內(nèi)存的端口列表。當(dāng)經(jīng)過NETLAB.DLL過濾的端口完成通信而釋放時(shí),通過這個(gè)控制代碼刪除共享內(nèi)存的端口列表,告訴驅(qū)動(dòng)程序,這個(gè)端口已經(jīng)不再被NETLAB.DLL過濾,驅(qū)動(dòng)程序需要負(fù)責(zé)對這個(gè)端口進(jìn)行過濾。
(5) 控制代碼:IOCTL_NETLABPCK_GET_NAME_F ROM_IP
參數(shù)含義:pVtoolsD->dioc_InBuf: 要查詢的IP地址;
pVtoolsD->dioc_OutBuf: 用來返回查詢得到的網(wǎng)上鄰居名字。
作用:FITLER.EXE通過這個(gè)控制代碼,從IP地址查詢得到網(wǎng)上鄰居的名字。
隨著Internet技術(shù)的發(fā)展,網(wǎng)絡(luò)安全將會面臨更加嚴(yán)峻的挑戰(zhàn)。本文從技術(shù)角度出發(fā),對防火墻內(nèi)部主要模塊間的通訊技術(shù)進(jìn)行了詳細(xì)的分析和介紹,希望能對不同的用戶提供參考。
[1] Keith E.Strassberg,Richard J.Gondek,Gary Rollie等著.李昂等譯.防火墻技術(shù)大全.北京:機(jī)械工業(yè)出版社.2003.
[2] Terry William Ogletree 著.李之棠等譯.防火墻的原理與實(shí)施.北京:電子工業(yè)出版社.2001.
[3] 博嘉科技.LINUX防火墻技術(shù)探秘.北京:國防工業(yè)出版社.2002.
[4] 周宏,劉克勤.新型主機(jī)防火墻模型的研究.現(xiàn)代電力.2003.