首页
社区
课程
招聘
[原创]nt到win7的防火墙研究之TDI
发表于: 2009-12-23 18:11 15313

[原创]nt到win7的防火墙研究之TDI

2009-12-23 18:11
15313

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只会给一个设备指针,这就是这个文章的技巧真谛,拥有它,你就想申请多少个设备申请多少个吧。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 324
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好文!学习了!顶一个
2009-12-23 19:14
0
雪    币: 8156
活跃值: (2756)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
就第一段话特别个性..骂微软的词语用的不错..
2009-12-23 19:21
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我不太明白,据说win7是vista的内核,为什么vista支持tdi而win7不支持?上面哪一步过不去?如果Attach设备不行的话,那以前n多靠attach吃饭的驱动都不能跑了。
2009-12-23 20:41
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
5
其实微软不是封杀tdi,而是因为有了更加简单的方法,有了更简单的架构
2009-12-23 23:52
0
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
咦~?那是什么构架,我还没有查阅到,鹿剑先生请赐教,交流的威力果然是大的。
2009-12-24 08:53
0
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
muroachanf先生,可能我文章没有说清楚,win7没有封attach这个,只是把/device/tcp这样类似的驱动irp接口变化了,所以tdi不能继续使用了。
2009-12-24 08:57
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
8
1、需要完成历程是因为在派遣历程中,需要获取的信息还不存在,必须把IRP发下去让底层设备填充,然后等IRP回卷上来再截获。
2、卸载例程里容易蓝是因为当时可能存在还没有回卷的IRP,这些IRP回卷到你的设备后,发现当初注册的完成历程已经没有了,甚至连设备都被删除了,当然就蓝了。处理好一点就没事了。
3、骂微软骂得很过瘾,爽
2009-12-24 09:46
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
9
其实微软以前就说过到了win7就彻底不支持tdi了,而取代这种tdi的实际上是一个称为Windows过滤平台的新技术(Windows Filtering Platform)(其实这个在寒江独钓里面也提到了)。在wdk7600里面就再带了几个例子,具体可参阅在线文档:

http://www.microsoft.com/whdc/device/network/wfp.mspx
2009-12-24 12:35
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
10
我给个讲NPI的链接:http://rootkit.com/newsread.php?newsid=952
2009-12-24 12:58
0
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
都是牛人,wfp和rootkit正所谓一正一邪,rootkit明显邪门的多,不过很爽。
2009-12-30 16:06
0
游客
登录 | 注册 方可回帖
返回
//