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

📄 filespy.c

📁 对本程序不隐藏 对其他程序隐藏
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1989-1999  Microsoft Corporation

Module Name:

    filespy.c

Abstract:

    This is the main module of FileSpy.

    As of the Windows XP SP1 IFS Kit version of this sample and later, this
    sample can be built for each build environment released with the IFS Kit
    with no additional modifications.  To provide this capability, additional
    compile-time logic was added -- see the '#if WINVER' locations.  Comments

    tagged with the 'VERSION NOTE' header have also been added as appropriate to
    describe how the logic must change between versions.

    If this sample is built in the Windows XP environment or later, it will run
    on Windows 2000 or later.  This is done by dynamically loading the routines
    that are only available on Windows XP or later and making run-time decisions
    to determine what code to execute.  Comments tagged with 'MULTIVERISON NOTE'
    mark the locations where such logic has been added.

Environment:

    Kernel mode

--*/

//
//  Fixes Win2K compatibility regarding lookaside lists.
//

#ifndef _WIN2K_COMPAT_SLIST_USAGE
#define _WIN2K_COMPAT_SLIST_USAGE
#endif

#include <ntifs.h>
#include <stdlib.h>
#include "filespy.h"
#include "fspyKern.h"
#include "namelookup.h"


//调试信息,DBG下有效
#ifdef DBG
#define dprintf  DbgPrint
#else 
#define dprintf  
#endif


//
// Global variables.
//

HANDLE  g_hProcessId=NULL;

//
// Record : Add by lwf : 07-06-19
// Purpose: Store the hidden Directory 
//  

PWSTR   g_szHiddenDir = UNICODE_NULL;
PCHAR   g_szPrivProcName = NULL;
ULONG   g_ulPrivProcNameLen = 0;
ULONG   ProcessNameOffset;


ULONG gFileSpyDebugLevel = DEFAULT_FILESPY_DEBUG_LEVEL;
/*
#if WINVER >= 0x0501
ULONG gFileSpyAttachMode = FILESPY_ATTACH_ALL_VOLUMES;
#else
ULONG gFileSpyAttachMode = FILESPY_ATTACH_ON_DEMAND;
#endif

UNICODE_STRING gInsufficientUnicode = CONSTANT_UNICODE_STRING(L"[-=Insufficient Resources=-]");
UNICODE_STRING gEmptyUnicode = CONSTANT_UNICODE_STRING(L"");
*/

//
//  This lookaside list is used to allocate NAME_CONTROLs.  A name control
//  has a small buffer that should be big enough to handle most object names,
//  and can be resized if necessary.  These name controls are used in many
//  places to avoid allocating a large name buffer on the stack.
//
//  We allocate space for the name control from the lookaside list, which is
//  efficient because the size of the allocation is known and constant.  If more
//  buffer space is needed, we use NLCheckAndGrowNameControl which then
//  allocates more space from paged pool.
//

#define FILESPY_LOOKASIDE_SIZE  sizeof( NAME_CONTROL )
PAGED_LOOKASIDE_LIST gFileSpyNameBufferLookasideList;

PDEVICE_OBJECT gControlDeviceObject;

PDRIVER_OBJECT gFileSpyDriverObject;

#define IS_MY_CONTROL_DEVICE_OBJECT(_devObj) \
    (((_devObj) == gControlDeviceObject) ? \
            (ASSERT(((_devObj)->DriverObject == gFileSpyDriverObject) && \
                    ((_devObj)->DeviceExtension == NULL)), TRUE) : \
            FALSE)


//
//  The list of device extensions for the volume device objects we are
//  attached to (the volumes we are spying on).  Note:  This list does NOT
//  include FileSystem control device objects we are attached to.  This
//  list is used to answer the question "Which volumes are we logging?"
//

FAST_MUTEX gSpyDeviceExtensionListLock;
LIST_ENTRY gSpyDeviceExtensionList;

//
// NOTE 1:  There are some cases where we need to hold both the
//   gControlDeviceStateLock and the gOutputBufferLock at the same time.  In
//   these cases, you should acquire the gControlDeviceStateLock then the
//   gOutputBufferLock.
// NOTE 2:  The gControlDeviceStateLock MUST be a spinlock since we try to
//   acquire it during the completion path in SpyLog, which could be called at
//   DISPATCH_LEVEL (only KSPIN_LOCKs can be acquired at DISPATCH_LEVEL).
//

CONTROL_DEVICE_STATE gControlDeviceState = CLOSED;
KSPIN_LOCK gControlDeviceStateLock;

// NOTE:  Like the gControlDeviceStateLock, gOutputBufferLock MUST be a spinlock
//   since we try to acquire it during the completion path in SpyLog, which
//   could be called at DISPATCH_LEVEL (only KSPIN_LOCKs can be acquired at
//   DISPATCH_LEVEL).
//
//KSPIN_LOCK gOutputBufferLock;
//LIST_ENTRY gOutputBufferList;

#ifndef MEMORY_DBG
//NPAGED_LOOKASIDE_LIST gFreeBufferList;
#endif

//ULONG gLogSequenceNumber = 0;
//KSPIN_LOCK gLogSequenceLock;

//UNICODE_STRING gVolumeString;
//UNICODE_STRING gOverrunString;
//UNICODE_STRING gPagingIoString;

//LONG gMaxRecordsToAllocate = DEFAULT_MAX_RECORDS_TO_ALLOCATE;
//LONG gRecordsAllocated = 0;

//LONG gMaxNamesToAllocate = DEFAULT_MAX_NAMES_TO_ALLOCATE;
//LONG gNamesAllocated = 0;

//LONG gStaticBufferInUse = FALSE;
//CHAR gOutOfMemoryBuffer[RECORD_SIZE];

#if WINVER >= 0x0501
//
//  The structure of function pointers for the functions that are not available
//  on all OS versions.
//

SPY_DYNAMIC_FUNCTION_POINTERS gSpyDynamicFunctions = {0};

ULONG gSpyOsMajorVersion = 0;
ULONG gSpyOsMinorVersion = 0;
#endif

//
//  Control FileSpy statistics
//

//FILESPY_STATISTICS gStats;

//
//  This lock is used to synchronize our attaching to a given device object.
//  This lock fixes a race condition where we could accidently attach to the
//  same device object more then once.  This race condition only occurs if
//  a volume is being mounted at the same time as this filter is being loaded.
//  This problem will never occur if this filter is loaded at boot time before
//  any file systems are loaded.
//
//  This lock is used to atomically test if we are already attached to a given
//  device object and if not, do the attach.
//

FAST_MUTEX gSpyAttachLock;

//
//  Macro for validating the FastIo dispatch routines before calling
//  them in the FastIo pass through functions.
//

#define VALID_FAST_IO_DISPATCH_HANDLER(FastIoDispatchPtr, FieldName) \
    (((FastIoDispatchPtr) != NULL) && \
     (((FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
      (FIELD_OFFSET(FAST_IO_DISPATCH, FieldName) + sizeof(VOID *))) && \
     ((FastIoDispatchPtr)->FieldName != NULL))

//
//  list of known device types
//

const PCHAR DeviceTypeNames[] = {
    "",
    "BEEP",
    "CD_ROM",
    "CD_ROM_FILE_SYSTEM",
    "CONTROLLER",
    "DATALINK",
    "DFS",
    "DISK",
    "DISK_FILE_SYSTEM",
    "FILE_SYSTEM",
    "INPORT_PORT",
    "KEYBOARD",
    "MAILSLOT",
    "MIDI_IN",
    "MIDI_OUT",
    "MOUSE",
    "MULTI_UNC_PROVIDER",
    "NAMED_PIPE",
    "NETWORK",
    "NETWORK_BROWSER",
    "NETWORK_FILE_SYSTEM",
    "NULL",
    "PARALLEL_PORT",
    "PHYSICAL_NETCARD",
    "PRINTER",
    "SCANNER",
    "SERIAL_MOUSE_PORT",
    "SERIAL_PORT",
    "SCREEN",
    "SOUND",
    "STREAMS",
    "TAPE",
    "TAPE_FILE_SYSTEM",
    "TRANSPORT",
    "UNKNOWN",
    "VIDEO",
    "VIRTUAL_DISK",
    "WAVE_IN",
    "WAVE_OUT",
    "8042_PORT",
    "NETWORK_REDIRECTOR",
    "BATTERY",
    "BUS_EXTENDER",
    "MODEM",
    "VDM",
    "MASS_STORAGE",
    "SMB",
    "KS",
    "CHANGER",
    "SMARTCARD",
    "ACPI",
    "DVD",
    "FULLSCREEN_VIDEO",
    "DFS_FILE_SYSTEM",
    "DFS_VOLUME",
    "SERENUM",
    "TERMSRV",
    "KSEC"
};

//
//  We need this because the compiler doesn't like doing sizeof an external
//  array in the other file that needs it (fspylib.c)
//

ULONG SizeOfDeviceTypeNames = sizeof( DeviceTypeNames );

//
//  Since functions in drivers are non-pageable by default, these pragmas
//  allow the driver writer to tell the system what functions can be paged.
//
//  Use the PAGED_CODE() macro at the beginning of these functions'
//  implementations while debugging to ensure that these routines are
//  never called at IRQL > APC_LEVEL (therefore the routine cannot
//  be paged).
//
#if DBG && WINVER >= 0x0501
VOID
DriverUnload(
    IN PDRIVER_OBJECT DriverObject
    );
#endif

NTSTATUS
SpyDirControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

//
// Record : add by lwf : 07-06-20
// Purpose: forward delaration
//   

ULONG 
SpyGetProcessNameOffset(
    VOID
    );
    
PCHAR
SpyGetProcess( 
    PCHAR ProcessName 
    );
        
PCHAR
SpyGetRequestProcess( 				 
    PCHAR ProcessName, 
	  PIRP  pIrp
    );
    
BOOLEAN
IsDirectory(
    ULONG dirattr
		);
            
#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry)
#if DBG && WINVER >= 0x0501
#pragma alloc_text(PAGE, DriverUnload)
#endif
#pragma alloc_text(PAGE, SpyFsNotification)
#pragma alloc_text(PAGE, SpyClose)
#pragma alloc_text(PAGE, SpyDirControl)
#pragma alloc_text(PAGE, SpyFsControl)
#pragma alloc_text(PAGE, SpyFsControlMountVolume)
#pragma alloc_text(PAGE, SpyFsControlMountVolumeComplete)
#pragma alloc_text(PAGE, SpyFsControlLoadFileSystem)
#pragma alloc_text(PAGE, SpyFsControlLoadFileSystemComplete)
#pragma alloc_text(PAGE, SpyFastIoCheckIfPossible)
#pragma alloc_text(PAGE, SpyFastIoRead)
#pragma alloc_text(PAGE, SpyFastIoWrite)
#pragma alloc_text(PAGE, SpyFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, SpyFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, SpyFastIoLock)
#pragma alloc_text(PAGE, SpyFastIoUnlockSingle)
#pragma alloc_text(PAGE, SpyFastIoUnlockAll)
#pragma alloc_text(PAGE, SpyFastIoUnlockAllByKey)
#pragma alloc_text(PAGE, SpyFastIoDeviceControl)
#pragma alloc_text(PAGE, SpyFastIoDetachDevice)
#pragma alloc_text(PAGE, SpyFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, SpyFastIoMdlRead)
#pragma alloc_text(PAGE, SpyFastIoPrepareMdlWrite)
#pragma alloc_text(PAGE, SpyFastIoReadCompressed)
#pragma alloc_text(PAGE, SpyFastIoWriteCompressed)
#pragma alloc_text(PAGE, SpyFastIoQueryOpen)
#pragma alloc_text(PAGE, SpyCommonDeviceIoControl)

#endif

// 
// Directory control structure
//
typedef struct {
    ULONG Length;
    PUNICODE_STRING FileName;
    FILE_INFORMATION_CLASS FileInformationClass;
    ULONG FileIndex;
} QUERY_DIRECTORY, *PQUERY_DIRECTORY;

NTSTATUS
SpyDirControlCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )
{
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);

    KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
SpyDirControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PFILESPY_DEVICE_EXTENSION devExt;
    PIO_STACK_LOCATION irpSp;
    PFILE_OBJECT FileObject;
    KEVENT waitEvent;
    NTSTATUS status;
    ULONG bufferLength;
    ULONG newLength;
    ULONG offset;
    ULONG currentPosition;
    PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
    PFILE_BOTH_DIR_INFORMATION preDirInfo = NULL;
    CHAR  name[PROCNAMELEN];
    PWSTR fileNameBuffer = UNICODE_NULL;

	if(gControlDeviceState == CLOSED || PsGetCurrentProcessId()==g_hProcessId)
	{
        return SpyDispatch(DeviceObject,Irp);
	}

	devExt = DeviceObject->DeviceExtension;
	irpSp = IoGetCurrentIrpStackLocation(Irp);
	FileObject = irpSp->FileObject;

  PAGED_CODE();

//  if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
//        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
//        Irp->IoStatus.Information = 0; 
//        IoCompleteRequest(Irp, IO_NO_INCREMENT);
//        return STATUS_INVALID_DEVICE_REQUEST;
//    }

    if (Irp->RequestorMode == KernelMode) {

        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
    }

    if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)->FileInformationClass) {

        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
    }

    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
    

⌨️ 快捷键说明

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