首页
社区
课程
招聘
[求助]《寒江独钓》中网络传输层过滤获取地址出现蓝屏!
发表于: 2010-1-7 14:01 7916

[求助]《寒江独钓》中网络传输层过滤获取地址出现蓝屏!

2010-1-7 14:01
7916
《寒江独钓-WINDOWS内核安全编程》中 10.3 小节,描述了获取生成地址的办法:
1、绑定相应的NDIS协议驱动对象
    "\Device\Tcp"
      "\Device\Udp"
      "\Device\RawIp"
2、过滤IRP_MJ_CREATE请求
    2.1 判断irp->AssociatedIrp.SystemBuffer->EaName是否为TdiTransportAddress;
      2.2 下发该请求,并在完成函数(这里为:IoCompletionCreate)中查询传输地址的信息。
    2.3 在查询传输地址的完成例程中,打印信息。
3、相应的代码如下:
//tdifilter.c
#include <ntddk.h>
#include <tdi.h>
#include <TdiKrnl.h>

#define TDI_TCP_DEVICE		L"\\Device\\Tcp"
#define	TDI_UDP_DEVICE		L"\\Device\\Udp"
#define TDI_RAWIP_DEVICE	L"\\Device\\RawIp"

typedef struct _DEVICE_EXTENSION
{
	PDEVICE_OBJECT DeviceObject;
	UNICODE_STRING LowerDeviceName;
	PDEVICE_OBJECT LowerDeviceObject;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;

typedef struct _COMPLETION_CREATE_CONTEXT
{
	PIRP Irp;
	PMDL Mdl;
	PVOID Buffer;
	PRKEVENT Event;
}COMPLETION_CREATE_CONTEXT,*PCOMPLETION_CREATE_CONTEXT;

NTSTATUS
  IoCompletionQuery(
    IN PDEVICE_OBJECT  fdo,
    IN PIRP  Irp,
    IN PVOID  Context
    );

VOID DriverUnload(IN PDRIVER_OBJECT  DriverObject)
{
	PDEVICE_EXTENSION pdx = NULL;
	PDEVICE_OBJECT fdo = DriverObject->DeviceObject;
	
	while(fdo != NULL)
	{
		pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
		fdo = fdo->NextDevice;
		
		KdPrint(("tdifilter!DriverUnLoad:[%wZ] Detached.\n",&pdx->LowerDeviceName));
		IoDetachDevice(pdx->LowerDeviceObject);
		IoDeleteDevice(pdx->DeviceObject);				
	}
}

NTSTATUS 
  CreateAndAttachDevice(
	IN PDRIVER_OBJECT  DriverObject,
	IN PCWSTR DeviceName
	)
{
	NTSTATUS status;
	UNICODE_STRING devname;
	PDEVICE_OBJECT fdo;
	PDEVICE_EXTENSION pdx;
	
	RtlInitUnicodeString(&devname,DeviceName);
	
	status = IoCreateDevice(DriverObject,
				sizeof(DEVICE_EXTENSION),
				NULL,
				FILE_DEVICE_UNKNOWN,
				0,
				TRUE,
				&fdo);
	if(!NT_SUCCESS(status))
	{
		return status;
	}
	
	//设置设备IO为直接IO
	fdo->Flags |= DO_DIRECT_IO;
	
	pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	pdx->LowerDeviceName = devname;
	pdx->DeviceObject = fdo;
	
	status = IoAttachDevice(fdo,&devname,&pdx->LowerDeviceObject);
	if(!NT_SUCCESS(status))
	{
		IoDeleteDevice(fdo);
	}
	
	KdPrint(("tdifilter!CreateAndAttachDevice:[%wZ] Attached.\n",&pdx->LowerDeviceName));
	
	return status;
}

NTSTATUS DispatchAny(PDEVICE_OBJECT fdo, PIRP Irp)
{
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
  
  	IoSkipCurrentIrpStackLocation(Irp);
  	return IoCallDriver(pdx->LowerDeviceObject, Irp);
}

//IRP_MJ_CREATE的完成例程
NTSTATUS
  IoCompletionCreate(
    IN PDEVICE_OBJECT  fdo,
    IN PIRP  Irp,
    IN PVOID  Context
    )
{
	//KEVENT event;
	PCOMPLETION_CREATE_CONTEXT ctx = (PCOMPLETION_CREATE_CONTEXT)Context;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
	
	if(Irp->PendingReturned)
	{
		IoMarkIrpPending(Irp);
	}	
	KdPrint(("tdifilter!IoCompletionCreate\n"));
	
	//KeInitializeEvent(&event,NotificationEvent,FALSE);
	//ctx->Event = &event;
	
	TdiBuildQueryInformation(ctx->Irp,
		pdx->LowerDeviceObject,
		IrpSp->FileObject,
		IoCompletionQuery,
		ctx,
		TDI_QUERY_ADDRESS_INFO,
		ctx->Mdl
		);
	IoCallDriver(pdx->LowerDeviceObject,ctx->Irp);
	//KeWaitForSingleObject(ctx->Event,Executive,KernelMode,TRUE,TRUE,TRUE);
	
	return STATUS_SUCCESS;
}

//查询传输地址IRP的完成例程
NTSTATUS
  IoCompletionQuery(
    IN PDEVICE_OBJECT  fdo,
    IN PIRP  Irp,
    IN PVOID  Context
    )
{
	PTDI_ADDRESS_INFO tdiAddress;
	PTA_ADDRESS taAddress;
	PTDI_ADDRESS_IP ip;
	PCOMPLETION_CREATE_CONTEXT ctx = (PCOMPLETION_CREATE_CONTEXT)Context;
	
	if(Irp->PendingReturned)
	{
		IoMarkIrpPending(Irp);
	}
	
	KdPrint(("tdifilter!IoCompletionQuery: Start.\n"));	
	
	tdiAddress = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);	
	taAddress = tdiAddress->Address.Address;
	ip = (PTDI_ADDRESS_IP)(taAddress->Address);	
	KdPrint(("ip:%x,port:%u\n",ip->in_addr,ip->sin_port));
	
	KdPrint(("tdifilter!IoCompletionQuery: End.\n"));	
	
	//释放内存
	//IoFreeMdl(ctx->Mdl);
	//ExFreePoolWithTag(ctx->Buffer,0x12345678);
	
	KeSetEvent(ctx->Event,IO_NO_INCREMENT,FALSE);	
	return STATUS_SUCCESS;
}

NTSTATUS 
  TdiDispatchCreate(
    IN PDEVICE_OBJECT fdo,
    IN PIRP  Irp
    )
{
	//NTSTATUS status;
	KEVENT event;
	PIRP QueryIrp;
	PTDI_ADDRESS_INFO tdiAddress;
	PMDL MdlAddress;
	COMPLETION_CREATE_CONTEXT context;
	PUCHAR Ep = (PUCHAR)PsGetCurrentProcess();
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
	PFILE_FULL_EA_INFORMATION ea = (PFILE_FULL_EA_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
	
	KeInitializeEvent(&event,NotificationEvent,FALSE);	
	
	if((ea->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH)
		&&(memcmp(ea->EaName,TdiTransportAddress,TDI_TRANSPORT_ADDRESS_LENGTH) == 0))
	{
		//生成查询的IRP,给IRP_MJ_CREATE完成例程下发查询
		QueryIrp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,
					pdx->LowerDeviceObject,
					IrpSp->FileObject,
					NULL,NULL);
		if(QueryIrp == NULL)
		{
			return DispatchAny(fdo,Irp);
		}
		//分配内存
		tdiAddress = (PTDI_ADDRESS_INFO)ExAllocatePoolWithTag(NonPagedPool,
						sizeof(TDI_ADDRESS_INFO)*16,0x12345678);
		MdlAddress = IoAllocateMdl(tdiAddress,
						sizeof(TDI_ADDRESS_INFO)*16,
						FALSE,FALSE,NULL);
		MmBuildMdlForNonPagedPool(MdlAddress);
		
		context.Irp = QueryIrp;
		context.Mdl = MdlAddress;
		context.Buffer = tdiAddress;
		context.Event = &event;
		
		//在这里捕获传输层地址的生成
		KdPrint(("%s:pname[%s].\n",TdiTransportAddress,(Ep + 0x174)));
		IoCopyCurrentIrpStackLocationToNext(Irp);
		//设置IRP_MJ_CREATE完成例程
		IoSetCompletionRoutine(Irp,IoCompletionCreate,&context,TRUE,TRUE,TRUE);
		IoCallDriver(pdx->LowerDeviceObject,Irp);
		
		//等待查询完毕,释放内存
		KeWaitForSingleObject(context.Event,Executive,KernelMode,FALSE,NULL);
		
		//释放内存
		IoFreeMdl(context.Mdl);
		ExFreePoolWithTag(context.Buffer,0x12345678);
		return Irp->IoStatus.Status;	
	}
	else if((ea->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH)
		 &&(memcmp(ea->EaName,TdiConnectionContext,TDI_CONNECTION_CONTEXT_LENGTH) == 0))
	{
		KdPrint(("%s:pname[%s].\n",TdiConnectionContext,(Ep + 0x174)));
	}
	
	return DispatchAny(fdo,Irp);
}

NTSTATUS 
  DriverEntry( 
    IN PDRIVER_OBJECT  DriverObject, 
    IN PUNICODE_STRING  RegistryPath 
    )
{
	NTSTATUS status;
	ULONG i;
	
	DriverObject->DriverUnload = DriverUnload;
	for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i ++)
	{
		DriverObject->MajorFunction[i] = DispatchAny;
	}
	DriverObject->MajorFunction[IRP_MJ_CREATE] = TdiDispatchCreate;
	
	//绑定TCP协议
	status = CreateAndAttachDevice(DriverObject,
				TDI_TCP_DEVICE);
	if(!NT_SUCCESS(status))
	{
		DriverUnload(DriverObject);
		return status;
	}
	
	//绑定UDP协议
	status = CreateAndAttachDevice(DriverObject,
				TDI_UDP_DEVICE);
	if(!NT_SUCCESS(status))
	{
		DriverUnload(DriverObject);
		return status;
	}
	
	//绑定IP协议
	status = CreateAndAttachDevice(DriverObject,
				TDI_RAWIP_DEVICE);
	if(!NT_SUCCESS(status))
	{
		DriverUnload(DriverObject);
		return status;
	}
	
	return STATUS_SUCCESS;
}


4、加载并测试,
输入:telnet 127.0.0.1 时,蓝屏重启。

5、windbg得到的信息是这样的,看不懂.
PFN_LIST_CORRUPT (4e)
Typically caused by drivers passing bad memory descriptor lists (ie: calling
MmUnlockPages twice with the same list, etc).  If a kernel debugger is
available get the stack trace.
Arguments:
Arg1: 00000007, A driver has unlocked a page more times than it locked it
Arg2: 00002582, page frame number
Arg3: 00000001, current share count
Arg4: 00000000, 0

Debugging Details:
------------------

BUGCHECK_STR:  0x4E_7

DEFAULT_BUCKET_ID:  INTEL_CPU_MICROCODE_ZERO

PROCESS_NAME:  System

LAST_CONTROL_TRANSFER:  from 805334a7 to 804e4592

SYMBOL_ON_RAW_STACK:  1

STACK_ADDR_RAW_STACK_SYMBOL: fffffffff7d9f360

STACK_COMMAND:  dds F7D9F360-0x20 ; kb

STACK_TEXT:  
f7d9f340  00000286
f7d9f344  f7d9f624
f7d9f348  00000010
f7d9f34c  8054c2b9 nt!ExAllocatePoolWithTag+0x7af
f7d9f350  804e30d2 nt!InterlockedPopEntrySList
f7d9f354  82a03120
f7d9f358  828e2ba8
f7d9f35c  f7e6864a kdcom!CpReadLsr+0x8d
f7d9f360  000003fe
f7d9f364  00000000
f7d9f368  f7e68d20 kdcom!Port
f7d9f36c  00000000
f7d9f370  00000000
f7d9f374  00000000
f7d9f378  82add190
f7d9f37c  00000000
f7d9f380  00000000
f7d9f384  f76374bc
f7d9f388  00000000
f7d9f38c  00000001
f7d9f390  00000000
f7d9f394  00010010
f7d9f398  0000003b
f7d9f39c  0000000a
f7d9f3a0  00000000
f7d9f3a4  f76374cc
f7d9f3a8  0000bb40
f7d9f3ac  0000bb40
f7d9f3b0  0000bb40
f7d9f3b4  f7637134
f7d9f3b8  f7637718
f7d9f3bc  f7637718

FOLLOWUP_IP:
kdcom!CpReadLsr+8d
f7e6864a 88450f          mov     byte ptr [ebp+0Fh],al

SYMBOL_NAME:  kdcom!CpReadLsr+8d

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: kdcom

IMAGE_NAME:  kdcom.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d8346

FAILURE_BUCKET_ID:  0x4E_7_kdcom!CpReadLsr+8d

BUCKET_ID:  0x4E_7_kdcom!CpReadLsr+8d

6、问题:本人太菜,请大家帮帮忙,代码中哪里写错了?万分感谢!!

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

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
dump文件的内容是这样的:
kd> !analyze -v
*******************************************************************************
*                                                                            *
*                        Bugcheck Analysis                                    *
*                                                                            *
*******************************************************************************

PFN_LIST_CORRUPT (4e)
Typically caused by drivers passing bad memory descriptor lists (ie: calling
MmUnlockPages twice with the same list, etc).  If a kernel debugger is
available get the stack trace.
Arguments:
Arg1: 00000007, A driver has unlocked a page more times than it locked it
Arg2: 00002402, page frame number
Arg3: 00000001, current share count
Arg4: 00000000, 0

Debugging Details:
------------------

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

Unable to open image file: C:\Program Files\Debugging Tools for Windows (x86)\sym\tcpip.sys\485B8A3657f80\tcpip.sys
ϵͳÕÒ²»µ½Ö¸¶¨µÄÎļþ¡£

PEB is paged out (Peb.Ldr = 7ffde00c).  Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 7ffde00c).  Type ".hh dbgerr001" for details

BUGCHECK_STR:  0x4E_7

DEFAULT_BUCKET_ID:  INTEL_CPU_MICROCODE_ZERO

PROCESS_NAME:  telnet.exe

LAST_CONTROL_TRANSFER:  from 805259de to 8053456e

STACK_TEXT:  
f6c7a99c 805259de 0000004e 00000007 00002402 nt!KeBugCheckEx+0x1b
f6c7a9bc 804f1ea4 82807000 829fbac0 80562bc0 nt!MiDecrementReferenceCount+0x4e
f6c7a9f0 8054a536 82afc6e0 829fbac0 80562bc0 nt!MiDeferredUnlockPages+0x13d
f6c7aa1c 8054be0b 82807000 829fbac0 829fbac0 nt!MiFreePoolPages+0xac
f6c7aa5c f748fad2 82807000 00000000 f6c7aa9c nt!ExFreePoolWithTag+0x1b7
f6c7aa6c f748fab8 829fbac0 82807000 00000000 tcpip!MdppFreePage+0x10
f6c7aa9c f748eb1b 80552500 00000000 f6c7aaf4 tcpip!MdppScavengePool+0xa9
f6c7aab8 f748ed36 829fba80 f6c7aaf4 828eb008 tcpip!MdpAllocateAtDpcLevel+0x5e
f6c7aacc f7498902 f6c7aaf4 828c68a0 828eb008 tcpip!GetTCPHeaderAtDpcLevel+0x15
f6c7aafc f74986fc 828eb008 00000000 82953200 tcpip!SendSYN+0x1d
f6c7ab40 f74988ca 00c7ab64 00000001 00000000 tcpip!TdiConnect+0x3ab
f6c7ab7c f7491038 828abbf8 828abcb0 828abbf8 tcpip!TCPConnect+0xa8
f6c7ab98 804e47f7 82ad7368 828abbf8 828ce388 tcpip!TCPDispatchInternalDeviceControl+0x13f
f6c7aba8 f7f005fb 828868f8 f6c7ac24 804e47f7 nt!IopfCallDriver+0x31
f6c7abb4 804e47f7 82886840 828abbf8 828f6f74 tdifilter!DispatchAny+0x3b [f:\tdifilter\tdifilter.c @ 96]
f6c7abc4 f7423ec4 00012007 f7423c55 828abbf8 nt!IopfCallDriver+0x31
f6c7ac24 f742b257 828a4988 82a041f0 f6c7ac58 afd!AfdConnect+0x3a8
f6c7ac34 804e47f7 82a1f7e0 828abbf8 806ee070 afd!AfdDispatchDeviceControl+0x53
f6c7ac44 8056b1c8 828abcd4 829be4d0 828abbf8 nt!IopfCallDriver+0x31
f6c7ac58 8057bd83 82a1f7e0 828abbf8 829be4d0 nt!IopSynchronousServiceTail+0x60
f6c7ad00 8057e30b 0000071c 00000734 00000000 nt!IopXxxControlFile+0x611
f6c7ad34 804df7ec 0000071c 00000734 00000000 nt!NtDeviceIoControlFile+0x2a
f6c7ad34 7c92eb94 0000071c 00000734 00000000 nt!KiFastCallEntry+0xf8
WARNING: Frame IP not in any known module. Following frames may be wrong.
0098ed40 00000000 00000000 00000000 00000000 0x7c92eb94

STACK_COMMAND:  kb

FOLLOWUP_IP:
nt!MiDeferredUnlockPages+13d
804f1ea4 e9e9080000      jmp    nt!MiDeferredUnlockPages+0x13d (804f2792)

SYMBOL_STACK_INDEX:  2

SYMBOL_NAME:  nt!MiDeferredUnlockPages+13d

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: nt

DEBUG_FLR_IMAGE_TIMESTAMP:  48a4023c

IMAGE_NAME:  memory_corruption

FAILURE_BUCKET_ID:  0x4E_7_nt!MiDeferredUnlockPages+13d

BUCKET_ID:  0x4E_7_nt!MiDeferredUnlockPages+13d

Followup: MachineOwner
---------
2010-1-8 19:10
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
过一个星期我也看后面的章节,一起交流
2010-1-8 23:49
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好的,一起交流一下!!
2010-1-9 12:20
0
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
别看tdi了,过时了,浪费时间的。
2010-2-4 15:17
0
游客
登录 | 注册 方可回帖
返回
//