baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
阅读:5182回复:17

tdi过滤驱动里自己分配一个irp,TdiBuildQueryInformation,蓝屏

楼主#
更多 发布于:2005-08-01 10:39
  晕阿,大家帮忙看下问题出在哪里,谢谢!

NTSTATUS completegettcpportbyfile(IN PDEVICE_OBJECT DeviceObject,IN PIRP irp,IN PVOID context){
       __asm int 3;
       if(irp->PendingReturned){
              IoMarkIrpPending(irp);
       }
       return STATUS_MORE_PROCESSING_REQUIRED;//自己分配的irp必须返回这个!
}

int gettcpportbyfile(PFILE_OBJECT file){//return -1 error,0 not tcp,other port number
       PIRP newirp;
       void* pooladdr;
       PMDL pmdl;
       int stat;
       int tmp;
       __asm int 3;
       newirp=IoAllocateIrp(plowerdev->StackSize,0);//分配新的irp
       pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池
       pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl
       if(pmdl==0){
#ifdef bydbg
              DbgPrint("bytdiflt.sys:cannot alloc MDL at gettcpportbyfile.\n");
              DbgBreakPoint();
#endif
              ExFreePool(pooladdr);
              IoFreeIrp(newirp);
              return -1;
       }
       ///
       TdiBuildQueryInformation(newirp,plowerdev,file,completegettcpportbyfile,
              0,TDI_QUERY_ADDRESS_INFO,pmdl);
       stat=IoCallDriver(plowerdev,newirp);
       if(NT_SUCCESS(stat)){
              if(((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].AddressType==TDI_ADDRESS_TYPE_IP)
              {stat=((TDI_ADDRESS_IP*)(&
                     ((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].Address[0]))
                     ->sin_port;
              //my_ntohs
              tmp=(UCHAR)stat;
              stat>>=8;
              stat|=(tmp<<8);
              }
              else
              {stat=0;}
       }
       else
       {stat=-1;}
       ///
       //IoCompleteRequest(newirp, IO_NO_INCREMENT);自己创建的不需要了
       IoFreeIrp(newirp);
       IoFreeMdl(pmdl);
       ExFreePool(pooladdr);
       return stat;
}
各类后门,木马,Exp,0day
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-08-01 10:43
stat=IoCallDriver(plowerdev,newirp);这句调用发出以后返回以前,完成例程被调用以前,发生的在tdi.sys中的page_error_in_nonpaged_area的bugcheck
各类后门,木马,Exp,0day
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2005-08-01 14:57
如果IoCallDriver返回pending,不蓝才怪
好像对完成例程的作用并不太清楚?
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-08-01 15:00
对stat == STATUS_PENDING没做处理
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-08-01 15:28
IoCallDriver函数根本就没有返回,是返回前就死了的,应该和stat == STATUS_PENDING没有什么关系吧?可能我上面没有叙述清楚
各类后门,木马,Exp,0day
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-08-01 16:39
TdiBuildQueryInformation前增加
KeInitializeEvent(&Event, NotificationEvent, TRUE);
KeClearEvent(&Event);
irp->UserEvent = &Event;
irp->UserIosb = &IoStatus;

在status = IoCallDriver(deviceObject, irp);后增加
if (status == STATUS_PENDING)
{
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            status = IoStatus.Status;
}
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-08-01 16:40
还有Complete中增加
if (Irp->UserEvent)
    {
        KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
    }
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-08-02 00:11
MmBuildMdlForNonPagedPool(pmdl);
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-08-02 10:09
tdi query_information这个irp不会返回pending,所以同步不是主要问题,这两天我发现主要存在2个问题:
一是我原来用的IoAllocateIrp后面跟着TdiBuildQueryInformation,ddk说应该用TdiBuildInternalDeviceControlIrp,就先改成它试试看;
二是原来没有MmBuildMdlForNonPagedPool,只是IoAllocateMdl,肯定不行,加上它

现在发现IoCallDriver里查询时还好,但是运行到系统自带的完成例程时崩溃,PFN_LIST_CORRUPT,(TdiBuildInternalDeviceControlIrp不用自己设置完成例程),大家帮忙看看呀,我都要崩溃了。


int gettcpportbyfile(PFILE_OBJECT file){//return -1 error,0 not tcp,other port number
       PIRP newirp;
       void* pooladdr;
       PMDL pmdl;
       int stat;
       int tmp;
       IO_STATUS_BLOCK iosb;
       KEVENT event;
       ///
       __asm int 3;
       if(KeGetCurrentIrql()>PASSIVE_LEVEL){return -1;}
       KeInitializeEvent(&event,NotificationEvent,0);
       newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb);
       pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池
       pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl
       MmBuildMdlForNonPagedPool(pmdl);//这个不能没有
       if(pmdl==0){
#ifdef bydbg
              DbgPrint("bytdiflt.sys:cannot alloc MDL at gettcpportbyfile.\n");
              DbgBreakPoint();
#endif
              ExFreePool(pooladdr);
              IoFreeIrp(newirp);
              return -1;
       }
       ///
       TdiBuildQueryInformation(newirp,plowerdev,file,0,
              0,TDI_QUERY_ADDRESS_INFO,pmdl);//不提供完成例程,按照TdiBuildInternalDeviceControlIrp的事件自动完成
       stat=IoCallDriver(plowerdev,newirp);
       if(stat==STATUS_PENDING){
              KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
              stat=iosb.Status;
       }//同步irp完成
       if(NT_SUCCESS(stat)){
              if(((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].AddressType==TDI_ADDRESS_TYPE_IP)
              {stat=((TDI_ADDRESS_IP*)(&
                     ((TDI_ADDRESS_INFO*)pooladdr)->Address.Address[0].Address[0]))
                     ->sin_port;
              //my_ntohs
              tmp=(UCHAR)stat;
              stat>>=8;
              stat|=(tmp<<8);
              }
              else
              {stat=0;
#ifdef bydbg
              DbgPrint("bytdiflt:non-tcp file called tcp's irp.\n");
              DbgBreakPoint();
#endif
              }
       }
       else
       {stat=-1;}
       ///
       //IoCompleteRequest(newirp, IO_NO_INCREMENT);//自己创建的不需要了,否则蓝屏
       IoFreeIrp(newirp);
       IoFreeMdl(pmdl);
       ExFreePool(pooladdr);
       return stat;
}
各类后门,木马,Exp,0day
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-08-02 10:45
我给你一段好了!!
NTSTATUS
AllocateMdlAndIrp(IN PVOID BufVAddress, IN ULONG BufLength, IN UCHAR StackSize, IN BOOLEAN IsNonPage, PIRP* Irp, PMDL* Mdl)
{
       PMDL TempMdl = IoAllocateMdl(BufVAddress, BufLength, FALSE, FALSE, NULL);
       if(TempMdl)
       {
              __try
              {
                     if(IsNonPage)
                     {
                            MmBuildMdlForNonPagedPool(TempMdl);
                     }
                     else
                     {
                            MmProbeAndLockPages(TempMdl, KernelMode, IoModifyAccess); // __try
                     }

                     PIRP TempIrp = IoAllocateIrp(StackSize, FALSE);
                     if(TempIrp)
                     {
                            *Mdl = TempMdl; *Irp = TempIrp;
                            return STATUS_SUCCESS;
                     }
              }
              __except(EXCEPTION_EXECUTE_HANDLER){}
              IoFreeMdl(TempMdl);
       }

       *Mdl = NULL; *Irp = NULL;
       return STATUS_INSUFFICIENT_RESOURCES;
}

VOID
FreeMdlAndIrp(IN PIRP Irp, IN PMDL Mdl, IN BOOLEAN IsNonPage)
{
       PMDL PrevMdl, NextMdl;

       if(Irp)
       {
              PrevMdl = Irp->MdlAddress;
              while(PrevMdl)
              {
                     NextMdl = PrevMdl->Next;
                     if(PrevMdl == Mdl)
                     {
                            Mdl = NULL;
                     }
                     if(!IsNonPage) //if(PrevMdl->MdlFlags |= MDL_PAGES_LOCKED)
                     {
                            MmUnlockPages(PrevMdl);
                     }
                     IoFreeMdl(PrevMdl);
                     PrevMdl = NextMdl;
              }

              IoFreeIrp(Irp);
       }

       PrevMdl = Mdl;
       while(PrevMdl)
       {
              NextMdl = PrevMdl->Next;
              if(!IsNonPage) //if(PrevMdl->MdlFlags |= MDL_PAGES_LOCKED)
              {
                     MmUnlockPages(PrevMdl);
              }
              IoFreeMdl(PrevMdl);
              PrevMdl = NextMdl;
       }
       return;
}

//////////////////////////////////////////////////////////////////////////
NTSTATUS
iSpTdiCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
       UNREFERENCED_PARAMETER(DeviceObject);
       UNREFERENCED_PARAMETER(Context);
       Irp->UserIosb->Information = Irp->IoStatus.Information;
       Irp->UserIosb->Status      = Irp->IoStatus.Status;
       KeSetEvent(Irp->UserEvent, IO_NETWORK_INCREMENT, FALSE);
       return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
iSpTdiSendIrpSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG WaitTime)
{
       IO_STATUS_BLOCK Iosb;
       KEVENT WaitEvent;
       NTSTATUS NtStatus;

       KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);
       Irp->UserEvent = &WaitEvent;
       Irp->UserIosb  = &Iosb;
       NtStatus = IoCallDriver(DeviceObject, Irp);
       if(NtStatus == STATUS_PENDING)
       {
              LARGE_INTEGER OutTime;
              OutTime.QuadPart = WaitTime*(-10000000);
              KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, WaitTime==0?NULL:&OutTime);
              if(NtStatus != STATUS_TIMEOUT)
              {
                     NtStatus = Iosb.Status;
              }
              else
              {
                     IoCancelIrp(Irp);
                     KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL);
                     NtStatus = STATUS_CANCELLED;
              }
       }
       return NtStatus;
}

NTSTATUS
iSpTdiQueryInformation(IN PDEVICE_OBJECT PDOTransport, IN PFILE_OBJECT PFOTransport, IN ULONG InfoType, IN ULONG InfoLength, OUT PVOID InfoBuffer)
{
       PIRP Irp; PMDL Mdl;
       NTSTATUS NtStatus = AllocateMdlAndIrp(InfoBuffer, InfoLength, PDOTransport->StackSize, TRUE, &Irp, &Mdl);
       if(NT_SUCCESS(NtStatus))
       {
              TdiBuildQueryInformation(Irp, PDOTransport, PFOTransport, iSpTdiCompletionRoutine, NULL, InfoType, Mdl);
              NtStatus = iSpTdiSendIrpSynchronous(PDOTransport, Irp, 0);
              FreeMdlAndIrp(Irp, Mdl, TRUE);
       }
       return NtStatus;
}
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-08-02 21:19
ldljlzw兄的代码是可以成功的,谢谢你了!不过我还是想知道

     KeInitializeEvent(&event,NotificationEvent,0);
     newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb);
     pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池
     pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl
     MmBuildMdlForNonPagedPool(pmdl);//这个不能没有
     TdiBuildQueryInformation(newirp,plowerdev,file,0,
           0,TDI_QUERY_ADDRESS_INFO,pmdl);//不提供完成例程,按照TdiBuildInternalDeviceControlIrp的事件自动完成
     stat=IoCallDriver(plowerdev,newirp);
     if(stat==STATUS_PENDING){
           KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
           stat=iosb.Status;
     }//同步irp完成

这种使用TdiBuildInternalDeviceControlIrp()的方法错在哪里了,会产生PFN_LIST_CORRUPT的bugcheck?ddk可是说应该用这个的啊,而不是ldljlzw兄使用的IoAllocateIrp,那位老大能解释一下呢?谢谢
各类后门,木马,Exp,0day
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-08-03 00:09
下面是引用baiyuanfan于2005-08-02 21:19发表的:
ldljlzw兄的代码是可以成功的,谢谢你了!不过我还是想知道

     KeInitializeEvent(&event,NotificationEvent,0);
     newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb);
     pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池
.......


KeInitializeEvent(&event,NotificationEvent,0);
改为:
KeInitializeEvent(&event,SynchronizationEvent,FALSE);

还有
KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
可以改为
KeWaitForSingleObject(&event, Executive,KernelMode,TRUE,NULL); 试试
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-08-03 06:17
跟KeInitializeEvent和KeWaitForSingleObject没有关系,在系统的IoCompleteRequest的执行过程中产生PFN_LIST_CORRUPT的bugcheck,IoCallDriver还没有返回
各类后门,木马,Exp,0day
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-08-03 09:20
但是这个看来没有什么问题,NT 源代码里都是这样用的!!!
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-08-03 09:22
这是从NT源代码中取来的:
//
// Create an event for the synchronous I/O requests that we'll be issuing.
//
KeInitializeEvent (&Event, SynchronizationEvent, FALSE);
Irp = TdiBuildInternalDeviceControlIrp (TDI_ASSOCIATE_ADDRESS, DeviceObject, ConnectionObject, &Event, &Iosb);
TdiBuildAssociateAddress (Irp, DeviceObject, ConnectionObject, NULL, NULL, AddressHandle);
Status = IoCallDriver(DeviceObject, Irp);
if(Status == STATUS_PENDING)
{
       KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL);
}
Status = Irp->IoStatus.Status;
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2005-08-03 09:29
只一个问题你是否注意了!就是TDI_QUERY_ADDRESS_INFO要用TDI的Transport设备对象和文件对象,还不是Connection设备对象和文件对象,这是有区别的!
baiyuanfan
驱动小牛
驱动小牛
  • 注册日期2004-11-23
  • 最后登录2007-06-21
  • 粉丝0
  • 关注0
  • 积分320分
  • 威望38点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-08-04 22:22
更郁闷的是换成用IoAllocateIrp的方式,
       KeInitializeEvent(&event,SynchronizationEvent,0);
       pooladdr=ExAllocatePool(NonPagedPool,4096);
       pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);
       MmBuildMdlForNonPagedPool(pmdl);
       newirp=IoAllocateIrp(plowerdev->StackSize,0);
       TdiBuildQueryInformation(newirp,plowerdev,file,completegettcpportbyfile,
              0,TDI_QUERY_ADDRESS_INFO,pmdl);
       newirp->UserEvent = &event;
       newirp->UserIosb = &iosb;

       ///
       stat=IoCallDriver(plowerdev,newirp);
       if(stat==STATUS_PENDING){
              KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
              stat=iosb.Status;
       }//同步irp完成
就能成功,但是
       if(KeGetCurrentIrql()>PASSIVE_LEVEL){return -1;}
       KeInitializeEvent(&event,SynchronizationEvent,0);
       newirp=TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,plowerdev,file,&event,&iosb);
       pooladdr=ExAllocatePool(NonPagedPool,4096);//内存池
       pmdl=IoAllocateMdl(pooladdr,4096,0,0,0);//内存池对应的mdl
       MmBuildMdlForNonPagedPool(pmdl);//这个不能没有
       TdiBuildQueryInformation(newirp,plowerdev,file,0,
              0,TDI_QUERY_ADDRESS_INFO,pmdl);
       stat=IoCallDriver(plowerdev,newirp);
       if(stat==STATUS_PENDING){
              KeWaitForSingleObject(&event, Executive,KernelMode,0,0);
              stat=iosb.Status;
       }//同步irp完成
就会发生pfn_list_corrupt,我实在看不出来这两个有什么区别??
各类后门,木马,Exp,0day
sysdog
驱动牛犊
驱动牛犊
  • 注册日期2009-04-02
  • 最后登录2010-11-10
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望61点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2010-04-12 23:10
我顶起啊 什么问题呢?
搞技术的,命很苦
游客

返回顶部