2013年9月16日星期一

FLT_PREOP_SUCCESS_WITH_CALLBACK蓝屏

If the minifilter driver's preoperation callback routine returns FLT_PREOP_SUCCESS_WITH_CALLBACK but the minifilter driver has not registered a postoperation callback routine for the operation, the system asserts on a checked build.

描述:
在 Windows xp 32上发生,在 Windows 7 64上没有发生.
代码是两个消息的前操作共用一个处理函数,一个有后操作,一个没有后操作,但是前操作里面返回了FLT_PREOP_SUCCESS_WITH_CALLBACK.
看样子是主动蓝屏,不是异常蓝屏.

1: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

FLTMGR_FILE_SYSTEM (f5)
An unrecoverable failure occured inside the filter manager.
Arguments:
Arg1: 00000066, The reason for the failure
Arg2: 82419064
Arg3: 00000000
Arg4: 00000000

Debugging Details:
------------------


DEFAULT_BUCKET_ID:  DRIVER_FAULT

BUGCHECK_STR:  0xF5

PROCESS_NAME:  explorer.exe

LAST_CONTROL_TRANSFER:  from 804f9e55 to 8052c65c

STACK_TEXT:  
b20cd4d4 804f9e55 00000003 b20cd830 00000000 nt!RtlpBreakWithStatusInstruction
b20cd520 804faa40 00000003 00000000 82280a78 nt!KiBugCheckDebugBreak+0x19
b20cd900 804faf8f 000000f5 00000066 82419064 nt!KeBugCheck2+0x574
b20cd920 f849bd28 000000f5 00000066 82419064 nt!KeBugCheckEx+0x1b
b20cd94c f849c8ec 82419008 00000000 b20cd9a8 fltMgr!FltpHandlePreCallbackReturnStatus+0x12e
b20cd9bc f849e1a7 000cd9f8 b20cdc00 824c3b48 fltMgr!FltpPerformPreCallbacks+0x338
b20cd9d4 f84aac7a 000cd9f8 b20cdc38 824c3b48 fltMgr!FltpPassThroughFastIo+0x3b
b20cda18 80584136 824c3b48 b20cdc00 824ca288 fltMgr!FltpFastIoQueryOpen+0xf4
b20cdb04 805c0490 82582030 00000000 821afee0 nt!IopParseDevice+0x916
b20cdb7c 805bca1c 00000000 b20cdbbc 00000040 nt!ObpLookupObjectName+0x53c
b20cdbd0 80577fe5 00000000 00000000 80623701 nt!ObOpenObjectByName+0xea
b20cdd54 8054272c 0191ecec 0191ecc4 0191ed18 nt!NtQueryAttributesFile+0xf1
b20cdd54 7c92e514 0191ecec 0191ecc4 0191ed18 nt!KiFastCallEntry+0xfc
0191eca4 7c92d71a 7c936665 0191ecec 0191ecc4 ntdll!KiFastSystemCallRet
0191eca8 7c936665 0191ecec 0191ecc4 0191f0ac ntdll!ZwQueryAttributesFile+0xc
0191ed18 7c9366d6 0191ed28 00000001 0040003e ntdll!RtlDoesFileExists_UstrEx+0x6b
0191ed30 7c971cb6 0191f0ac 00000001 0191f09c ntdll!RtlDoesFileExists_UEx+0x27
0191ed58 7c935fad 00131470 0191f0ac 00000000 ntdll!RtlDosSearchPath_UEx+0x1f
0191f024 7c9361a5 00131470 0191f09c 00000000 ntdll!LdrpCheckForLoadedDll+0x192
0191f2e0 7c93643d 00000000 00131470 0191f5d4 ntdll!LdrpLoadDll+0x1ba
0191f588 7c801bbd 00131470 0191f5d4 0191f5b4 ntdll!LdrLoadDll+0x230
0191f5f0 77f489ee 0191f844 00000000 00000000 kernel32!LoadLibraryExW+0x18e
0191f820 77f48aab 0191f844 00000000 00000000 SHLWAPI!LoadLibraryExWrapW+0x7e
0191fab8 7d5c21db 0191faf8 00000000 000e55d4 SHLWAPI!SHPinDllOfCLSID+0xab
0191fb0c 7d5bbcac 000e55c0 00000000 7d597034 SHELL32!CRegFolder::_CreateAndInit+0x1cc
0191fb34 7d5bb89f 000e55c0 00000000 7d597034 SHELL32!CRegFolder::_BindToItem+0x55
0191fb58 7d5c05b2 0009f710 000e55c0 00000000 SHELL32!CRegFolder::BindToObject+0x45
0191fb80 7d5c010c 0009f710 000c8fe0 000e55c0 SHELL32!ILCompareRelIDs+0x5b
0191fba4 7d5c14e4 00000000 10000000 00128c48 SHELL32!CRegFolder::CompareIDs+0xb7
0191fbc8 7d5c151e 00128c48 02691e20 0009f710 SHELL32!ILIsParent+0xb2
0191fbe4 7d5c7257 00128c48 02691e20 0191fc90 SHELL32!ILFindChild+0x16
0191fc0c 7d5c729c 00000000 00000000 02691e20 SHELL32!_ReparentAliases+0x58
0191fc28 7d6a2dbd 02691e20 0191fc90 00000002 SHELL32!SHILAliasTranslate+0x17
0191fc48 7d68b58e 000c8db8 0191fc80 02691e20 SHELL32!CDesktopFolder::TranslateIDs+0x34
0191fc94 7d5f942d ffffffff 00000001 7d68b1aa SHELL32!CAnyAlias::_SendNotification+0x66
0191fcc0 7d5c9642 00133c90 000c9dc4 000c9db0 SHELL32!CCollapsingClient::_Flush+0xa8
0191fcd4 7d5c972d 00000001 00000000 0191fd70 SHELL32!CCollapsingClient::Flush+0x2f
0191fcf8 7d5c9765 00000000 7d5c4416 0191fd34 SHELL32!CChangeNotify::_Flush+0x4b
0191fd08 77d18734 0001007a 00000113 00000001 SHELL32!CChangeNotify::WndProc+0xef
0191fd34 77d18816 7d5c4416 0001007a 00000113 USER32!InternalCallWinProc+0x28
0191fd9c 77d189cd 000a1330 7d5c4416 0001007a USER32!UserCallWinProcCheckWow+0x150
0191fdfc 77d18a10 0191fe20 00000000 0191fe3c USER32!DispatchMessageWorker+0x306
0191fe0c 7d5c4495 0191fe20 000c9db0 00000008 USER32!DispatchMessageW+0xf
0191fe3c 7d5c431f 00000000 00000000 00000000 SHELL32!CChangeNotify::_HandleMessages+0x2d
0191ff4c 7d5e1fe4 77f56f82 00000000 7c8099fa SHELL32!CChangeNotify::_MessagePump+0x52
0191ff50 77f56f82 00000000 7c8099fa 00090000 SHELL32!CChangeNotify::ThreadProc+0x1e
0191ffb4 7c80b729 00000000 7c8099fa 00090000 SHLWAPI!WrapperThreadProc+0x94
0191ffec 00000000 77f56f13 016df4d4 00000000 kernel32!BaseThreadStart+0x37


STACK_COMMAND:  kb

FOLLOWUP_IP: 
fltMgr!FltpHandlePreCallbackReturnStatus+12e
f849bd28 cc              int     3

SYMBOL_STACK_INDEX:  4

SYMBOL_NAME:  fltMgr!FltpHandlePreCallbackReturnStatus+12e

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: fltMgr

IMAGE_NAME:  fltMgr.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  480251da

FAILURE_BUCKET_ID:  0xF5_fltMgr!FltpHandlePreCallbackReturnStatus+12e

BUCKET_ID:  0xF5_fltMgr!FltpHandlePreCallbackReturnStatus+12e

Followup: MachineOwner
---------

2013年9月10日星期二

过滤命名管道和邮件槽的操作

#include <ntifs.h>

/*
一下是微软官方的回信:
Hi Kou,
Thanks for your feedback question about this topic.
In the Windows kernel, mailslot and named pipe operations are handled as file I/O.
Prior to Windows 8, the filter manager did not direct I/O for these ‘file types’ to the registered minifilters.
You would need to create a legacy style filter to capture any I/O for a mailslot or a named pipe.
Starting with Windows 8, however, your minifilter can register to filter I/O for the mailslot and named pipe file types also.
Thanks again,
Galen

本文的功能是附加并过滤下面两个对象的操作.
L"\\Device\\NamedPipe"
L"\\Device\\Mailslot"
没有fastio会蓝屏的,这个费了我一周的时间才解决,刚开始是确信没有fastio的,这是错误的.

named pipe测试代码:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx

Mailslots测试代码:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365160(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365802(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365785(v=vs.85).aspx

made by correy
made at 2013.09.05
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

#define TAG 'tset' //test

typedef struct _FILTER_DEVICE_EXTENSION{
    int type; //可以填写的值有NPFS,MSFS,CD0
    PDEVICE_OBJECT NextDeviceObject;
} FILTER_DEVICE_EXTENSION, * PFILTER_DEVICE_EXTENSION;

PDRIVER_OBJECT g_p_DriverObject;

#define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) \
  (((_FastIoDispatchPtr) != NULL) && (((_FastIoDispatchPtr)->SizeOfFastIoDispatch) >= (FIELD_OFFSET(FAST_IO_DISPATCH, _FieldName) + sizeof(void *))) && ((_FastIoDispatchPtr)->_FieldName != NULL))
 
BOOLEAN FsFilterFastIoCheckIfPossible(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__in BOOLEAN CheckForReadOperation,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoCheckIfPossible)) return (fastIoDispatch->FastIoCheckIfPossible)(FileObject, FileOffset, Length, Wait, LockKey, CheckForReadOperation, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoRead(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__out PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoRead)) return (fastIoDispatch->FastIoRead)( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoWrite(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__in PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWrite)) return (fastIoDispatch->FastIoWrite)( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryBasicInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_BASIC_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryBasicInfo)) return (fastIoDispatch->FastIoQueryBasicInfo)( FileObject, Wait, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryStandardInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_STANDARD_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryStandardInfo)) return (fastIoDispatch->FastIoQueryStandardInfo)(FileObject,Wait,Buffer,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoLock(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PLARGE_INTEGER Length,__in PEPROCESS ProcessId,__in ULONG Key,__in BOOLEAN FailImmediately,__in BOOLEAN ExclusiveLock,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoLock)) return (fastIoDispatch->FastIoLock)(FileObject,FileOffset,Length,ProcessId,Key,FailImmediately,ExclusiveLock,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockSingle(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PLARGE_INTEGER Length,__in PEPROCESS ProcessId,__in ULONG Key,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockSingle)) return (fastIoDispatch->FastIoUnlockSingle)(FileObject,FileOffset,Length,ProcessId,Key,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockAll(__in PFILE_OBJECT FileObject,__in PEPROCESS ProcessId,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAll)) return (fastIoDispatch->FastIoUnlockAll)(FileObject,ProcessId,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockAllByKey(__in PFILE_OBJECT FileObject,__in PVOID ProcessId,__in ULONG Key,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAllByKey)) return (fastIoDispatch->FastIoUnlockAllByKey)(FileObject,ProcessId,Key,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoDeviceControl(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__in_opt PVOID InputBuffer,__in ULONG InputBufferLength,__out_opt PVOID OutputBuffer,__in ULONG OutputBufferLength,__in ULONG IoControlCode,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoDeviceControl)) return (fastIoDispatch->FastIoDeviceControl)(FileObject,Wait,InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,IoControlCode,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryNetworkOpenInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_NETWORK_OPEN_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryNetworkOpenInfo)) return (fastIoDispatch->FastIoQueryNetworkOpenInfo)(FileObject,Wait,Buffer,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlRead(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlRead)) return (fastIoDispatch->MdlRead)(FileObject,FileOffset,Length,LockKey,MdlChain,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlReadComplete(__in PFILE_OBJECT FileObject,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadComplete)) return (fastIoDispatch->MdlReadComplete)(FileObject,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoPrepareMdlWrite(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, PrepareMdlWrite)) return (fastIoDispatch->PrepareMdlWrite)(FileObject,FileOffset,Length,LockKey,MdlChain,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlWriteComplete(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteComplete)) return (fastIoDispatch->MdlWriteComplete)(FileObject,FileOffset,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoReadCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PVOID Buffer,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__out struct _COMPRESSED_DATA_INFO* CompressedDataInfo,__in ULONG CompressedDataInfoLength,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoReadCompressed)) return (fastIoDispatch->FastIoReadCompressed)(FileObject,FileOffset,Length,LockKey,Buffer,MdlChain,IoStatus,CompressedDataInfo,CompressedDataInfoLength,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoWriteCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__in PVOID Buffer,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in struct _COMPRESSED_DATA_INFO* CompressedDataInfo,__in ULONG CompressedDataInfoLength,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWriteCompressed)) return (fastIoDispatch->FastIoWriteCompressed)(FileObject,FileOffset,Length,LockKey,Buffer,MdlChain,IoStatus,CompressedDataInfo,CompressedDataInfoLength,nextDeviceObject );
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlReadCompleteCompressed(__in PFILE_OBJECT FileObject,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadCompleteCompressed)) return (fastIoDispatch->MdlReadCompleteCompressed)(FileObject,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlWriteCompleteCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteCompleteCompressed)) return (fastIoDispatch->MdlWriteCompleteCompressed)(FileObject,FileOffset,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryOpen(__in PIRP Irp,__out PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryOpen))
  {
    BOOLEAN result;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    irpSp->DeviceObject = nextDeviceObject;
    result = (fastIoDispatch->FastIoQueryOpen)(Irp,NetworkInformation,nextDeviceObject);
    irpSp->DeviceObject = DeviceObject;
    return result;
  }
  return FALSE;
}

VOID FsFilterFastIoDetachDevice(__in PDEVICE_OBJECT SourceDevice,__in PDEVICE_OBJECT TargetDevice)
{
  IoDetachDevice(TargetDevice);
  IoDeleteDevice(SourceDevice);
}

FAST_IO_DISPATCH g_fastIoDispatch ={
  sizeof(FAST_IO_DISPATCH),
  FsFilterFastIoCheckIfPossible,
  FsFilterFastIoRead,
  FsFilterFastIoWrite,
  FsFilterFastIoQueryBasicInfo,
  FsFilterFastIoQueryStandardInfo,
  FsFilterFastIoLock,
  FsFilterFastIoUnlockSingle,
  FsFilterFastIoUnlockAll,
  FsFilterFastIoUnlockAllByKey,
  FsFilterFastIoDeviceControl,
  NULL,
  NULL,
  FsFilterFastIoDetachDevice,
  FsFilterFastIoQueryNetworkOpenInfo,
  NULL,
  FsFilterFastIoMdlRead,
  FsFilterFastIoMdlReadComplete,
  FsFilterFastIoPrepareMdlWrite,
  FsFilterFastIoMdlWriteComplete,
  FsFilterFastIoReadCompressed,
  FsFilterFastIoWriteCompressed,
  FsFilterFastIoMdlReadCompleteCompressed,
  FsFilterFastIoMdlWriteCompleteCompressed,
  FsFilterFastIoQueryOpen,
  NULL,
  NULL,
  NULL,
};

BOOLEAN is_block_namedpipe(IN PIO_STACK_LOCATION irpStack,IN PIRP Irp)
{
    switch(irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE: //估计这里全是打开的操作.

        if(FlagOn(irpStack->FileObject->Flags,FO_NAMED_PIPE))
        {
            KdPrint(("FO_NAMED_PIPE!\n"));//这里没有拦截到.
        }

        if(Irp->IoStatus.Information == FILE_CREATED )//应该在完成后检测.
        {
            KdPrint(("named pipe FILE_CREATED!\n"));//这里没有拦截到.
        }

        /*
        检测到的名字有:操作是在桌面刷新一下.
        "\srvsvc"  这两个在对象管理器中没有找到.
        "\lsarpc"
        "\wkssvc"
        "\qqpcmgr\3_1_80" 这个估计是QQ电脑管家的.
        还有就是在我们的客户端测试程序拦截的,我们的东西"\mynamedpipe".
        */
        KdPrint(("named pipe name:%wZ\n",&(irpStack->FileObject->FileName)));

        break;
    case IRP_MJ_CREATE_NAMED_PIPE:
        KdPrint(("IRP_MJ_CREATE_NAMED_PIPE!\n"));//这里拦截到了,估计这里是创建的.用测试代码,也是创建操作在这里过.
        KdPrint(("create named pipe name:%wZ\n",&(irpStack->FileObject->FileName)));
        break;
    case IRP_MJ_READ:
        KdPrint(("NAMED PIPE READ!\n"));
        break;
    case IRP_MJ_WRITE:
        KdPrint(("NAMED PIPE WRITE!\n"));
        break;
    case IRP_MJ_SET_INFORMATION:
        KdPrint(("named pipe set information!\n"));//如果蓝屏,这是蓝屏后的最后一个消息,可是却蓝在读写函数或者控制上.
        break;
    default:
        KdPrint(("NAMED PIPE MajorFunction == %d!\n",irpStack->MajorFunction));
        break;
    }

    return FALSE;
}

BOOLEAN is_block_mailslot (IN PIO_STACK_LOCATION irpStack,IN PIRP Irp)
{
    switch(irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE: //估计这里全是打开的操作.

        if (FlagOn(irpStack->FileObject->Flags,FO_MAILSLOT))
        {
            KdPrint(("FO_MAILSLOT!\n"));//这里没有拦截到.
        }

        if(Irp->IoStatus.Information == FILE_CREATED )//应该在完成后检测.
        {
            KdPrint(("mail slot FILE_CREATED!\n"));//这里没有拦截到.
        }

        KdPrint(("mail slot name:%wZ\n",&(irpStack->FileObject->FileName)));

        break;
    case IRP_MJ_CREATE_MAILSLOT:

        //打开局域网上的文件,发现了"\NET\GETDC042".

        KdPrint(("IRP_MJ_CREATE_MAILSLOT!\n"));//这里拦截到了,估计这里是创建的.
        KdPrint(("create mail slot name:%wZ\n",&(irpStack->FileObject->FileName)));
        break;
    case IRP_MJ_READ:
        KdPrint(("mail slot read!\n"));
        break;
    case IRP_MJ_WRITE:
        KdPrint(("mail slot write!\n"));
        break;
    case IRP_MJ_SET_INFORMATION:
        KdPrint(("mail slot set information!\n"));
        break;
    default:
        KdPrint(("mail slot MajorFunction == %d!\n",irpStack->MajorFunction));
        break;
    }

    return FALSE;
}

NTSTATUS PassThrough(IN PDEVICE_OBJECT pDO, IN PIRP Irp)
{
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
    PFILTER_DEVICE_EXTENSION pDevExt = (PFILTER_DEVICE_EXTENSION)pDO->DeviceExtension;
    BOOLEAN b = FALSE;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    if (pDevExt->type == 'NPFS')
    {
        b = is_block_namedpipe(irpStack,Irp);
    } else if (pDevExt->type == 'MSFS')
    {
        b = is_block_mailslot (irpStack,Irp);
    } else {
        //CD0,这里可以有控制设备的处理.
    }

    //if (b)
    //{
    //    Irp->IoStatus.Status = STATUS_SUCCESS;
    //    Irp->IoStatus.Information = 0;

    //    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    //    return STATUS_SUCCESS;
    //}
   
    IoSkipCurrentIrpStackLocation(Irp);
    Status = IoCallDriver(pDevExt->NextDeviceObject, Irp);//AttachedDevice
    if (!NT_SUCCESS(Status)) {
        KdPrint(("IoCallDriver fail %x!\n",Status));
        KdBreakPoint();
    }

    return Status;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT preDeviceObject, CurrentDeviceObject;
    PFILTER_DEVICE_EXTENSION pDevExt;  

    PAGED_CODE();  

    preDeviceObject = DriverObject->DeviceObject;
    while (preDeviceObject != NULL)
    {
        pDevExt = (PFILTER_DEVICE_EXTENSION)preDeviceObject->DeviceExtension;  
        if (pDevExt->NextDeviceObject) { //确保本驱动创建的设备都包含PFILTER_DEVICE_EXTENSION,没有挂载的把此值设置为0.
            IoDetachDevice(pDevExt->NextDeviceObject);//反附加.AttachedDevice
        }

        CurrentDeviceObject = preDeviceObject;
        preDeviceObject = CurrentDeviceObject->NextDevice;
        IoDeleteDevice(CurrentDeviceObject);
    }
}

NTSTATUS AttachedDevice(wchar_t * pdevice,wchar_t * filter_device_name, int flag)
    /*
    功能:创建一个(过滤)设备并挂载到指定的设备上.
    参数说明:
    pdevice 被挂载的设备.
    filter_device_name 创建的过滤设备.
    flag 创建的过滤设备的标志,在设备对象的扩展结构里面.  

    失败的处理还不完善.需要改进.
    */
{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING DeviceName;
    PDEVICE_OBJECT FilterDeviceObject;
    UNICODE_STRING ObjectName;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT P_Target_DEVICE_OBJECT = 0;
    PFILTER_DEVICE_EXTENSION pDevExt = 0;
    PDEVICE_OBJECT  AttachedDevice = 0;
    PDEVICE_OBJECT      fileSysDevice;

    RtlInitUnicodeString(&ObjectName, pdevice);
    Status = IoGetDeviceObjectPointer(&ObjectName, FILE_ALL_ACCESS, &FileObject, &P_Target_DEVICE_OBJECT);
    if (Status != STATUS_SUCCESS) {
        KdPrint(("IoGetDeviceObjectPointer fail!\n"));
        KdBreakPoint();      
    }  

    ObDereferenceObject(FileObject);

    RtlInitUnicodeString( &DeviceName, filter_device_name);// NT_DEVICE_NAME  FILTER_DEVICE_NAME
    Status = IoCreateDevice(g_p_DriverObject, sizeof(FILTER_DEVICE_EXTENSION),&DeviceName, P_Target_DEVICE_OBJECT->DeviceType, 0, FALSE,&FilterDeviceObject);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }
   
    ClearFlag(FilterDeviceObject->Flags, DO_DEVICE_INITIALIZING); //filterDeviceObject->Flags &= ~0x00000080;

    AttachedDevice = IoAttachDeviceToDeviceStack(FilterDeviceObject,  P_Target_DEVICE_OBJECT);//返回附加前的顶层设备.
    if (AttachedDevice == NULL) {
        KdPrint(("IoAttachDeviceToDeviceStack fail!\n"));  
        KdBreakPoint();
    }

    pDevExt = (PFILTER_DEVICE_EXTENSION)FilterDeviceObject->DeviceExtension;
    pDevExt->NextDeviceObject = AttachedDevice;
    pDevExt->type = flag;//        
   
    return TRUE;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    int i;
    NTSTATUS Status = STATUS_SUCCESS;
   
    UNREFERENCED_PARAMETER (RegistryPath);

    KdBreakPoint();//DbgBreakPoint()

    g_p_DriverObject = DriverObject;

    DriverObject->DriverUnload = DriverUnload;

    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = PassThrough;
    }

    DriverObject->FastIoDispatch = & g_fastIoDispatch;
   
    Status = AttachedDevice(L"\\Device\\NamedPipe", L"\\Device\\NPFS", 'NPFS');
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    Status = AttachedDevice(L"\\Device\\Mailslot", L"\\Device\\MSFS", 'MSFS');
    if (!NT_SUCCESS(Status)) {
        //添加删除和反附加设备的代码.
        KdBreakPoint();  
    }

    return Status;
}

2013年9月6日星期五

x64 inline hook ZwCreateSection

#include <ntddk.h>

/*
x64 inline hook ZwCreateSection.
为啥不x64 ssdt hook?,原因有:
1.ssdt 里面的函数少.
2.微软官方声明,这样会patchguard检测到并蓝屏.
3.ssdt 没有导出,需要自己获得.

made by correy
made at 2013.09.06
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

/*
本代码测试环境为:windows server 2008 R2 X64
测试对象为:ZwCreateSection

0: kd> vertarget
Windows 7 Kernel Version 7601 (Service Pack 1) MP (2 procs) Free x64
Product: Server, suite: Enterprise TerminalServer SingleUserTS
Built by: 7601.18205.amd64fre.win7sp1_gdr.130708-1532
Machine Name:
Kernel base = 0xfffff800`01617000 PsLoadedModuleList = 0xfffff800`0185a6d0
Debug session time: Thu Sep  5 20:21:57.396 2013 (UTC + 8:00)
System Uptime: 0 days 0:11:39.021
0: kd> u nt!ZwCreateSection
nt!ZwCreateSection:
fffff800`016c3a60 488bc4          mov     rax,rsp
fffff800`016c3a63 fa              cli
fffff800`016c3a64 4883ec10        sub     rsp,10h
fffff800`016c3a68 50              push    rax
fffff800`016c3a69 9c              pushfq
fffff800`016c3a6a 6a10            push    10h
fffff800`016c3a6c 488d055d290000  lea     rax,[nt!KiServiceLinkage (fffff800`016c63d0)]
fffff800`016c3a73 50              push    rax
*/

/*
经过编译,搜索,发现如下机器码.提示,用push 0x9999999999 是不行的.只能一个字节.
48b89999999909000000 mov rax,999999999h
50                   push    rax
c3                   retn
retn 应该没啥影响,实验吧!

这个12字节,正好对应ZwCreateSection的前几个指令.
如果不对应,后面可以加NOP.
*/
#pragma pack(1) //这一行必不可少.
typedef struct _opcode {
    unsigned short int mov_rax;
    unsigned __int64 my_fn;
    unsigned char push_rax;
    unsigned char retn;
} opcode, *popcode;

opcode g_op;

unsigned char g_original[sizeof(opcode)];//保存函数的前几个字节.

PVOID g_pfn = 0;

NTSTATUS SuperRtlCopyMemory(IN VOID UNALIGNED  *Destination, IN CONST VOID UNALIGNED  *Source, IN SIZE_T  Length)
{
    NTSTATUS status = STATUS_SUCCESS;//STATUS_UNSUCCESSFUL
    PMDL  g_pmdl;
    unsigned int * Mapped;
    KIRQL kirql;

    //改变内存属性。
    g_pmdl = IoAllocateMdl(Destination, sizeof(opcode), 0, 0, NULL);
    if(!g_pmdl)  {
        return status;
    }
    MmBuildMdlForNonPagedPool(g_pmdl);
    Mapped = (unsigned int *)MmMapLockedPages(g_pmdl, KernelMode); //建议使用MmMapLockedPagesSpecifyCache。
    if (Mapped == NULL) {
        return status;
    }

    kirql = KeRaiseIrqlToDpcLevel();

    RtlCopyMemory(Mapped,/*&*/Source,Length);//运行此行前后可以用u nt!ZwOpenProcess看看达到效果没有.  

    KeLowerIrql(kirql);

    //恢复内存属性.
    if(g_pmdl) {
        MmUnmapLockedPages((PVOID)Mapped, g_pmdl);
        IoFreeMdl(g_pmdl);
    }

    return status;
}

NTSTATUS
    MyZwCreateSection(
    OUT PHANDLE  SectionHandle,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
    IN PLARGE_INTEGER  MaximumSize  OPTIONAL,
    IN ULONG  SectionPageProtection,
    IN ULONG  AllocationAttributes,
    IN HANDLE  FileHandle  OPTIONAL
    )
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;

    //也可以通过bu nt!ZwOpenProcess,看看在那里是否跳转到这里.
    KdBreakPoint();//DbgBreakPoint()

    //这是一个示例:打印一个消息,然后原路返回,没有过滤.

    KdPrint(("i am in MyZwCreateSection!\n"));

    SuperRtlCopyMemory(g_pfn,g_original,sizeof(opcode));

    //疑问是在两个SuperRtlCopyMemory函数的调用之间,再发生ZwCreateSection调用,估计是拦截不到的.
    status = ZwCreateSection(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle);

    SuperRtlCopyMemory(g_pfn,&g_op,sizeof(opcode));

    //if (0) //如果拒绝
    //{
    //    //直接返回即可,不必进行下一行的复杂操作.注意,这没有测试.
    //    //设置ZwOpenProcess的sizeof(opcode)+1 = 0xc3,让主函数返回.
    //}
    //else
    //{
    //    //恢复设置,(加DPC及内存读写),包括:ZwOpenProcess的sizeof(opcode)+1 = 0xc3的恢复.
    //    //调用原来的函数.//不准别的在调用.这时功能已经完成了.
    //    //设置hook.(加DPC及内存读写)
    //}

    return status;
}

NTSTATUS hook(wchar_t * pfn,unsigned __int64 p_my_fn)
{
    NTSTATUS status = STATUS_SUCCESS;//STATUS_UNSUCCESSFUL
    UNICODE_STRING usfn;
 
    RtlInitUnicodeString( &usfn, pfn);
    g_pfn = MmGetSystemRoutineAddress(&usfn);
    if (g_pfn == NULL) {
        return status;
    }

    g_op.mov_rax = 0xb848;
    g_op.my_fn = MyZwCreateSection;
    g_op.push_rax = 0x50;
    g_op.retn = 0xc3;//此时可以用 u g_op看看效果.

    RtlCopyMemory(g_original,g_pfn,sizeof(opcode));

    return SuperRtlCopyMemory(g_pfn,&g_op,sizeof(opcode));
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    SuperRtlCopyMemory(g_pfn,g_original,sizeof(opcode));
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    KdBreakPoint();//DbgBreakPoint()

    DriverObject->DriverUnload = DriverUnload;

    return hook(L"ZwCreateSection",MyZwCreateSection);
}

/*一下是验证效果.
0: kd> u nt!ZwCreateSection
nt!ZwCreateSection:
fffff800`016c3a60 488bc4          mov     rax,rsp
fffff800`016c3a63 fa              cli
fffff800`016c3a64 4883ec10        sub     rsp,10h
fffff800`016c3a68 50              push    rax
fffff800`016c3a69 9c              pushfq
fffff800`016c3a6a 6a10            push    10h
fffff800`016c3a6c 488d055d290000  lea     rax,[nt!KiServiceLinkage (fffff800`016c63d0)]
fffff800`016c3a73 50              push    rax
0: kd> p
test!write_memory+0x8d:
fffff880`049a029d 0fb64c2430      movzx   ecx,byte ptr [rsp+30h]
0: kd> u nt!ZwCreateSection
nt!ZwCreateSection:
fffff800`016c3a60 48b840019a0480f8ffff mov rax,offset test!MyZwCreateSection (fffff880`049a0140)
fffff800`016c3a6a 50              push    rax
fffff800`016c3a6b c3              ret
fffff800`016c3a6c 488d055d290000  lea     rax,[nt!KiServiceLinkage (fffff800`016c63d0)]
fffff800`016c3a73 50              push    rax
fffff800`016c3a74 b847000000      mov     eax,47h
fffff800`016c3a79 e982600000      jmp     nt!KiServiceInternal (fffff800`016c9b00)
fffff800`016c3a7e 6690            xchg    ax,ax

依旧出现:
BugCheck 109
Fatal System Error: 0x00000109
nt!FsRtlPrivateInsertSharedLock
*/

2013年9月5日星期四

驱动自杀失败

#include <ntddk.h>

PVOID g_pkThread;

/*
经测试:此代码没有蓝屏,应该蓝屏的.
本想在驱动中自己卸载自己的,测试结果是这样无效.
我想即使是这样,驱动的功能是无效的,即使显示还在运行.

顺便说一下!不注册卸载函数,是无法卸载驱动的,
除非:
1.把驱动模块的内存清零(或者ret c3),但是这样很危险(蓝屏).申请的内容没有清理,内存泄漏.
2.在卸载函数中做手脚.
3.其他.

made by correy
made at 2013.09.05
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{  
    //正常情况下需要等待线程结束,但是现在在线程中调用此函数.
    //KeWaitForSingleObject(g_pkThread, Executive, KernelMode, FALSE, NULL);
    //ObDereferenceObject(g_pkThread);
}

KSTART_ROUTINE ThreadStart;
VOID ThreadStart(__in PVOID  StartContext)
{
    //KeStallExecutionProcessor(60000000);//停止1分钟是为了查看加载没有,应该相信已经加载了。
    DriverUnload((PDRIVER_OBJECT)StartContext);
    PsTerminateSystemThread(STATUS_SUCCESS);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    HANDLE  ThreadHandle;

    KdBreakPoint();//DbgBreakPoint()
    DriverObject->DriverUnload = DriverUnload;

    status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadStart, DriverObject);
    if (status != STATUS_SUCCESS)
    {
        KdPrint(("PsCreateSystemThread return:%d\n", status));
    } else {
        ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &g_pkThread, NULL);
        ZwClose(ThreadHandle);
    }

    return status;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//下面的办法在2013.11.23实验失败.

#include <ntifs.h>

PVOID g_pkThread;
UNICODE_STRING DriverServiceName  = RTL_CONSTANT_STRING(L"test");
wchar_t buffer[260] = {0};
UNICODE_STRING g_RegistryPath;

KSTART_ROUTINE ThreadStart;
VOID ThreadStart(__in PVOID  StartContext)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;

    //KeStallExecutionProcessor(60000000);//停止1分钟是为了查看加载没有,应该相信已经加载了。

    //status = ZwUnloadDriver(&DriverServiceName);//c0000034
    status = ZwUnloadDriver(&g_RegistryPath);//c0000010
    if (status != STATUS_SUCCESS) {//C0000034
        KdPrint(("ZwUnloadDriver fail with:0x%x\n", status));
    }

    PsTerminateSystemThread(STATUS_SUCCESS);
}

DRIVER_UNLOAD DriverUnload;
VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)
{  
    KdBreakPoint();  
}

#pragma INITCODE
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    HANDLE  ThreadHandle;

    KdBreakPoint();

    //g_RegistryPath = RegistryPath;
    RtlInitEmptyUnicodeString(&g_RegistryPath,buffer,sizeof(buffer));//RtlInitUnicodeString(&us1,wsz1);
    RtlCopyUnicodeString(&g_RegistryPath,RegistryPath);

    DriverObject->DriverUnload = DriverUnload;

    status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadStart, DriverObject);
    if (status != STATUS_SUCCESS) {
        KdPrint(("PsCreateSystemThread return:%d\n", status));
    } else {
        ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &g_pkThread, NULL);
        ZwClose(ThreadHandle);
    }

    return status;
}

2013年9月3日星期二

minifilter和namedpipe和mailslot

/*
一个没有成功的测试代码.
测试的代码为msdn上的NamedPipe或者mailslot的示例代码.
此代码的测试环境为:win 8 and windows server 2012及以后的系统.

还是附加并过滤:L"\\Device\\NamedPipe" and L"\\Device\\Mailslot"吧!在win 8以前支持,win 8上也支持,win 8以后就不说了.

made by correy
made at 2013.09.03
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

#include <fltKernel.h>

PFLT_FILTER gFilterHandle;

#define TAG 'tset' //test

#define _In_

FLT_PREOP_CALLBACK_STATUS CreateNamedPipePreOPeration(__inout PFLT_CALLBACK_DATA Cbd, __in PCFLT_RELATED_OBJECTS FltObjects, __out PVOID *CompletionContext)
    /*
    拦截namedpipe and mailslot的操作.
    可能只适宜于win 8 and windows server 2012及以后的系统.
    win 8 以下需要附加并过滤:L"\\Device\\NamedPipe" and L"\\Device\\Mailslot".
    */
{
    //没有走到这里过,如何能走到这里呢?难道要使用:FltCreateNamedPipeFile和FltCreateMailslotFile

    KdPrint(("i am in CreateNamedPipePreOPeration!\n"));

    if (0)  
    {
        Cbd->IoStatus.Status = STATUS_ACCESS_DENIED;
        Cbd->IoStatus.Information = 0;
        return FLT_PREOP_COMPLETE;        
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

FLT_POSTOP_CALLBACK_STATUS CreatePostOperation(__inout PFLT_CALLBACK_DATA Data,__in PCFLT_RELATED_OBJECTS FltObjects, __in_opt PVOID CompletionContext,__in FLT_POST_OPERATION_FLAGS Flags)
{
    PFLT_FILE_NAME_INFORMATION    pfni;
    NTSTATUS                      status;
    FILE_DISPOSITION_INFORMATION  fdi;
    BOOLEAN IsInSpecial = FALSE;
    BOOLEAN IsInRecycler = FALSE;
    BOOLEAN IsInMup = FALSE;    

    UNREFERENCED_PARAMETER(CompletionContext);
    UNREFERENCED_PARAMETER(Flags);

    if(FlagOn(Data->Iopb->TargetFileObject->Flags,FO_NAMED_PIPE) || FlagOn(Data->Iopb->TargetFileObject->Flags,FO_MAILSLOT))//Data->Flags
    {
        //没有走到这里过,如何能走到这里呢?
        KdPrint(("i am in CreatePostOperation!\n"));
    }

    return FLT_POSTOP_FINISHED_PROCESSING;
}

CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
    { IRP_MJ_CREATE,  0, 0, CreatePostOperation},
    { IRP_MJ_CREATE_NAMED_PIPE,  0, CreateNamedPipePreOPeration, 0},
    { IRP_MJ_CREATE_MAILSLOT,  0, CreateNamedPipePreOPeration, 0},//这个和IRP_MJ_CREATE_NAMED_PIPE的处理一样,用同一个函数.
    { IRP_MJ_OPERATION_END }
};

BOOLEAN PrintVolume(__in PCFLT_RELATED_OBJECTS FltObjects)
    /*
    功能:打印挂载的对象的信息。
    这里始终没有打印到:L"\\Device\\NamedPipe" and L"\\Device\\Mailslot".
    倒是第一个是:L"\\Device\\Mup"和一些卷对象,win 8 以前也是这样的.
    */
{
    NTSTATUS status;    
    PVOID Buffer;
    BOOLEAN r = FALSE;    
    ULONG BufferSizeNeeded;
    UNICODE_STRING Volume;

    status = FltGetVolumeName(FltObjects->Volume, NULL, &BufferSizeNeeded);
    if (status != STATUS_BUFFER_TOO_SMALL) {
        return FALSE;
    }

    Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSizeNeeded + 2, TAG);
    if (Buffer == NULL) {
        return FALSE;
    }
    RtlZeroMemory(Buffer,BufferSizeNeeded + 2);

    Volume.Buffer = Buffer;
    Volume.Length = BufferSizeNeeded;
    Volume.MaximumLength = BufferSizeNeeded + 2;

    status = FltGetVolumeName(FltObjects->Volume, &Volume, &BufferSizeNeeded);//最后一个参数为NULL失败。
    if (!NT_SUCCESS(status)) {
        KdPrint(("FltGetVolumeName fail with error 0x%x!\n",status));
        ExFreePoolWithTag(Buffer, TAG);
        return FALSE;
    }

    KdPrint(("attached device:%wZ\n",&Volume));
      
    ExFreePoolWithTag(Buffer, TAG);
    return r;
}

NTSTATUS InstanceSetup (__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, 
                              __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType)
{    
    UNREFERENCED_PARAMETER( Flags );//与下面的if语句自相矛盾。
    UNREFERENCED_PARAMETER( VolumeDeviceType );
    UNREFERENCED_PARAMETER( VolumeFilesystemType );

    PAGED_CODE();

    PrintVolume(FltObjects);

    return STATUS_SUCCESS;//  Attach on manual attachment.
}

#pragma PAGEDCODE
NTSTATUS PtInstanceQueryTeardown (__in PCFLT_RELATED_OBJECTS FltObjects,__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
{
    return STATUS_SUCCESS;
}

#pragma PAGEDCODE//#pragma alloc_text(PAGE, PtUnload)
NTSTATUS PtUnload (__in FLT_FILTER_UNLOAD_FLAGS Flags)
{
    FltUnregisterFilter( gFilterHandle );
    return STATUS_SUCCESS;
}

const FLT_REGISTRATION FilterRegistration = {
    sizeof( FLT_REGISTRATION ),         //  Size

    /*
    注意这个编译的平台要选择WIN 8,估计这样会起效果.
    #if FLT_MGR_WIN8
    #define FLT_REGISTRATION_VERSION   FLT_REGISTRATION_VERSION_0203  // Current version is 2.03
    #elif FLT_MGR_LONGHORN
    #define FLT_REGISTRATION_VERSION   FLT_REGISTRATION_VERSION_0202  // Current version is 2.02
    #else
    #define FLT_REGISTRATION_VERSION   FLT_REGISTRATION_VERSION_0200  // Current version is 2.00
    #endif
    */
    FLT_REGISTRATION_VERSION,           //  Version

//#if (NTDDI_VERSION >= NTDDI_WIN8)
//    FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS,   //  Flags
//#else
//    0,                                      //  Flags
//#endif 

    FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS,   //  Flags
    
    0,                                  //  Context
    Callbacks,                          //  Operation callbacks
    PtUnload,                           //  MiniFilterUnload
    InstanceSetup,                      //  InstanceSetup
    PtInstanceQueryTeardown,            //  InstanceQueryTeardown
    NULL,                               //  InstanceTeardownStart
    NULL,                               //  InstanceTeardownComplete
    NULL,                               //  GenerateFileName
    NULL,                               //  GenerateDestinationFileName
    NULL                                //  NormalizeNameComponent
};

DRIVER_INITIALIZE DriverEntry;
#pragma alloc_text(INIT, DriverEntry)//#pragma INITCODE
NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;

    UNREFERENCED_PARAMETER( RegistryPath );

    //KdBreakPoint();//DbgBreakPoint() 
    
    status = FltRegisterFilter( DriverObject, &FilterRegistration, &gFilterHandle );//Register with FltMgr to tell it our callback routines    
    if (NT_SUCCESS( status )) //FLT_ASSERT( NT_SUCCESS( status ) );
    {        
        status = FltStartFiltering( gFilterHandle );
        if (!NT_SUCCESS( status )) {
            FltUnregisterFilter( gFilterHandle );
        }
    }

    return status;
}