阅读:5262回复:28
关于windows下包过滤技术的讨论,欢迎加入
在windows下开发包过滤的东东,找到几种技术,据我所知大概有三种:
1,ndis imd中间层过滤,这种技术很先进,可也有很大的缺点,windows各版本差异太大,很难做到统一,且安装比较麻烦,尤其是nt的安装,但却是ms推荐的技术。 2,截获windows api,对socket的发送和接收进行截取,这种我并不太了解,只知道其缺点是不能对所有的数据进行过滤 3,hook技术,这个技术可能是当前个人firewall的主要技术,安装方便,且各windows版差异并不大 由于本人只做过ndis imd,对2,3两项技术并不太了解,ndis imd在这里的讨论已经很多,所以我想请熟悉2,3技术的兄弟谈谈你们对这两种技术的看法,当然如果能讲一讲大致的实现方法更欢迎! 欢迎大家讨论! |
|
沙发#
发布于:2002-08-05 13:21
REGISTER FAKE PROTOCOL的方法在2K/XP下原理是一样的,而且我还做到了几乎是SOURCE的兼容,这个大家可以去大胆的尝试了,,。。。
但是现在我的问题是:当PFW遭遇SYN FLOOD的时候,驱动就把CPU给占完了,大家对于PFW防止SYN FLOOD有什么好的办法吗?可以讨论讨论吧 |
|
|
板凳#
发布于:2002-08-03 23:35
不需要装DS,只需要在VC里面设置好就可以直接用VC编译啦.
|
|
地板#
发布于:2002-08-02 12:42
装上driverstudio!
|
|
地下室#
发布于:2002-08-02 11:42
我用的是hook ndis的方法,看我的贴子 大狭,你怎么编译的,没有Makefile,直接在VC中编译吗 |
|
|
5楼#
发布于:2002-08-02 11:16
我用的是hook ndis的方法,看我的贴子
http://www.driverdevelop.com/forum/viewthread.php?tid=19249 http://www.driverdevelop.com/forum/viewthread.php?tid=19246 |
|
6楼#
发布于:2002-08-02 10:21
up ! up!
|
|
|
7楼#
发布于:2002-05-13 10:59
在pcause上看到这个,证明ndis imd在98&NT上的安装问题,依然是个大问题,
如果谁做过NT上的自动安装,可否讲讲经验! For example, although NDIS Intermediate (IM) drivers are quite effective for packet filtering on the Windows 2000 and Windows XP platforms, they are less practical to use on Windows NT and Windows 9X/ME. Issues that lead to impracticality include: Installation Issues - It may be possible to develop a NDIS IM driver for Windows 9X/ME and Windows NT, but difficult or impossible to install it. Operation On RAS/PPP Adapters - Microsoft does not provide a mechanism to filter packets on RAS/PPP adapters on Windows 9X/ME and Windows NT. Filtering on these adapters is essential for some products. Special Requirements - Some products have functional needs that simply are not provided by the standard NDIS APIs. |
|
8楼#
发布于:2002-05-13 10:38
这个例子要如何安装到机器上?
是否要自己写安装文件? 终于知道什么是export table了,呵呵,用dumpbin可以看到, 与不知道的共享 example:dumpbin /exports ndis.sys |
|
9楼#
发布于:2002-05-13 09:04
水木清华 -- DriverDev精华区文章阅读
-------------------------------------------------------------------------------- 发信人: Immortal1015 (1015), 信区: WinDDK 标 题: 一个win2000下的IP HOOK DRIVER 发信站: BBS 水木清华站 (Fri Mar 16 08:32:45 2001) 呵呵,因为做这个东东比较容易。 下面是源代码: #include \"ntddk.h\" #include \"ntddndis.h\" #include \"pfhook.h\" #include \"filter.h\" #define PROT_TCP 6 #define NT_DEVICE_NAME L\"\\\\Device\\\\IbanHook\" #define DOS_DEVICE_NAME L\"\\\\DosDevices\\\\IbanHookV1\" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT deviceObject=NULL; NTSTATUS status; PIPFILTER_INFO deviceInfo; UNICODE_STRING uniNtNameString; UNICODE_STRING uniWin32NameString; UNICODE_STRING uniIPFILTERNameString; PIRP ipFilterIRP=NULL; RtlInitUnicodeString(&uniNtNameString,NT_DEVICE_NAME); //1.创建一个设备 status=IoCreateDevice(DriverObject, sizeof(deviceInfo), &uniNtNameString, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject); if(!NT_SUCCESS(status)) { return status; } DriverObject->MajorFunction[IRP_MJ_CREATE]=SetFilterHook; DriverObject->MajorFunction[IRP_MJ_CLOSE]=CloseFilterHook; DriverObject->DriverUnload=FilterUnload; //2.创建SymbolName RtlInitUnicodeString(&uniWin32NameString,DOS_DEVICE_NAME); status=IoCreateSymbolicLink(&uniWin32NameString,&uniNtNameString); if(!NT_SUCCESS(status)) { IoDeleteDevice(DriverObject->DeviceObject); } deviceInfo=(PIPFILTER_INFO)deviceObject->DeviceExtension; //添加Hook if(deviceObject) { deviceInfo=(PIPFILTER_INFO)deviceObject->DeviceExtension; } RtlInitUnicodeString(&uniIPFILTERNameString, DD_IPFLTRDRVR_DEVICE_NAME); status=IoGetDeviceObjectPointer(&uniIPFILTERNameString, FILE_ALL_ACCESS, &deviceInfo->ipfilter , &deviceInfo->filterObject); deviceInfo->callback.ExtensionPointer= DropTcpPackets; ipFilterIRP=IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, deviceInfo->filterObject , &deviceInfo->callback , sizeof(deviceInfo->callback), NULL, 0, FALSE, NULL, NULL); status=IoCallDriver(deviceInfo->filterObject,ipFilterIRP ); if(!NT_SUCCESS(status)) { IoDeleteSymbolicLink(&uniWin32NameString); IoDeleteDevice(DriverObject->DeviceObject); return status; } return STATUS_SUCCESS; } NTSTATUS FilterUnload(PDRIVER_OBJECT DriverObject) { UNICODE_STRING uniWin32NameString; UNICODE_STRING uniIPFILTERNameString; PIRP ipFilterIRP=NULL; NTSTATUS status; PIPFILTER_INFO deviceInfo; //删除挂钩 if(DriverObject->DeviceObject) { deviceInfo=(PIPFILTER_INFO)(DriverObject->DeviceObject)->DeviceExtension; } RtlInitUnicodeString(&uniIPFILTERNameString, DD_IPFLTRDRVR_DEVICE_NAME); status=IoGetDeviceObjectPointer(&uniIPFILTERNameString, FILE_ALL_ACCESS, &deviceInfo->ipfilter , &deviceInfo->filterObject); deviceInfo->callback.ExtensionPointer= NULL; ipFilterIRP=IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, deviceInfo->filterObject , &deviceInfo->callback , sizeof(deviceInfo->callback), NULL, 0, FALSE, NULL, NULL); status=IoCallDriver(deviceInfo->filterObject,ipFilterIRP ); RtlInitUnicodeString(&uniWin32NameString,DOS_DEVICE_NAME); //删除SymbolicLink IoDeleteSymbolicLink(&uniWin32NameString); //删除设备 IoDeleteDevice(DriverObject->DeviceObject); return STATUS_SUCCESS; } //处理IRP_MJ_CREATE NTSTATUS SetFilterHook(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { KdPrint((\"ooh--create\")); Irp->IoStatus.Status=STATUS_SUCCESS; Irp->IoStatus.Information=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; } //处理IRP_MJ_CLOSE NTSTATUS CloseFilterHook(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { KdPrint((\"ooh--Close\")); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } // Drop all TCP packets PF_FORWARD_ACTION DropTcpPackets( unsigned char *PacketHeader, unsigned char *Packet, unsigned int PacketLength, unsigned int RecvInterfaceIndex, unsigned int SendInterfaceIndex, IPAddr RecvLinkNextHop, IPAddr SendLinkNextHop ) { /* if (((IPHeader *)PacketHeader)->iph_protocol == PROT_TCP) { KdPrint((\"TCP DATA\")); return PF_DROP; }*/ return PF_DROP; //return PF_FORWARD; } |
|
|
10楼#
发布于:2002-05-10 14:22
怎样看ndis.sys的export table,什么是pe-format?
哪位知道,帮忙讲解一下吧! 用softice敲exp列出的是export table吗? |
|
11楼#
发布于:2002-05-10 13:34
刚看到一篇关于2K下HOOK的文章!
Part III. NDIS Hooking Filter Driver in Windows NT/2000. For the best understanding of the technology stated in the given part acquaintance to a nucleus of operating systems of Windows NT/2000 is recommended. Acquaintance to writing kernel-mode drivers and the PE-format is desirable. How to start... Certainly from creation of the elementary driver. If for a Windows 9x/ME I have mentioned VToolsD for the given driver, for example, it is possible to use DriverWorks though certainly nothing prevents to write it, using DDK only and the compiler of the command line. I\'ve already mentioned, that for drivers of the given type the order of loading is important, the main requirement to our driver to boot after NDIS, but before TCPIP (and accordingly other protocols which we want to filter). As far as Windows 2000 and NT has a little different order of loading for the network subsystem, I shall not result concrete guidelines. (LoadOrder from www.osr.com utility displays the order of loading of drivers in convenient sort can help here. How to hook … Implementations NDIS are various in a Windows 9x/ME and NT/2000, now it will be enough to hook only 4 functions: - NdisRegisterProtocol - NdisDeregisterProtocol - NdisOpenAdapter - NdisCloseAdapter Hooking NdisSend has no sense any more, if you take a look in ndis.h you will see, that in our case this function is defined as macro. However these four functions need to be intercepted somehow. Right at the beginning of this part I already marked, that it is desirable to familiarize with the PE-format, this knowledge is necessary for interception. The essence of the technology is reduced to that it is necessary to find ndis.sys header image in the memory and to patch the export table of it, changing addresses for four functions above. All necessary structures for operation with PE-image are in the winnt.h file from DDK. In Windows NT 4.0 this technology will work fine, however, having started this driver under Windows 2000 or XP (and if large 4MB pages are not used, if used WP protection disabled), you will see only \" the dark blue screen of death \". The problem is that Windows 2000 protects a kernel image from possible modification. To resolve this problem there are two possible ways: 1) Disable protection of a kernel image through the registry. For this purpose it is necessary to create in a HKLM\\SYSTEM\\CurrentControlSet\\Control\\S essionManager\\Memory Management key REG_DWORD parameter with name EnforceWriteProtection and value 0. 2) Reset Write Protection bits in register CR0, before updating the export table. It can be done, for example as follows: mov ebx, cr0; to receive current state Cr0push ebx; to save it(him) and ebx, ~0x10000; to reset WP bats mov cr0, ebx; to switch off write protection ; Here we modify the table of export.... pop ebx; mov cr0, ebx; to restore the previous processor state I do not bring here the code for modification of the export table mainly, because it is not a unique way to intercept NDIS function. Daniel Lanciany (www.danlan.com) in his variant of NDIS-hooking driver has gone in other way, he has updated the beginning of functions, having inserted in them transitions to his code. In his handler he restores a body of the intercepted function, makes necessary operations on processing call, calles the restored function, and after return from it again modifies the beginning. As far as calls to this four functions set are not so often, this way is nothing worse than editing of the export table. However, should mention, that as well as a similar method of hooking DLL functions in User-mode it may appear unsafe on SMP platforms. What else it is necessary to do … I shall not stop in detail on new handler NdisRegisterProtocol, as it should make practically the same as in a Windows 9x/ME i.e. to expose the handler of entering traffic (actually it is necessary to change not only ReceiveHandler, but also in particular TransferDataCompleteHandler). The only thing I should mention here is that if 9x/ME TCP/IP driver (\"MSTCP\") registers one protocol and this protocol directly opens both Ethernet adapters and PPPMAC (emulation Ethernet above dial-up) then in NT/2000/XP TCP/IP actually consists of two drivers TCPIP.SYS (\"TCPIP\") and WANARP.SYS (\"TCPIP_WANARP\" in 2000/XP, \"RASARP\" in NT 4.0) and this second protocol opens emulation \\DEVICE\\NDISWANIP (emulating Ethernet upper interface of intermediate NDISWAN driver). The further operation in many respects is similar to writing of the driver of the network protocol, therefore I would advise to familiarize with appropriate section NT DDK (Network Drivers). The only complex enough moment is about new handler for NdisOpenAdapter. One of returned parameters of this function (NdisBindingHandle) actually is a pointer to NDIS_OPEN_BLOCKstructure . This structure is defined in ndis.h file, but, unfortunately, is not documented. This is important for us because it gives access to outgoing from the protocol traffic (fields SendHandler, SendPacketsHandler, and TransferDataHandler). Obviously, now it is necessary to transfer to the protocol our variant NDIS_OPEN_BLOCK, having saved the original. The following code is taken from new NdisOpenAdapter handler: ... // Save ProtocolBindingContext pAdapter - > m_ProtocolBindingContext = ProtocolBindingContext; // Allocate and initialize adapter namestatus = NdisAllocateMemory ( *pAdapter-> m_AdapterName. Buffer, AdapterName-> MaximumLength, 0, noMaxAddr ); if (status == NDIS_STATUS_SUCCESS){ NdisMoveMemory ( pAdapter-> m_AdapterName. Buffer, AdapterName-> Buffer, AdapterName-> MaximumLength ); pAdapter-> m_AdapterName. Length = AdapterName-> Length;pAdapter-> m_AdapterName. MaximumLength = AdapterName-> MaximumLength; } else { pAdapter-> m_AdapterName. Buffer = NULL; pAdapter-> m_AdapterName. Length = 0; pAdapter-> m_AdapterName. MaximumLength = 0; } // Call old NdisOpenAdapter handlerOF_NdisOpenAdapter ( Status, OpenErrorStatus, NdisBindingHandle, SelectedMediumIndex, MediumArray, MediumArraySize, NdisProtocolHandle, ProtocolBindingContext, AdapterName, OpenOptions, AddressingInformation ); if (((*Status == NDIS_STATUS_SUCCESS) || (*Status == NDIS_STATUS_PENDING))){ // Save old binding handle and adapter selected medium pAdapter - > m_NdisBindingHandle = *NdisBindingHandle; pAdapter - > m_Medium = MediumArray [*SelectedMediumIndex]; // we does not support adapters except ethernet and \\DEVICE\\NDISWANIP if (! ((pAdapter - > m_Medium == NdisMediumDix) || (pAdapter - > m_Medium == NdisMedium802_3) || (pAdapter - > m_Medium == NdisMediumWan))) { // Release already allocated resources AF_FreeAdapterEntry (pAdapter); NdisReleaseSpinLock (*g_OpenAdapterLock); return; } // Copy Real Open Block to our locationNdisMoveMemory ( *pAdapter - > m_OpenBlock, *NdisBindingHandle, sizeof (NDIS_OPEN_BLOCK) ); // Substitute Real Open Block by our Open Block*NdisBindingHandle = *pAdapter - > m_OpenBlock; if (*Status == NDIS_STATUS_SUCCESS) // Handlers already initialized{ // Pointer to our OPEN_BLOCK (for convnience) pOpenBlock = (PNDIS_OPEN_BLOCK) *NdisBindingHandle; pAdapter - > m_MacBindingHandle = pOpenBlock - > MacBindingHandle; // Substitute Some Real handlers by our versionpAdapter - > m_SendHandler = pOpenBlock - > SendHandler; pOpenBlock - > SendHandler = OBF_SendHandler; pAdapter - > m_SendPacketsHandler = pOpenBlock - > SendPacketsHandler;pOpenBlock - > SendPacketsHandler = OBF_SendPacketsHandler; pAdapter - > m_RequestHandler = pOpenBlock - > RequestHandler;pOpenBlock - > RequestHandler = OBF_RequestHandler; pAdapter - > m_TransferDataHandler = pOpenBlock - > TransferDataHandler; ... } What we have … Thus, the driver with minimum functionality turns out small enough and not complex in implementation. Installation of it does not make problem as well as in a case with the driver for a Windows 9x/ME and require adding of several keys in the registry. Besides the described static way of hooking NDIS library functions which demands loading the driver at a stage of start of the operating system and as such this driver can not be unloaded from memory, there is one more dynamic approach. This method works both under a Windows 9x/ME and under NT/2k/XP and though in the first case it is necessary to write VxD, and in the second kernel-mode the driver, a principle is identical. Among products existing in the market it is applied (besides control TDI and all started processes in the system) in rather known firewall ZoneAlarm (with widely recognized TrueVector technology). The essence of the approach that we register the dummy protocol (call NdisRegisterProtocol) i.e. which handlers do nothing, most complex of them can be ProtocolReceive, which returnes NDIS_STATUS_NOT_ACCEPTED. This protocol is one simple purpose to receive NdisProtocolHandle. Actually, it is the pointer to internal NDIS structure NDIS_PROTOCOL_BLOCK which, unfortunately, differs from one NDIS version to another and not always defined in ndis.h. And so in addition, this structure comprises NDIS_PROTOCOL_CHARACTERISTICS with addresses of all ProtocolXXX functions, NDIS_OPEN_BLOCK list (this structure in turn contains handlers Send/SendPackets/Request) all network interfaces bound to the given protocol and the pointer to next structure NDIS_PROTOCOL_BLOCK. The further is practically obvious, moving the list of registered protocols, we substitute the handlers where it is necessary. However, despite of seemless simplicity, this method is not simple and also demands the big care as we interfere with functionality of already working system. The conclusion: So, we have superficially considered the majority of approaches to firewall creation for the Windows platform, and the variant with interception NDIS was reviewed, as it seems to me, rather in details. As far as this is the only method which guarantees a complete control over network traffic, watching all registering protocols it seems to be the best way for network security relative projects. I did not try to teach you to write drivers in this small article, nonspecialists can address to DDK and learn about features of the Windows network subsystem . I can\'t say that this is easy to read material, but authors of books for some reason usually practically do not give NDIS attention, so this about the only source of information. From on-line resources, I think, it has some reasonable sense to look at www.pcausa.com., an example you can order NDISPIM samples in source built using the reviewed approach at http://www.pcausa.com/ndispim (common packet filtering framework for all Windows OS\'s from Win95Gold till WinXP). |
|
|
12楼#
发布于:2002-05-09 22:00
我想大家不要只说能或者不能,好或者不好,
如果哪位高人知道具体的方法,能否贴出来,我只知道方向,但不知道方法和实现细节! 还有胡大侠能否把在nt下自动安装的方法或者方向贴出来,让我等了解了解,长长见识,呵呵! |
|
13楼#
发布于:2002-05-09 20:50
哎~~又被批评了!555555~~~看来当不成妈妈的好孩子了!不过NT下的安装我的确没搞过!2000下我还是敢确定方法是正确的!
|
|
|
14楼#
发布于:2002-05-09 20:22
2000下的安装用netcfg是可以,只是会弹出数据签名窗口, nt下也能自动安装。 你问错了人。 |
|
|
15楼#
发布于:2002-05-09 19:48
看到一篇文章上这样讲,哪位给详细的分析一下,谢谢! 1.第一种有人做出来么?我看见pcausa上有一个PIM好像是基于这种思路的,但好像是在98下的(98下不是只需要Hook_Device就可以了么?) 2.第二种有个问题:假设注册的假协议装上之后,又有其他协议装上,怎么去挂钩后来安装的协议呢?(这种方法好像就是很久前那篇“网络数据包的通用拦截技术”所说的方法吧?) |
|
16楼#
发布于:2002-05-09 18:24
你说的第一种情况我见过别人详细讲解过。
至于第一种情况恐怕挺难的,说起来简单,做起来应该挺复杂,记得有人问过如何修改Ndis.sys的输出表,当时觉得他们说的好复杂,就没有仔细看了! |
|
|
17楼#
发布于:2002-05-09 14:39
看到一篇文章上这样讲,哪位给详细的分析一下,谢谢!
在Windows NT/2000下面如何实现Hook呢?有两种不同的思路: 1) 通过修改NDIS.SYS的Export Table。在Windows NT/2000下,可执行文件(包括DLL以及SYS)都是遵从PE(Portable Executable)格式的。所有向其他操作系统组件提供接口的驱动程序都有Export Table,因此只要修改NDIS.SYS的Export Table就可以实现对关键NDIS API的挂接。由于协议驱动程序在系统启动的时候会调用NdisRegisterProtocol来向系统进行协议注册,因此这种方法关键在于修改NDIS.SYS所提供的NdisRegisterProtocol/NdisDeRegisterProtocol/NdisOpenAdapter/NdisCloseAdapter/NdisSend函数的起始地址。我们知道,在用户态模式要修改PE文件格式可以用一些API来实现,而NDIS.SYS位于系统的核心内存区,因此要修改NDIS.SYS就不得不通过写驱动程序来实现,也就要求我们对PE文件格式有比较深入的了解。使用这种方法还要注意驱动程序的加载次序,显然Hook Driver必须在NDIS.SYS被加载之后,而在协议驱动程序如tcpip.sys被加载之前。另外,Windows2000还提供了系统文件保护机制,因此在修改ndis.sys还需要通过修改注册表屏蔽系统文件保护机制。 2) 向系统注册假协议(fake protocol)。在Windows内核中,所有已注册的协议是通过一个单向的协议链表来维护的。这个单向链表保存了所有已注册协议的NDIS_PROTOCOL_BLOCK结构的地址,在这个结构中保存了协议驱动所指定的相应的派发函数的地址如RECEIVE_HANDLER等。并且,每个协议驱动还对应一个NDIS_OPEN_BLOCK的单向链表来维护其所绑定的网卡信息。当协议驱动调用NdisRegisterProtocol之后,NDIS总是会把新注册的协议放在协议链表的表头并返回这张表,所以只要我们注册一个新的协议通过新协议注册返回的链表头就可以轻而易举的遍历系统中所有协议表。但是,如果要成功地挂接派发函数,还需要对协议所对应的NDIS_OPEN_BLOCK结构里的派发函数进行挂接,因为NDIS并不是直接调用协议驱动在NDIS_PROTOCOL_CHARACTERISTICS所注册的派发函数地址,而是调用NDIS_OPEN_BLOCK里的派发函数。值得注意的是,在Windows9x/Me/NT的DDK中,NDIS_PROTOCOL_BLOCK的定义是很明确的,而在Windows 2000/xp的DDK中,并没有该结构的详细定义,也就是说该结构在Windows2000/xp下是非公开的,因此开发人员需要利用各种调试工具来发掘该结构的详细定义。也正是因为如此,这种方法对平台的依赖性比较大,需要在程序中判断不同的操作系统版本而使用不同的结构定义。 |
|
18楼#
发布于:2002-05-09 12:50
我记得那位大虾说过xp DDK,可以转换vxd 到wdm 找一xpddk来研究一下吧。也许很简单呢。
|
|
|
19楼#
发布于:2002-05-09 12:37
我做过hook技术的,也刚刚完成!觉得hook就一点,搞清ndis的流程,然后就是对windows系统程序设计的问题了。
其实对NT防火墙来说好象不能用hook,因为ndis4。0以后的版本就提了分层结构,另外nt结构好象也不提供hook技术了。不知道我的理解对不对。记得胡斑竹曾教导过,在nt下hook技术很复杂,一般不用他来做防火墙,一般用IMD! 祝大家好运!! |
|
|
上一页
下一页