首页
社区
课程
招聘
[求助]tdi过滤驱动里自己分配一个irp,TdiBuildQueryInformation,蓝屏
发表于: 2010-4-12 23:11 7221

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

2010-4-12 23:11
7221
tdi过滤驱动里自己分配一个irp,TdiBuildQueryInformation,蓝屏
/*
    tdi防火墙 先关注TCP协议   采用过滤驱动
    Codz by Zero 2010-04-08
*/
/*
	typedef struct _NETWORK
	{
		PID                 224
		NAME                iexplore.exe
		PATH                C:\Program Files\Internet Explorer\iexplorer.exe
		LOCAL_IP			192.168.1.22
		LOCAL_PORT			1747
		REMOTE_IP			192.168.1.102
		REMOTE_PORT			8000
		TIME				2010-04-08-09-49-33
	}NETWORK,*PNETWORK;
*/
#ifndef _TDI
#define _TDI 1

#include <ntddk.h>

#endif
#include "mytdi.h"  
#include "filter.h" 
#include <tdikrnl.h>

PDEVICE_OBJECT tcpfltobj = NULL;
PDEVICE_OBJECT tcpoldobj = NULL;

typedef struct _COMPLETION 
{
	PIO_COMPLETION_ROUTINE	routine;
	PVOID					context;
}COMPLETION;

typedef struct
{
	TDI_ADDRESS_INFO	*tai;            //地址信息保存在这里面		
	PFILE_OBJECT		fileobj;	     //irps保存的文件对象
} TDI_CREATE_ADDROBJ2_CTX;

NTKERNELAPI
UCHAR *
PsGetProcessImageFileName(
						  PEPROCESS Process);
//===========================================
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObject, PUNICODE_STRING pRegString);
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObject, PIRP pIrp);
NTSTATUS DispatchRoutine(PDEVICE_OBJECT pDevObject, PIRP pIrp);
VOID DriverUnload(PDRIVER_OBJECT pDrvObject);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObject, PIRP pIrp);
VOID GetCurrentProcess(PULONG pid, PCHAR name, PCHAR path);
VOID Get_Process(PIRP irp, COMPLETION *completion);
NTSTATUS Pass_Irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
NTSTATUS Get_Address(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);


//==========================================
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObject, PUNICODE_STRING pRegString)
{
	NTSTATUS status = STATUS_SUCCESS;
	UNICODE_STRING ustrLinkName;
	UNICODE_STRING ustrDevName;    
	PDEVICE_OBJECT pDevObject;
	int i;
	KdPrint(("[tdi] DriverEntry: %S\n",pRegString->Buffer));
	//设置28个分发例程
	for(i=0;i<28;i++)
	{
		pDrvObject->MajorFunction[i]=DispatchRoutine;
	}
	pDrvObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
	pDrvObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
	pDrvObject->DriverUnload = DriverUnload;

	//创建设备绑定Tcp
	status = Filter_AttachDevice(pDrvObject,&tcpfltobj,&tcpoldobj,L"\\Device\\Tcp");
	if(!NT_SUCCESS(status))
	{
		return status;
	}
	//创建符号链接
	RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
	
	status = IoCreateDevice(pDrvObject, 
		0,
		&ustrDevName, 
		FILE_DEVICE_UNKNOWN,
		0,
		FALSE,
		&pDevObject);
	
	KdPrint(("[sae] Device Name %S",ustrDevName.Buffer));
	
	if(!NT_SUCCESS(status))
	{
		KdPrint(("[sae] IoCreateDevice = 0x%x\n", status));
		return status;
	}
	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
	
	status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
	if(!NT_SUCCESS(status))
	{
		KdPrint(("[tdi] IoCreateSymbolicLink = 0x%x\n", status));
		IoDeleteDevice(pDevObject);  
		return status;
	}
	
	KdPrint(("[tdi] SymbolicLink:%S",ustrLinkName.Buffer));
	return STATUS_SUCCESS;
}


VOID DriverUnload(PDRIVER_OBJECT pDrvObject)
{	
	UNICODE_STRING strLink;
	RtlInitUnicodeString(&strLink, LINK_NAME);
	IoDeleteSymbolicLink(&strLink);
	IoDeleteDevice(pDrvObject->DeviceObject);
	//对已生成和绑定的设备进行解绑和删除
	if(tcpfltobj!=NULL)
	{
		IoDeleteDevice(tcpfltobj);
	}
	if(tcpoldobj!=NULL)
	{
		IoDetachDevice(tcpoldobj);
	}
	KdPrint(("[tdi] Unloaded\n"));
}

NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObject, PIRP pIrp)
{
	
	if(pDevObject == tcpfltobj)
	{
		PFILE_FULL_EA_INFORMATION ea;
		COMPLETION completion;
		memset(&completion, 0, sizeof(COMPLETION));
		ea = (PFILE_FULL_EA_INFORMATION)pIrp->AssociatedIrp.SystemBuffer;
		if(ea != NULL)
		{
			if(	ea->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH&&
				memcmp(ea->EaName,TdiTransportAddress,TDI_TRANSPORT_ADDRESS_LENGTH)==0)
			{
				//这里解析得到本地IP和端口
				KdPrint(("Get Local\n"));
				//得到进程 本地IP 端口
				IoCopyCurrentIrpStackLocationToNext(pIrp);
				Get_Process(pIrp,&completion);
				IoCallDriver( tcpoldobj, pIrp ); 
				return STATUS_PENDING;
			}
			else if(ea->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH&&
				    memcmp(ea->EaName,TdiConnectionContext,TDI_CONNECTION_CONTEXT_LENGTH) == 0)
			{
				//这里解析远程IP 和端口
				KdPrint(("Get Remote\n"));
				IoSkipCurrentIrpStackLocation (pIrp);
				return IoCallDriver( tcpoldobj, pIrp );
			}
		}
		IoSkipCurrentIrpStackLocation (pIrp);
		return IoCallDriver( tcpoldobj, pIrp ); 
	}
	return STATUS_SUCCESS;
}

NTSTATUS DispatchRoutine(PDEVICE_OBJECT pDevObject, PIRP pIrp)
{
	//下发IRP
	if(pDevObject == tcpfltobj)
	{
		IoSkipCurrentIrpStackLocation (pIrp);
		return IoCallDriver( tcpoldobj, pIrp ); 
	}
	return STATUS_SUCCESS;	
}

NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObject, PIRP pIrp)
{
	PIO_STACK_LOCATION pIrpStack;
	ULONG uIoControlCode;
	PVOID pIoBuffer;
	ULONG uInSize;
	ULONG uOutSize;
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

	if(pDevObject == tcpfltobj)
	{
		IoSkipCurrentIrpStackLocation (pIrp);
		return IoCallDriver( tcpoldobj, pIrp );
	}
	
	

	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	switch(uIoControlCode)
	{
	case IOCTL_HELLO:
		{
			KdPrint(("[tdi] Hello,I have benn called.."));
			status = STATUS_SUCCESS;
		}
		break;
	}

	if(status == STATUS_SUCCESS)
		pIrp->IoStatus.Information = uOutSize;
	else
		pIrp->IoStatus.Information = 0;

	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return status;
}


//依据EPROCESS得到进程全路径
VOID GetFullPathByEprocess( ULONG eprocess,PCHAR ProcessImageName )
{
	//原理Eprocess->sectionobject(0x138)->Segment(0x014)->ControlAera(0x000)->FilePointer(0x024)->(FileObject->FileName,FileObject->DeviceObject)
	ULONG object;
	PFILE_OBJECT FileObject;
	UNICODE_STRING FilePath; 
	UNICODE_STRING DosName; 
	STRING AnsiString; 
	
	FileObject = NULL; 
	FilePath.Buffer = NULL; 
	FilePath.Length = 0; 
	*ProcessImageName = 0;  
	
	if(MmIsAddressValid((PULONG)(eprocess+0x138)))//Eprocess->sectionobject(0x138)
	{
		object=(*(PULONG)(eprocess+0x138));
        //KdPrint(("[GetProcessFileName] sectionobject :0x%x\n",object));
		if(MmIsAddressValid((PULONG)((ULONG)object+0x014)))
		{
			object=*(PULONG)((ULONG)object+0x014);
			//KdPrint(("[GetProcessFileName] Segment :0x%x\n",object));
			if(MmIsAddressValid((PULONG)((ULONG)object+0x0)))
			{
				object=*(PULONG)((ULONG_PTR)object+0x0);
				//KdPrint(("[GetProcessFileName] ControlAera :0x%x\n",object));
				if(MmIsAddressValid((PULONG)((ULONG)object+0x024)))
				{
					object=*(PULONG)((ULONG)object+0x024);
					//KdPrint(("[GetProcessFileName] FilePointer :0x%x\n",object));
				}
				else
					return ;
			}
			else
				return ;
		}
		else
			return ;
	}
	else
		return ;
    FileObject=(PFILE_OBJECT)object;
	
	FilePath.Buffer = ExAllocatePool(PagedPool,0x200);
	FilePath.MaximumLength = 0x200; 
    //KdPrint(("[GetProcessFileName] FilePointer :%wZ\n",&FilePointer->FileName));
	ObReferenceObjectByPointer((PVOID)FileObject,0,NULL,KernelMode);//引用计数+1,操作对象
	
	RtlVolumeDeviceToDosName(FileObject-> DeviceObject, &DosName); 
	RtlCopyUnicodeString(&FilePath, &DosName); 
	RtlAppendUnicodeStringToString(&FilePath, &FileObject->FileName); 
	ObDereferenceObject(FileObject); 
	
	RtlUnicodeStringToAnsiString(&AnsiString, &FilePath, TRUE); 
	if ( AnsiString.Length >= 216 ) 
	{ 
		memcpy(ProcessImageName, AnsiString.Buffer, 0x100u); 
		*(ProcessImageName + 215) = 0; 
	} 
	else 
	{ 
		memcpy(ProcessImageName, AnsiString.Buffer, AnsiString.Length); 
		ProcessImageName[AnsiString.Length] = 0; 
	} 
	RtlFreeAnsiString(&AnsiString); 
	ExFreePool(DosName.Buffer); 
	ExFreePool(FilePath.Buffer); 
}
//
VOID GetCurrentProcess(PULONG pid, PCHAR name, PCHAR path)
{
	PEPROCESS Cprocess;
	Cprocess = PsGetCurrentProcess();
	*pid = *(PULONG)((ULONG)Cprocess+0x84);
	strcpy(name ,PsGetProcessImageFileName(Cprocess));
	GetFullPathByEprocess((ULONG)Cprocess,path);
}
//
VOID Get_Process(PIRP irp,COMPLETION* completion)
{
	/*进程信息*/
	ULONG pid;
	CHAR name[126]={0};
	CHAR path[256]={0};
	/*获取地址*/
	/*创建查询IRP*/
	PIRP query_irp;
	GetCurrentProcess(&pid, name, path);
	query_irp = TdiBuildInternalDeviceControlIrp(	TDI_QUERY_INFORMATION,
													tcpoldobj, 
													irps->FileObject, 
													NULL, 
													NULL);
	if (query_irp == NULL) 
	{
		KdPrint(("[tdi_fw] tdi_create: TdiBuildInternalDeviceControlIrp\n"));
		return ;
	}
	/*设置completion*/
	completion->routine = Pass_Irp;      //生成请求的完成函数
	completion->context = query_irp;
	/*设置回调例程*/
	IoSetCompletionRoutine(irp,completion->routine,completion->context, TRUE, TRUE, TRUE);
	/*打印信息*/
	KdPrint(("pid:%d\n",pid));
	KdPrint(("name:%s\n",name));
	KdPrint(("path:%s\n",path));

}
//回调例程Query_Irp
NTSTATUS Pass_Irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
	NTSTATUS status;
	/*发送query_irp*/
	PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(Irp);
	/*Context参数是我们申请的query_irp*/
	PIRP query_irp = (PIRP)Context;
	/*填充query_irp*/
	TDI_ADDRESS_INFO *ctx = NULL;
	PMDL mdl = NULL;

	if(Irp->PendingReturned)
	{
		IoMarkIrpPending(Irp);
	}

	KdPrint(("Enter Pass_Irp\n"));

	ctx = (TDI_ADDRESS_INFO *)ExAllocatePool(NonPagedPool,sizeof(TDI_ADDRESS_INFO));
	if(ctx == NULL)
	{
		KdPrint(("malloc error\n"));
		return STATUS_SUCCESS;
	}
	mdl = IoAllocateMdl(ctx,sizeof(TDI_ADDRESS_INFO),FALSE,FALSE,NULL);
	if(mdl == NULL)
	{
		KdPrint(("malloc error\n"));
		return STATUS_SUCCESS;
	}
	MmBuildMdlForNonPagedPool(mdl);
	//设置query_irp
	TdiBuildQueryInformation(query_irp,
							tcpoldobj,
							irps->FileObject,
							Get_Address,
							Context,
							TDI_QUERY_ADDRESS_INFO,
							mdl);
	status = IoCallDriver(tcpfltobj,query_irp);
	status = STATUS_SUCCESS;
	return status;
}                                                                                                                                                                                                   
NTSTATUS Get_Address(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
	if(Irp->MdlAddress)
	{
		TDI_ADDRESS_INFO *ctx = (TDI_ADDRESS_INFO *)MmGetSystemAddressForMdl(Irp->MdlAddress);
		TA_ADDRESS *addr = ctx->Address.Address;
		KdPrint(("Enter Get_Address\n"));
		KdPrint(("[tdi_fw] tdi_create_addrobj_complete2: address: %u\n", 
		 ((TDI_ADDRESS_IP *)(addr->Address))->sin_port));

	}
	return STATUS_SUCCESS;
}


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

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
自己先顶一下
2010-4-13 11:48
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
帮你顶一下...
2010-4-13 12:28
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
为什么会蓝屏,我也遇到了这个问题
2018-3-15 16:56
0
游客
登录 | 注册 方可回帖
返回
//