📄 packet.c
字号:
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;
NDIS_STATUS Status;
NDIS_STRING SymLink;
IF_LOUD(DbgPrint("NPF: Unload\n"););
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject != NULL) {
OldDeviceObject = DeviceObject;
DeviceObject = DeviceObject->NextDevice;
DeviceExtension = OldDeviceObject->DeviceExtension;
NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
DeviceExtension->AdapterName.Buffer,
NdisProtocolHandle,
DeviceObject,
OldDeviceObject););
if (DeviceExtension->ExportString)
{
RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
IoDeleteSymbolicLink(&SymLink);
ExFreePool(DeviceExtension->ExportString);
}
IoDeleteDevice(OldDeviceObject);
}
NdisDeregisterProtocol(
&Status,
NdisProtocolHandle
);
// Free the adapters names
ExFreePool( bindP );
}
//-------------------------------------------------------------------
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;
PLIST_ENTRY PacketListEntry;
UINT i;
PUCHAR tpointer;
ULONG dim,timeout;
PUCHAR prog;
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;
BOOLEAN Flag;
IF_LOUD(DbgPrint("NPF: IoControl\n");)
IrpSp = IoGetCurrentIrpStackLocation(Irp);
FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
Open=IrpSp->FileObject->FsContext;
Irp->IoStatus.Status = STATUS_SUCCESS;
IF_LOUD(DbgPrint("NPF: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
switch (FunctionCode){
case BIOCGSTATS: //function to get the capture stats
if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){
EXIT_FAILURE(0);
}
*(((PUINT)Irp->UserBuffer)+3) = 0;
*(((PUINT)Irp->UserBuffer)+0) = 0;
*(((PUINT)Irp->UserBuffer)+1) = 0;
*(((PUINT)Irp->UserBuffer)+2) = 0; // Not yet supported
for(i=0;i<NCpu;i++)
{
*(((PUINT)Irp->UserBuffer)+3) += Open->CpuData[i].Accepted;
*(((PUINT)Irp->UserBuffer)+0) += Open->CpuData[i].Received;
*(((PUINT)Irp->UserBuffer)+1) += Open->CpuData[i].Dropped;
*(((PUINT)Irp->UserBuffer)+2) += 0; // Not yet supported
}
EXIT_SUCCESS(4*sizeof(INT));
break;
case BIOCGEVNAME: //function to get the name of the event associated with the current instance
if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){
EXIT_FAILURE(0);
}
RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26);
EXIT_SUCCESS(26);
break;
case BIOCSENDPACKETSSYNC:
SyncWrite = TRUE;
case BIOCSENDPACKETSNOSYNC:
WriteRes = NPF_BufferedWrite(Irp,
(PUCHAR)Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.DeviceIoControl.InputBufferLength,
SyncWrite);
if( WriteRes != -1)
{
EXIT_SUCCESS(WriteRes);
}
EXIT_FAILURE(WriteRes);
break;
case BIOCSETF:
Open->SkipProcessing = 1;
do
{
Flag = FALSE;
for(i=0;i<NCpu;i++)
if (Open->CpuData[i].Processing == 1)
Flag = TRUE;
}
while(Flag); //BUSY FORM WAITING...
// Free the previous buffer if it was present
if(Open->bpfprogram!=NULL){
TmpBPFProgram=Open->bpfprogram;
Open->bpfprogram = NULL;
ExFreePool(TmpBPFProgram);
}
if (Open->Filter!=NULL)
{
JIT_BPF_Filter *OldFilter=Open->Filter;
Open->Filter=NULL;
BPF_Destroy_JIT_Filter(OldFilter);
}
// Get the pointer to the new program
prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
if(prog==NULL)
{
IF_LOUD(DbgPrint("0001");)
Open->SkipProcessing = 0;
EXIT_FAILURE(0);
}
insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
//count the number of operative instructions
for (cnt=0;(cnt<insns) &&(((struct bpf_insn*)prog)[cnt].code!=BPF_SEPARATION); cnt++);
IF_LOUD(DbgPrint("Operative instructions=%u\n",cnt);)
if (((struct bpf_insn*)prog)[cnt].code==BPF_SEPARATION && (insns-cnt-1)!=0)
{
IF_LOUD(DbgPrint("Initialization instructions=%u\n",insns-cnt-1);)
IsExtendedFilter=TRUE;
initprogram=&((struct bpf_insn*)prog)[cnt+1];
if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
{
IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");)
Open->SkipProcessing = 0;
EXIT_FAILURE(0);
}
}
//the NPF processor has been initialized, we have to validate the operative instructions
insns=cnt;
if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0)
{
IF_LOUD(DbgPrint("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
Open->SkipProcessing = 0;
EXIT_FAILURE(0);
}
// 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)
{
IF_LOUD(DbgPrint("Error - No memory for filter");)
// no memory
Open->SkipProcessing = 0;
EXIT_FAILURE(0);
}
//copy the program in the new buffer
RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn));
Open->bpfprogram=TmpBPFProgram;
// Create the new JIT filter function
if(!IsExtendedFilter)
if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL)
{
IF_LOUD(DbgPrint("Error jittering filter");)
Open->SkipProcessing = 0;
EXIT_FAILURE(0);
}
//return
for (i=0;i<NCpu;i++)
{
Open->CpuData[i].C=0;
Open->CpuData[i].P=0;
Open->CpuData[i].Free = Open->Size;
Open->CpuData[i].Accepted=0;
Open->CpuData[i].Dropped=0;
Open->CpuData[i].Received = 0;
}
Open->ReaderSN=0;
Open->WriterSN=0;
Open->SkipProcessing = 0;
EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
break;
case BIOCSMODE: //set the capture mode
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
EXIT_FAILURE(0);
}
mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
///////kernel dump does not work at the moment//////////////////////////////////////////
if (mode & MODE_DUMP)
{
EXIT_FAILURE(0);
}
///////kernel dump does not work at the moment//////////////////////////////////////////
if(mode == MODE_CAPT){
Open->mode=MODE_CAPT;
EXIT_SUCCESS(0);
}
else if (mode==MODE_MON){
Open->mode=MODE_MON;
EXIT_SUCCESS(0);
}
else{
if(mode & MODE_STAT){
Open->mode = MODE_STAT;
NdisAcquireSpinLock(&Open->CountersLock);
Open->Nbytes.QuadPart=0;
Open->Npackets.QuadPart=0;
NdisReleaseSpinLock(&Open->CountersLock);
if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000;
}
if(mode & MODE_DUMP){
Open->mode |= MODE_DUMP;
// Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000;
}
EXIT_SUCCESS(0);
}
EXIT_FAILURE(0);
break;
case BIOCSETDUMPFILENAME:
///////kernel dump does not work at the moment//////////////////////////////////////////
EXIT_FAILURE(0);
///////kernel dump does not work at the moment//////////////////////////////////////////
if(Open->mode & MODE_DUMP)
{
// Close current dump file
if(Open->DumpFileHandle != NULL)
{
NPF_CloseDumpFile(Open);
Open->DumpFileHandle = NULL;
}
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){
EXIT_FAILURE(0);
}
// Allocate the buffer that will contain the string
DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA');
if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
EXIT_FAILURE(0);
}
// Copy the buffer
RtlCopyBytes((PVOID)DumpNameBuff,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.DeviceIoControl.InputBufferLength);
// Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system
((PSHORT)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0;
// Create the unicode string
RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff);
IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n",
Open->DumpFileName.Buffer,
IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
// Try to create the file
if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) &&
NT_SUCCESS( NPF_StartDump(Open)))
{
EXIT_SUCCESS(0);
}
}
EXIT_FAILURE(0);
break;
case BIOCSETDUMPLIMITS:
///////kernel dump does not work at the moment//////////////////////////////////////////
EXIT_FAILURE(0);
///////kernel dump does not work at the moment//////////////////////////////////////////
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 2*sizeof(ULONG))
{
EXIT_FAILURE(0);
}
Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1);
IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);)
EXIT_SUCCESS(0);
break;
case BIOCISDUMPENDED:
///////kernel dump does not work at the moment//////////////////////////////////////////
EXIT_FAILURE(0);
///////kernel dump does not work at the moment//////////////////////////////////////////
if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT))
{
EXIT_FAILURE(0);
}
*((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
EXIT_SUCCESS(4);
break;
case BIOCSETBUFFERSIZE:
if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
{
EXIT_FAILURE(0);
}
// Get the number of bytes to allocate
dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
Open->SkipProcessing = 1;
do
{
Flag = FALSE;
for(i=0;i<NCpu;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -