📄 dump.c
字号:
/*
* Copyright (c) 1999 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdarg.h>
#include <ntddk.h>
#include <ntiologc.h>
#include <ndis.h>
#include "debug.h"
#include "packet.h"
#include "win_bpf.h"
//-------------------------------------------------------------------
NTSTATUS
NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append)
{
NTSTATUS ntStatus;
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
PWCHAR PathPrefix;
USHORT PathLen;
UNICODE_STRING FullFileName;
ULONG FullFileNameLength;
PDEVICE_OBJECT fsdDevice;
FILE_STANDARD_INFORMATION StandardInfo;
IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");)
if(fileName->Buffer[0] == L'\\' &&
fileName->Buffer[1] == L'?' &&
fileName->Buffer[2] == L'?' &&
fileName->Buffer[3] == L'\\'
){
PathLen = 0;
}
else{
PathPrefix = L"\\??\\";
PathLen = 8;
}
// Insert the correct path prefix.
FullFileNameLength = PathLen + fileName->MaximumLength;
FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
FullFileNameLength,
'0DWA');
if (FullFileName.Buffer == NULL) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
return ntStatus;
}
FullFileName.Length = PathLen;
FullFileName.MaximumLength = (USHORT)FullFileNameLength;
if(PathLen)
RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
RtlAppendUnicodeStringToString (&FullFileName, fileName);
IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
InitializeObjectAttributes ( &ObjectAttributes,
&FullFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
// Create the dump file
ntStatus = ZwCreateFile( &Open->DumpFileHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
(Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);)
ExFreePool(FullFileName.Buffer);
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
ExFreePool(FullFileName.Buffer);
ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
FILE_WRITE_ACCESS,
*IoFileObjectType,
KernelMode,
&Open->DumpFileObject,
0);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject);
IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);)
return ntStatus;
}
//-------------------------------------------------------------------
NTSTATUS
NPF_StartDump(POPEN_INSTANCE Open)
{
NTSTATUS ntStatus;
struct packet_file_header hdr;
IO_STATUS_BLOCK IoStatus;
NDIS_REQUEST pRequest;
ULONG MediaType;
OBJECT_ATTRIBUTES ObjectAttributes;
IF_LOUD(DbgPrint("NPF: StartDump.\n");)
// Init the file header
hdr.magic = TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = 0; /*Currently not set*/
hdr.snaplen = 1514;
hdr.sigfigs = 0;
// Detect the medium type
switch (Open->Medium){
case NdisMediumWan:
hdr.linktype = DLT_EN10MB;
break;
case NdisMedium802_3:
hdr.linktype = DLT_EN10MB;
break;
case NdisMediumFddi:
hdr.linktype = DLT_FDDI;
break;
case NdisMedium802_5:
hdr.linktype = DLT_IEEE802;
break;
case NdisMediumArcnet878_2:
hdr.linktype = DLT_ARCNET;
break;
case NdisMediumAtm:
hdr.linktype = DLT_ATM_RFC1483;
break;
default:
hdr.linktype = DLT_EN10MB;
}
// Write the header.
// We can use ZwWriteFile because we are in the context of the application
ntStatus = ZwWriteFile(Open->DumpFileHandle,
NULL,
NULL,
NULL,
&IoStatus,
&hdr,
sizeof(hdr),
NULL,
NULL );
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
ntStatus = STATUS_NO_SUCH_FILE;
return ntStatus;
}
Open->DumpOffset.QuadPart=24;
ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
(ACCESS_MASK)0L,
0,
0,
NPF_DumpThread,
Open);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
return ntStatus;
}
ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&Open->DumpThreadObject,
0);
if ( !NT_SUCCESS( ntStatus ) )
{
IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
ObDereferenceObject(Open->DumpFileObject);
ZwClose( Open->DumpFileHandle );
Open->DumpFileHandle=NULL;
return ntStatus;
}
return ntStatus;
}
//-------------------------------------------------------------------
// Dump Thread
//-------------------------------------------------------------------
VOID NPF_DumpThread(POPEN_INSTANCE Open)
{
ULONG FrozenNic;
IF_LOUD(DbgPrint("NPF: In the work routine. Parameter = 0x%p\n",Open);)
while(TRUE){
// Wait until some packets arrive or the timeout expires
NdisWaitEvent(&Open->DumpEvent, 5000);
IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");)
if(Open->DumpLimitReached ||
Open->Size==0){ // BufSize=0 means that this instance was closed, or that the buffer is too
// small for any capture. In both cases it is better to end the dump
IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
PsTerminateSystemThread(STATUS_SUCCESS);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -