-
-
[原创]nt到win7的防火墙研究之TDI
-
发表于:
2009-12-23 18:11
15311
-
tdi防火墙驱动,这个构架是tdifw这个开源网站率先提出的。微软也发扬他一贯的作风,在win7里面全面封杀这种防火墙驱动的写法。对于微软,技术的霸道和垄断不用质疑。可是tdi防火墙驱动依照他良好的架构,和简易的编程一举囊获了从win2000-win vista的这些个版本,至于之后出来的这个怪胎,现在国人对于他的态度是直接启用ndsi驱动,有种你微软把这个也封杀掉,我看你pppoe咋做,我看你tcp咋做,我看你虚拟网卡咋做。
所以将来可能防火墙都有两个以上的内核,一个是nt-vista的,另外一个是win7以后的,听说微软已经开始招募win8开发人员了。看来微软是被这win7的销售高潮冲晕了。要知道现在多数客户还在死守xp,要知道还有很多程序员没转vista,要知道你的win7现在还没有引来良性发展。嗨~~~~~~中国啥时候能出一个操作系统啊,甚至是黑屏cmd,甚至是没有命令,咱都支持,我**个肺微软。
tdi驱动模式本着是irp过滤型驱动的模型做的,也就是标准的attach模型。
1.创建设备
2.attach上自己想要attach的设备
3.重新定向自己想要定向的所有irp
4.建立irp完成机制,对于一些不能等待的irp请求,做完成等待处理
(所谓完成等待,这就是微软这些贱人想出来的鳖招,我们不能叫一个Irp等待,因为这样我们的io控制器负担会很大,非常大,所以你必须先把irp直接传递下去,或者作短暂处理,不要做线程切换这样负担极大的处理,否则我就蓝给你看,等系统驱动处理完成,你要真的想要等待一下,好,我微软可以容忍,你只能在你自己的进程里面等,随你等多久,只要不甘我事就行,所以,你在完成回调函数里面想等多久等多久,压力分摊给各个进程,之后就美其名曰的掏出一堆的中断级别,什么dispatch或者是passlevel,看吧,我微软够专业吧?我**个肥佬~~~~~~)
代码重点如下:
1.变量声明
#define kprintf DbgPrint
//每个设备所独有的空间扩展
typedef struct _DEVICE_EXTENSION
{
ULONG StateVariable;
PDEVICE_OBJECT OrgNetDevice;//原始设备指针
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
#define DEVICE_EXT(a) (PDEVICE_EXTENSION)a->DeviceExtension//获取扩展的宏
extern PDEVICE_OBJECT TcpFilterDevice;//过滤层设备指针,针对工程的全局对象
extern PDEVICE_OBJECT UdpFilterDevice;
extern PDEVICE_OBJECT RawIpFilterDevice;
enum PROTOL_TYPES//协议类型
{
TCP_TYPE,//tcp类型
UDP_TYPE,
RAW_IP,
};
2.DriverEntry里面产生设备
//产生tcp过滤器
ntStatus=CreateATdiDevice(DriverObject,TCP_FILTER_DEVICE_NAME,&TcpFilterDevice);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
//产生udp过滤器
ntStatus=CreateATdiDevice(DriverObject,UDP_FILTER_DEVICE_NAME,&UdpFilterDevice);
if(!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(TcpFilterDevice);
return ntStatus;
}
//产生原始ip过滤器
ntStatus=CreateATdiDevice(DriverObject,RAWIP_FILTER_DEVICE_NAME,&RawIpFilterDevice);
if(!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(TcpFilterDevice);
IoDeleteDevice(RawIpFilterDevice);
return ntStatus;
}
其中CreateATdiDevice函数如下:
/*********************************************************************
函数作用:产生以及tdi设备
参数:基础驱动,设备驱动
返回值:状态返回
**********************************************************************/
NTSTATUS CreateATdiDevice(
IN PDRIVER_OBJECT pDriver,//驱动指针
IN PWCHAR pDeviceName,//设备名称
OUT PDEVICE_OBJECT *pDevice//设备指针(返回)
)
{
NTSTATUS ntStatus;
UNICODE_STRING ntDeviceName,dosDeviceName;
PDEVICE_EXTENSION DeviceExtension;
RtlInitUnicodeString(&ntDeviceName, pDeviceName);
ntStatus = IoCreateDevice(
pDriver,
sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
0,// DeviceCharacteristics
TRUE,// Exclusive
pDevice// [OUT]
);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("[CreateATdiDevice]IoCreateDevice=0x%x\n", ntStatus);
return ntStatus;
}
(*pDevice)->Flags|=DO_DIRECT_IO;//直接io缓冲类型
return ntStatus;
}
3.DriverEntry里面Attach驱动
PDEVICE_EXTENSION pExt=DEVICE_EXT(TcpFilterDevice);
//绑定tcp
ntStatus=AttachDevice(NT_TCP_DEVICE_NAME,TcpFilterDevice,
&pExt->OrgNetDevice);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
DbgPrint("[DriverEntry]tcp org net device %08x\r\n",pExt->OrgNetDevice);
pExt=DEVICE_EXT(UdpFilterDevice);
//绑定udp
ntStatus=AttachDevice(NT_UDP_DEVICE_NAME,UdpFilterDevice,
&pExt->OrgNetDevice);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
DbgPrint("[DriverEntry]udp org net device %08x\r\n",pExt->OrgNetDevice);
pExt=DEVICE_EXT(RawIpFilterDevice);
//绑定rawip
ntStatus=AttachDevice(NT_RAWIP_DEVICE_NAME,RawIpFilterDevice,
&pExt->OrgNetDevice);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
DbgPrint("[DriverEntry]rawip org net device %08x\r\n",pExt->OrgNetDevice);
其中
#define TCP_FILTER_DEVICE_NAME L"\\Device\\TcpFilterTrans"
#define UDP_FILTER_DEVICE_NAME L"\\Device\\UdpFilterTrans"
#define RAWIP_FILTER_DEVICE_NAME L"\\Device\\RowIpFilterTrans"
#define NT_TCP_DEVICE_NAME L"\\Device\\Tcp"
#define NT_UDP_DEVICE_NAME L"\\Device\\Udp"
#define NT_RAWIP_DEVICE_NAME L"\\Device\\RawIp"
AttachDevice函数:
/*********************************************************************
函数作用:绑定指定设备
参数:需要绑定的设备名称,想帮到目标上的设备指针,绑定后获取到的老顶层设备指针
返回值:
**********************************************************************/
NTSTATUS AttachDevice(
IN PWCHAR pDeviceName,//需要绑定的设备名称
IN PDEVICE_OBJECT pAttachingDevice,//想帮到目标上的设备指针
OUT PDEVICE_OBJECT *oldDevice//绑定后获取到的老顶层设备指针
)
{
NTSTATUS ntStatus;
UNICODE_STRING AttachDeviceName;
RtlInitUnicodeString(&AttachDeviceName,pDeviceName);
ntStatus=IoAttachDevice(pAttachingDevice,&AttachDeviceName,oldDevice);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("[AttachDevice]IoAttachDevice=0x%x\n", ntStatus);
return ntStatus;
}
return ntStatus;
}
4.DriverEntry勾走所有的irp处理
for(int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
DriverObject->MajorFunction[i]=TditransDispatch;
DriverObject->DriverUnload=TditransUnload;
5.我们跳过所有的处理,只稍微判断下他们的类型
NTSTATUS TditransDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
switch ((unsigned int)WhichProtol(DeviceObject))
{
case PROTOL_TYPES::TCP_TYPE:
DbgPrint("[TditransDispatch]Tcp action\r\n");
break;
case PROTOL_TYPES::UDP_TYPE:
DbgPrint("[TditransDispatch]Udp action\r\n");
break;
case PROTOL_TYPES::RAW_IP:
DbgPrint("[TditransDispatch]Rawip action\r\n");
break;
}
PDEVICE_EXTENSION pExt=DEVICE_EXT(DeviceObject);
PDEVICE_OBJECT pOrgDev=pExt->OrgNetDevice;
DbgPrint("[TditransDispatch]org net device %08x\r\n",pExt->OrgNetDevice);
if(pOrgDev!=NULL)
{
IoSkipCurrentIrpStackLocation(Irp);
ntStatus=IoCallDriver(pOrgDev,Irp);
}
return ntStatus;
}
其中WhichProtol
/*********************************************************************
函数作用:判断协议属于类型
参数:被选中通讯的设备指针
返回值:协议类型
**********************************************************************/
int WhichProtol(PDEVICE_OBJECT pSelDevice)
{
if(TcpFilterDevice==pSelDevice)
return (int)PROTOL_TYPES::TCP_TYPE;
if(UdpFilterDevice==pSelDevice)
return (int)PROTOL_TYPES::UDP_TYPE;
if(RawIpFilterDevice==pSelDevice)
return (int)PROTOL_TYPES::RAW_IP;
return 0;
}
6.Unload里面啥也别做,否则系统蓝给你看!(这一点不要怀疑,所有通过attach+完成事例来做过滤的驱动最好都不要做这个卸载,否则后果很严重,微软会在卸载里面判断你这个驱动是不是符合wdm即插即用标准,如果但凡你不支持pnp和power管理标准,你就去蓝屏那里买单吧,我顶~~~)
//啥也不要做,做了会蓝屏
VOID TditransUnload(
IN PDRIVER_OBJECT DriverObject
)
{
DbgPrint("[TDITrans] unloaded\n");
}
总结:并非一个sys对应一个设备,也并非一个irp回调过程对一个sys只会给一个设备指针,这就是这个文章的技巧真谛,拥有它,你就想申请多少个设备申请多少个吧。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课