⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	deviceSymLink.Length = 0;
	deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length 
		+ symbolicLinkPrefix.Length 
		+ g_NPF_Prefix.Length 
		+ sizeof(UNICODE_NULL));

	deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA');

	if (deviceSymLink.Buffer  == NULL)
	{
		ExFreePool(deviceName.Buffer);
		return FALSE;
	}

	RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
	RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix);
	RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
		devicePrefix.Length / sizeof(WCHAR));

	RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
	RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix);
	RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
		devicePrefix.Length / sizeof(WCHAR));

	IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)

		status = IoCreateDevice(adriverObjectP, 
		sizeof(DEVICE_EXTENSION),
		&deviceName, 
		FILE_DEVICE_TRANSPORT, 
		0, 
		FALSE,
		&devObjP);

	if (NT_SUCCESS(status)) 
	{
		PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
		
		IF_LOUD(DbgPrint("Device created successfully\n"););

		devObjP->Flags |= DO_DIRECT_IO;
		RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);   
		devExtP->NdisProtocolHandle=aProtoHandle;

		IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););

		if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS)
		{
			IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););

			ExFreePool(deviceName.Buffer);
			ExFreePool(deviceSymLink.Buffer);

			devExtP->ExportString = NULL;

			return FALSE;
		}

		IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););

		devExtP->ExportString = deviceSymLink.Buffer;

		ExFreePool(deviceName.Buffer);

		return TRUE;
	}

	else 
	{
		IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););

		ExFreePool(deviceName.Buffer);
		ExFreePool(deviceSymLink.Buffer);
		
		return FALSE;
	}
}
//-------------------------------------------------------------------

VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject)
{
	PDEVICE_OBJECT     DeviceObject;
	PDEVICE_OBJECT     OldDeviceObject;
	PDEVICE_EXTENSION  DeviceExtension;

	NDIS_HANDLE        NdisProtocolHandle = NULL;
	NDIS_STATUS        Status;

	NDIS_STRING		   SymLink;

	TRACE_ENTER();
	
	DeviceObject    = DriverObject->DeviceObject;

	while (DeviceObject != NULL) {
		OldDeviceObject = DeviceObject;

		DeviceObject = DeviceObject->NextDevice;

		DeviceExtension = OldDeviceObject->DeviceExtension;

		NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;

		TRACE_MESSAGE4(PACKET_DEBUG_LOUD,"Deleting Adapter %ws, Protocol Handle=%p, Device Obj=%p (%p)",
			DeviceExtension->AdapterName.Buffer,
			NdisProtocolHandle,
			DeviceObject,
			OldDeviceObject);

		if (DeviceExtension->ExportString)
		{
			RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);

			TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Deleting SymLink at %p", SymLink.Buffer);

			IoDeleteSymbolicLink(&SymLink);
			ExFreePool(DeviceExtension->ExportString);
		}

		IoDeleteDevice(OldDeviceObject);
	}

	NdisDeregisterProtocol(
		&Status,
		NdisProtocolHandle
		);

	// Free the adapters names
	ExFreePool( bindP );

	TRACE_EXIT();

	// Free the device names string that was allocated in the DriverEntry 
//	NdisFreeString(g_NPF_Prefix);
}

#define SET_FAILURE_BUFFER_SMALL() do{\
	Information = 0; \
	Status = STATUS_BUFFER_TOO_SMALL; \
} while(FALSE)

#define SET_RESULT_SUCCESS(__a__) do{\
	Information = __a__;	\
	Status = STATUS_SUCCESS;	\
} while(FALSE)

#define SET_FAILURE_INVALID_REQUEST() do{\
	Information = 0; \
	Status = STATUS_INVALID_DEVICE_REQUEST; \
} while(FALSE)

#define SET_FAILURE_UNSUCCESSFUL()  do{\
	Information = 0; \
	Status = STATUS_UNSUCCESSFUL; \
} while(FALSE)

#define SET_FAILURE_NOMEM()  do{\
	Information = 0; \
	Status = STATUS_INSUFFICIENT_RESOURCES; \
} while(FALSE)

//-------------------------------------------------------------------

NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    POPEN_INSTANCE      Open;
    PIO_STACK_LOCATION  IrpSp;
    PLIST_ENTRY         RequestListEntry;
    PINTERNAL_REQUEST   pRequest;
    ULONG               FunctionCode;
    NDIS_STATUS	        Status;
	ULONG				Information = 0;
	PLIST_ENTRY         PacketListEntry;
	UINT				i;
	PUCHAR				tpointer;
	ULONG				dim,timeout;
	struct bpf_insn*	NewBpfProgram;
	PPACKET_OID_DATA    OidData;
	int					*StatsBuf;
    PNDIS_PACKET        pPacket;
	ULONG				mode;
	PWSTR				DumpNameBuff;
	PUCHAR				TmpBPFProgram;
	INT					WriteRes;
	BOOLEAN				SyncWrite = FALSE;
	struct bpf_insn		*initprogram;
	ULONG				insns;
	ULONG				cnt;
	BOOLEAN				IsExtendedFilter=FALSE;
	ULONG				StringLength;
	ULONG				NeededBytes;
	BOOLEAN				Flag;
	PUINT				pStats;

	HANDLE				hUserEvent;
	PKEVENT				pKernelEvent;
#ifdef __NPF_AMD64__
    VOID*POINTER_32		hUserEvent32Bit;
#endif
	PMDL				mdl;

	TRACE_ENTER();

	IrpSp = IoGetCurrentIrpStackLocation(Irp);
    FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
    Open=IrpSp->FileObject->FsContext;

    Irp->IoStatus.Status = STATUS_SUCCESS;

	TRACE_MESSAGE3(PACKET_DEBUG_LOUD,
		"Function code is %08lx Input size=%08lx Output size %08lx",
		FunctionCode,
		IrpSp->Parameters.DeviceIoControl.InputBufferLength,
		IrpSp->Parameters.DeviceIoControl.OutputBufferLength);

	switch (FunctionCode){
		
	case BIOCGSTATS: //function to get the capture stats

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCGSTATS");

		if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(UINT))
		{			
			SET_FAILURE_BUFFER_SMALL();
			break;
		}

		if (Irp->UserBuffer == NULL)
		{
			SET_FAILURE_UNSUCCESSFUL();
			break;
		}

		//
		// temp fix to a GIANT bug from LD. The CTL code has been defined as METHOD_NEITHER, so it
		// might well be a dangling pointer. We need to probe and lock the address.
		//

		mdl = NULL;
		pStats = NULL;

		__try
		{
			mdl = IoAllocateMdl(
				Irp->UserBuffer,  
				IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
				FALSE,
				TRUE,
				NULL);

			if (mdl == NULL)
			{
				SET_FAILURE_UNSUCCESSFUL();
				break;
			}

			MmProbeAndLockPages(
				mdl,
				UserMode,
				IoWriteAccess);

			pStats = (PUINT)(Irp->UserBuffer);
		}
		__except(GetExceptionCode() == STATUS_ACCESS_VIOLATION)
		{
			pStats = NULL;
		}

		if (pStats == NULL)
		{
			if (mdl != NULL)
			{
				IoFreeMdl(mdl);
			}

			SET_FAILURE_UNSUCCESSFUL();
			break;
		}

		pStats[3] = 0;
		pStats[0] = 0;
		pStats[1] = 0;
		pStats[2] = 0;		// Not yet supported

		for(i = 0 ; i < NCpu ; i++)
		{

			pStats[3] += Open->CpuData[i].Accepted;
			pStats[0] += Open->CpuData[i].Received;
			pStats[1] += Open->CpuData[i].Dropped;
			pStats[2] += 0;		// Not yet supported
		}
		
		MmUnlockPages(mdl);
		IoFreeMdl(mdl);

		SET_RESULT_SUCCESS(4*sizeof(UINT));
		
		break;
		
	case BIOCGEVNAME: //function to get the name of the event associated with the current instance
		
		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCGEVNAME");

		//
		// Since 20060405, the event handling has been changed:
		// we no longer use named events, instead the user level app creates an event,
		// and passes it back to the kernel, that references it (ObReferenceObjectByHandle), and
		// signals it.
		// For the time being, we still leave this ioctl code here, and we simply fail.
		//
		SET_FAILURE_INVALID_REQUEST();
		break;

	case BIOCSENDPACKETSSYNC:

		SyncWrite = TRUE;

	case BIOCSENDPACKETSNOSYNC:

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSENDPACKETSNOSYNC");
		
		NdisAcquireSpinLock(&Open->WriteLock);
		if(Open->WriteInProgress)
		{
			NdisReleaseSpinLock(&Open->WriteLock);
			//
			// Another write operation is currently in progress
			//
			SET_FAILURE_UNSUCCESSFUL();
			break;
		}
		else
		{
			Open->WriteInProgress = TRUE;
		}
		NdisReleaseSpinLock(&Open->WriteLock);
		
		WriteRes = NPF_BufferedWrite(Irp,
			(PUCHAR)Irp->AssociatedIrp.SystemBuffer,
			IrpSp->Parameters.DeviceIoControl.InputBufferLength,
			SyncWrite);

		NdisAcquireSpinLock(&Open->WriteLock);
		Open->WriteInProgress = FALSE;
		NdisReleaseSpinLock(&Open->WriteLock);

		if( WriteRes != -1)
		{
			SET_RESULT_SUCCESS(WriteRes);
		}
		else
		{
			SET_FAILURE_UNSUCCESSFUL();
		}
		break;

	case BIOCSETF:  

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETF");

		//
		// Get the pointer to the new program
		//
		NewBpfProgram = (struct bpf_insn*)Irp->AssociatedIrp.SystemBuffer;
		
		if(NewBpfProgram == NULL)
		{
			SET_FAILURE_BUFFER_SMALL();
			break;
		}
		
		//
		// Lock the machine. After this call we are at DISPATCH level
		//
		NdisAcquireSpinLock(&Open->MachineLock);

		do
		{

			// Free the previous buffer if it was present
			if(Open->bpfprogram != NULL)
			{
				TmpBPFProgram = Open->bpfprogram;
				Open->bpfprogram = NULL;
				ExFreePool(TmpBPFProgram);
			}
		
//
// Jitted filters are supported on x86 (32bit) only
// 
#ifdef __NPF_x86__
			if (Open->Filter != NULL)
			{
				BPF_Destroy_JIT_Filter(Open->Filter);
				Open->Filter = NULL;
			}
#endif // __NPF_x86__

			insns = (IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
		
			//count the number of operative instructions
			for (cnt = 0 ; (cnt < insns) &&(NewBpfProgram[cnt].code != BPF_SEPARATION); cnt++);
		
			TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Operative instructions=%u", cnt);

#ifdef __NPF_x86__
			if ( (cnt != insns) && (insns != cnt+1) && (NewBpfProgram[cnt].code == BPF_SEPARATION)) 
			{
				TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Initialization instructions = %u",insns-cnt-1);
		
				IsExtendedFilter = TRUE;

				initprogram = &NewBpfProgram[cnt+1];
				
				if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
				{
				
					TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error initializing NPF machine (bpf_filter_init)");
					
					SET_FAILURE_INVALID_REQUEST();
					break;
				}
			}
#else  //x86-64 and IA64
			if ( cnt != insns)
			{
				TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error installing the BPF filter. The filter contains TME extensions,"
					" not supported on 64bit platforms.");

				SET_FAILURE_INVALID_REQUEST();
				break;
			}
#endif

			//the NPF processor has been initialized, we have to validate the operative instructions
			insns = cnt;
		
			//NOTE: the validation code checks for TME instructions, and fails if a TME instruction is
			//encountered on 64 bit machines
			if(bpf_validate(NewBpfProgram, cnt, Open->mem_ex.size) == 0)
			{
				TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error validating program");
				//FIXME: the machine has been initialized(?), but the operative code is wrong. 
				//we have to reset the machine!
				//something like: reallocate the mem_ex, and reset the tme_core
				SET_FAILURE_INVALID_REQUEST();
				break;
			}
		
			// Allocate the memory to contain the new filter program
			// We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
			TmpBPFProgram = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA');
			if (TmpBPFProgram == NULL)
			{
				TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error - No memory for filter");
				// no memory
				
				SET_FAILURE_NOMEM();
				break;
			}
		
			//
			// At the moment the JIT compiler works on x86 (32 bit) only
			//
#ifdef __NPF_x86__
			// Create the new JIT filter function
			if(!IsExtendedFilter)
			{
				if((Open->Filter = BPF_jitter(NewBpfProgram, cnt)) == NULL)
				{
					TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Error jittering filter");
					
					ExFreePool(TmpBPFProgram);

					SET_FAILURE_UNSUCCESSFUL();
					break;
				}
			}
#endif

			//copy the program in the new buffer
			RtlCopyMemory(TmpBPFProgram,NewBpfProgram,cnt*sizeof(struct bpf_insn));
			Open->bpfprogram = TmpBPFProgram;

			SET_RESULT_SUCCESS(0);
		}
		while(FALSE);

		//
		// release the machine lock and then reset the buffer
		//
		NdisReleaseSpinLock(&Open->MachineLock);

		NPF_ResetBufferContents(Open);

		break;		
		
	case BIOCSMODE:  //set the capture mode

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSMODE");

		if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
		{			
			SET_FAILURE_BUFFER_SMALL();
			break;
		}

		mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
		
///////kernel dump does not work at the moment//////////////////////////////////////////
		if (mode & MODE_DUMP)
		{			
			SET_FAILURE_INVALID_REQUEST();
			break;
		}
///////kernel dump does not work at the moment//////////////////////////////////////////

		if(mode == MODE_CAPT)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -