📄 packet.c
字号:
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 + -