分享
 
 
 

书写NDIS过滤钩子驱动实现ip包过滤

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

转贴:原作者安全焦点

在普通的WINDOWS 2000下实现实现包过滤的方法主要是书写NDIS过滤驱动程序,需要的技巧比较高,而且烦琐,需要考虑很多细节。但是对于很多应用而言,只需要能更方便的对ip包进行过滤处理,其实NDIS对于ip包的过滤提供一种书写过滤钩子驱动的方式,主要方法是:

驱动中建立一个普通的设备,然后通过IOCTL_PF_SET_EXTENSION_POINTER操作将你的内核模式的过滤钩子挂接到系统默认的ip过滤驱动上,这样你就可以在自己的过滤钩子里面实现完整的基于包的各种分析和过滤的处理了。

下面就是一个完整的NDIS过滤钩子驱动的代码拒绝所有外来的TCP带S的建立连接的请求。

注意事项:

1。需要在DDK环境中编译

2。需要修改注册表中LMHK\System\\CurrentControlSet\\Services\\IPFILTERDRIVER的START类型为3,让他随系统启动而启动

3。编译生成了sys文件后需要拷贝到winnt\system32\drivers目录下

4。需要运行一个程序后手动生成注册表项

5。使用时用net start fxfilthook启动驱动,用net stop fxfilthook停止驱动

6。此方法只能对ip包进行过滤,其他的协议不会经过这个过滤钩子进行处理。

//驱动程序的头文件

#include "ntddk.h"

#include "ntddndis.h"

#include "pfhook.h"

#ifndef __NTHANDLE_H

#define __NTHANDLE_H

#define NT_DEVICE_NAME L"\\Device\\Fxfilthook"

#define DOS_DEVICE_NAME L"\\DosDevices\\Fxfilthook"

#define PROT_TCP 6

#include "ntddk.h"

#include "xfilthook.h"

typedef struct IPHeader {

UCHAR iph_verlen; // Version and length

UCHAR iph_tos; // Type of service

USHORT iph_length; // Total datagram length

USHORT iph_id; // Identification

USHORT iph_offset; // Flags, fragment offset

UCHAR iph_ttl; // Time to live

UCHAR iph_protocol; // Protocol

USHORT iph_xsum; // Header checksum

ULONG iph_src; // Source address

ULONG iph_dest; // Destination address

} IPHeader;

NTSTATUS

DriverEntry(

IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath);

NTSTATUS

CreateFilterHook

(IN PDRIVER_OBJECT DriverObject);

VOID

DriverUnload

(IN PDRIVER_OBJECT DriverObject);

PF_FORWARD_ACTION

IpFilterHook(

IN unsigned char *PacketHeader,

IN unsigned char *Packet,

IN unsigned int PacketLength,

IN unsigned int RecvInterfaceIndex,

IN unsigned int SendInterfaceIndex,

IN IPAddr RecvLinkNextHop,

IN IPAddr SendLinkNextHop);

#endif

//驱动程序的c文件

#define PROT_TCP 6

#include "ntddk.h"

#include "ntddndis.h"

#include "pfhook.h"

#include "fxfilthook.h"

PDEVICE_OBJECT deviceObject;

UNICODE_STRING win32DeviceName;

//住驱动入口点

NTSTATUS

DriverEntry(

IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath

)

{

NTSTATUS status = STATUS_SUCCESS;

UNICODE_STRING ntDeviceName;

RtlInitUnicodeString(&ntDeviceName,NT_DEVICE_NAME);

//建立一个过滤钩子驱动设备

status = IoCreateDevice (DriverObject,0,&ntDeviceName,FILE_DEVICE_UNKNOWN,0,TRUE,&deviceObject);

if (!NT_SUCCESS (status)) {

goto ERROR;

}

RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

//建立一个过滤钩子驱动设备符号连接

status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );

if (!NT_SUCCESS(status)) // If we couldn't create the link then

{ // abort installation.

goto ERROR;

}

//申明卸载例程

DriverObject-DriverUnload = DriverUnload;

//建立钩子挂接

status = CreateFilterHook(DriverObject);

if (!NT_SUCCESS(status)) // If we couldn't create the link then

{ // abort installation.

IoDeleteSymbolicLink(&win32DeviceName);

goto ERROR;

}

return(STATUS_SUCCESS);

ERROR:

if(deviceObject)

IoDeleteDevice(deviceObject);

//DbgPrint( "Leave DriverEntry failed\n" );

return status;

}

NTSTATUS

CreateFilterHook(IN PDRIVER_OBJECT DriverObject)

{

PIRP nirp;

NTSTATUS status = STATUS_SUCCESS;

PFILE_OBJECT filtfileob;

UNICODE_STRING ntDeviceName;

PDEVICE_OBJECT filtdeviceob;

PF_SET_EXTENSION_HOOK_INFO filthook;

IO_STATUS_BLOCK filtstatus;

RtlInitUnicodeString(&ntDeviceName,L"\\Device\\IPFILTERDRIVER");

//将钩子挂接函数放入结构中

filthook.ExtensionPointer = IpFilterHook;

//获得系统ipfilterdriver驱动的设备指针

status = IoGetDeviceObjectPointer(&ntDeviceName,FILE_GENERIC_READ|FILE_GENERIC_WRITE,&filtfileob,&filtdeviceob);

if(status!=STATUS_SUCCESS)

return status;

//绑定过滤钩子到系统ipfilterdriver驱动的设备指针

nirp = IoBuildDeviceIoControlRequest(

IOCTL_PF_SET_EXTENSION_POINTER,

filtdeviceob,

&filthook,

sizeof(PF_SET_EXTENSION_HOOK_INFO),

NULL,

0,

FALSE,

NULL,

&filtstatus);

if(nirp==NULL)

return filtstatus.Status;

//调度系统ipfilterdriver设备重新操作irp

return (IoCallDriver(filtdeviceob,nirp));

}

VOID

DriverUnload(IN PDRIVER_OBJECT DriverObject)

{

//与加载一样,只是钩子函数结构中放NULL,让系统ipfilterdriver卸载加载的钩子函数

PIRP nirp;

NTSTATUS status = STATUS_SUCCESS;

PDEVICE_OBJECT filtdeviceob;

PFILE_OBJECT filtfileob;

PF_SET_EXTENSION_HOOK_INFO filthook;

IO_STATUS_BLOCK filtstatus;

UNICODE_STRING ntDeviceName;

RtlInitUnicodeString(&ntDeviceName,L"\\Device\\IPFILTERDRIVER");

filthook.ExtensionPointer = NULL;

status = IoGetDeviceObjectPointer(&ntDeviceName,FILE_GENERIC_READ|FILE_GENERIC_WRITE,&filtfileob,&filtdeviceob);

if(status==STATUS_SUCCESS)

{

nirp = IoBuildDeviceIoControlRequest(

IOCTL_PF_SET_EXTENSION_POINTER,

filtdeviceob,

&filthook,

sizeof(PF_SET_EXTENSION_HOOK_INFO),

NULL,

0,

FALSE,

NULL,

&filtstatus);

if(nirp!=NULL)

IoCallDriver(filtdeviceob,nirp);

}

IoDeleteSymbolicLink(&win32DeviceName);

IoDeleteDevice(deviceObject);

return;

}

PF_FORWARD_ACTION

IpFilterHook(

unsigned char *PacketHeader,

unsigned char *Packet,

unsigned int PacketLength,

unsigned int RecvInterfaceIndex,

unsigned int SendInterfaceIndex,

IPAddr RecvLinkNextHop,

IPAddr SendLinkNextHop

)

{

//过滤钩子函数,这儿只简单判断属于TCP协议且数据是抵达而且带SYN标志则过滤。大家可以根据需要修改自己的过滤判断和处理。

if(((IPHeader *)PacketHeader)-iph_protocol == PROT_TCP)

{

//Packet[13]==0x2就是TCP中SYN的标志

//SendInterfaceIndex==INVALID_PF_IF_INDEX说明包是抵达而不是发送的,因此这样过滤就不会影响自己的包出去,但是外来带SYN请求的包则会拒绝。

if(Packet[13]==0x2 && SendInterfaceIndex==INVALID_PF_IF_INDEX)

return PF_DROP;

}

return PF_FORWARD;

}

//简单的建立注册表项的程序

unsigned char sysdir[256];

unsigned char drivcedir[256];

int RegHandelDev(char * exename)

{

//修改注册表启动一个NTHANDLE驱动程序

char subkey[200];

int buflen;

HKEY hkResult;

char Data[4];

DWORD isok;

buflen = sprintf(subkey,"System\\CurrentControlSet\\Services\\%s",exename);

subkey[buflen]=0;

isok = RegCreateKey(HKEY_LOCAL_MACHINE,subkey,&hkResult);

if(isok!=ERROR_SUCCESS)

return FALSE;

Data[0]=3;

Data[1]=0;

Data[2]=0;

Data[3]=0;

isok=RegSetValueEx(hkResult,"Start",0,4,(const unsigned char *)Data,4);

Data[0]=1;

isok=RegSetValueEx(hkResult,"Type",0,4,(const unsigned char *)Data,4);

isok=RegSetValueEx(hkResult,"ErrorControl",0,4,(const unsigned char *)Data,4);

GetSystemDirectory(sysdir,256);

buflen = sprintf(drivcedir,"%s\\Drivers\\FxFiltHook.sys",sysdir);

buflen = sprintf(subkey,"\\??\\%s",drivcedir);

subkey[buflen]=0;

isok=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)subkey,buflen);

RegCloseKey(hkResult);

buflen = sprintf(subkey,"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s",exename);

subkey[buflen]=0;

return TRUE;

}

int main(int argc,char *argv[])

{

//注册驱动程序

if(RegHandelDev("Fxfilthook")==FALSE)

return FALSE;

return TRUE;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有