• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            FileMon源碼學習筆記(二)

            Posted on 2010-02-18 15:11 S.l.e!ep.¢% 閱讀(1737) 評論(0)  編輯 收藏 引用 所屬分類: Windows WDM
            FileMon源碼學習筆記(二)
            2008-11-24 10:41

            FileMon源碼中另一個比較疑惑的地方,FileMon創建了兩類設備,一個是用于和ring3通信的GUI設備,另一個是hook的過濾設備,但在代碼中,當收到發向GUI設備的IRP_MJ_DEVICE_CONTROL時,代碼竟是去調用屬于hook設備的功能函數,而在這個功能函數里面通過條件判斷是否是GUI設備來分別處理,而對于發給GUI設備的其他IRP都在直接在GUI的處理函數中直接處理的,不知道作者這樣寫是否有什么深層的含義,不過對于我這種初學者來說,這樣的寫法倒是容易引起混亂,還是不同設備的功能函數,分開來寫好一點。下面附上相關代碼:

            //=========================================================

            //GUI設備的功能函數,注意IRP_MJ_DEVICE_CONTROL的實現

            //=========================================================

            NTSTATUS
            FilemonDeviceRoutine(
            ??? IN PDEVICE_OBJECT DeviceObject,
            ??? IN PIRP Irp
            ??? )
            {
            ??? PIO_STACK_LOCATION irpStack;
            ??? PVOID?????????????? inputBuffer;
            ??? PVOID?????????????? outputBuffer;
            ??? ULONG?????????????? inputBufferLength;
            ??? ULONG?????????????? outputBufferLength;
            ??? ULONG?????????????? ioControlCode;

            ??? //
            ??? // Go ahead and set the request up as successful
            ??? //
            ??? Irp->IoStatus.Status????? = STATUS_SUCCESS;
            ??? Irp->IoStatus.Information = 0;

            ??? //
            ??? // Get a pointer to the current location in the Irp. This is where
            ??? // the function codes and parameters are located.
            ??? //
            ??? irpStack = IoGetCurrentIrpStackLocation (Irp);

            ??? //
            ??? // Get the pointer to the input/output buffer and its length
            ??? //
            ??? inputBuffer??????? = Irp->AssociatedIrp.SystemBuffer;
            ??? inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
            ??? outputBuffer?????? = Irp->AssociatedIrp.SystemBuffer;
            ??? outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
            ??? ioControlCode????? = irpStack->Parameters.DeviceIoControl.IoControlCode;

            ??? switch (irpStack->MajorFunction) {
            ??? case IRP_MJ_CREATE:

            ??????? DbgPrint(("Filemon: IRP_MJ_CREATE\n"));

            ??????? //
            ??????? // Start the sequence number at 0
            ??????? //
            ??????? Sequence = 0;
            ??????? break;

            ??? case IRP_MJ_CLOSE:

            ??????? DbgPrint(("Filemon: IRP_MJ_CLOSE\n"));

            ??????? //
            ??????? // A GUI is closing communication
            ??????? //
            ??????? FilterOn = FALSE;

            ??????? //
            ??????? // If the GUI has no more references to us, reset the output
            ??????? // buffers and hash table.
            ??????? //
            ??????? FilemonResetLog();
            ??????? FilemonHashCleanup();

            ??????? //
            ??????? // Stop capturing drives
            ??????? //
            ??????? HookDriveSet( 0, DeviceObject->DriverObject );
            ??????? UnhookSpecialFs( NPFS );
            ??????? UnhookSpecialFs( MSFS );
            ??????? break;

            ??? case IRP_MJ_DEVICE_CONTROL:

            ??????? //
            ??????? // This path will never execute because we have registered a
            ??????? // fast I/O path for device control. That means that the fast I/O entry
            ??????? // point will ALWAYS be called for Device Control operations
            ??????? //
            ??????? DbgPrint (("Filemon: IRP_MJ_DEVICE_CONTROL\n"));

            ??????? //
            ??????? // Get output buffer if its passed as an MDL
            ??????? //
            ??????? if( Irp->MdlAddress ) {

            ??????????? outputBuffer = MmGetSystemAddressForMdl( Irp->MdlAddress );
            ??????? }

            ??????? //
            ??????? // Its a request from the GUI. Simply call our fast handler.
            ??????? //
            ??????? FilemonFastIoDeviceControl( irpStack->FileObject, TRUE,
            ??????????????????????????????????? inputBuffer, inputBufferLength,
            ??????????????????????????????????? outputBuffer, outputBufferLength,
            ??????????????????????????????????? ioControlCode, &Irp->IoStatus, DeviceObject );
            ??????? break;
            ??? }

            ??? //
            ??? // Complete the IRP
            ??? //
            ??? IoCompleteRequest( Irp, IO_NO_INCREMENT );
            ??? return STATUS_SUCCESS;??
            }

            //=========================================================

            //hook設備的功能函數,在里面夾雜了處理GUI設備的IRP_MJ_DEVICE_CONTROL的代碼

            //=========================================================
            BOOLEAN
            FilemonFastIoDeviceControl(
            ??? IN PFILE_OBJECT FileObject,
            ??? IN BOOLEAN Wait,
            ??? IN PVOID InputBuffer,
            ??? IN ULONG InputBufferLength,
            ??? OUT PVOID OutputBuffer,
            ??? IN ULONG OutputBufferLength,
            ??? IN ULONG IoControlCode,
            ??? OUT PIO_STATUS_BLOCK IoStatus,
            ??? IN PDEVICE_OBJECT DeviceObject
            ??? )
            {
            ??? BOOLEAN???????????? retval = FALSE;
            ??? BOOLEAN???????????? logMutexReleased;
            ??? PHOOK_EXTENSION???? hookExt;
            ??? PLOG_BUF??????????? oldLog, savedCurrentLog;
            ??? CHAR??????????????? fullPathName[MAXPATHLEN], name[PROCNAMELEN], errorBuf[ERRORLEN];
            ??? KIRQL?????????????? oldirql;
            ??? LARGE_INTEGER?????? timeStampStart, timeStampComplete, timeResult;
            ??? LARGE_INTEGER?????? dateTime;

            ??? hookExt = DeviceObject->DeviceExtension;
            ??? if( hookExt->Type == GUIINTERFACE ) {

            ??????? //
            ??????? // Its a message from our GUI!
            ??????? //
            ??????? IoStatus->Status????? = STATUS_SUCCESS; // Assume success
            ??????? IoStatus->Information = 0;????? // Assume nothing returned

            ??????? switch ( IoControlCode ) {

            ??????? case IOCTL_FILEMON_VERSION:

            ??????????? //
            ??????????? // Version #
            ??????????? //
            ??????????? if( OutputBufferLength >= sizeof(ULONG)) {

            ??????????????? *(ULONG *)OutputBuffer = FILEMONVERSION;
            ??????????????? IoStatus->Information = sizeof(ULONG);

            ??????????? } else {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????? }???????????
            ??????????? break;

            ??????? case IOCTL_FILEMON_SETDRIVES:

            ??????????? //
            ??????????? // Hook and/or unhook drives
            ??????????? //
            ??????????? DbgPrint (("Filemon: set drives\n"));

            ??????????? if( InputBufferLength >= sizeof(ULONG) &&
            ???????????????? OutputBufferLength >= sizeof(ULONG)) {

            ??????????????? *(ULONG *)OutputBuffer = HookDriveSet( *(ULONG *)InputBuffer, DeviceObject->DriverObject );
            ??????????????? IoStatus->Information = sizeof(ULONG);

            ??????????? } else {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????? }
            ??????????? break;

            ??????? case IOCTL_FILEMON_HOOKSPECIAL:

            ??????????? if( InputBufferLength >= sizeof(FILE_SYSTEM_TYPE )) {

            ??????????????? if( !HookSpecialFs( DeviceObject->DriverObject, *(PFILE_SYSTEM_TYPE) InputBuffer )) {
            ???????????????
            ??????????????????? IoStatus->Status = STATUS_UNSUCCESSFUL;
            ??????????????? }
            ??????????? } else {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????? }
            ??????????? break;

            ??????? case IOCTL_FILEMON_UNHOOKSPECIAL:

            ??????????? if( InputBufferLength >= sizeof(FILE_SYSTEM_TYPE )) {

            ??????????????? UnhookSpecialFs( *(PFILE_SYSTEM_TYPE) InputBuffer );

            ??????????? } else {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????? }
            ??????????? break;

            ??????? case IOCTL_FILEMON_STOPFILTER:
            ???????????
            ??????????? //
            ??????????? // Turn off logging
            ??????????? //
            ??????????? DbgPrint(("Filemon: stop logging\n"));
            ??????????? FilterOn = FALSE;
            ??????????? break;

            ??????? case IOCTL_FILEMON_STARTFILTER:
            ?????????
            ??????????? //
            ??????????? // Turn on logging
            ??????????? //
            ??????????? DbgPrint(("Filemon: start logging\n"));
            ??????????? FilterOn = TRUE;
            ??????????? break;

            ??????? case IOCTL_FILEMON_SETFILTER:

            ??????????? //
            ??????????? // Gui is updating the filter functions
            ??????????? //
            ??????????? DbgPrint(("Filemon: set filter\n"));

            ??????????? if( InputBufferLength >= sizeof(FILTER) ) {

            ??????????????? FilterDef = *(PFILTER) InputBuffer;
            ??????????????? FilemonUpdateFilters();

            ??????????? } else {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????? }
            ??????????? break;

            ??????? case IOCTL_FILEMON_UNLOADQUERY:
            #if DBG
            ??????????? //
            ??????????? // Is it possible to unload?
            ??????????? //
            ??????????? KeAcquireSpinLock( &CountMutex, &oldirql );
            ??????????? IoStatus->Information = OutstandingIRPCount;

            ??????????? //
            ??????????? // Any outstanding Irps?
            ??????????? //
            ??????????? if( !OutstandingIRPCount ) {

            ??????????????? //
            ??????????????? // Nope, so don't process anymore
            ??????????????? //
            ??????????????? UnloadInProgress = TRUE;

            ??????????????? KeReleaseSpinLock( &CountMutex, oldirql );

            ??????????????? //
            ??????????????? // Stop capturing drives
            ??????????????? //
            ??????????????? HookDriveSet( 0, DeviceObject->DriverObject );
            ??????????????? UnhookSpecialFs( NPFS );
            ??????????????? UnhookSpecialFs( MSFS );

            ??????????????? //
            ??????????????? // Detach from all devices
            ??????????????? //
            ??????????????? UnloadDetach();

            ??????????? } else {

            ??????????????? KeReleaseSpinLock( &CountMutex, oldirql );
            ??????????? }
            #else // DBG
            ??????????? IoStatus->Information = 1;
            #endif // DBG
            ??????????? break;

            ??????? case IOCTL_FILEMON_ZEROSTATS:

            ??????????? //
            ??????????? // Reset all output buffers
            ??????????? //
            ??????????? DbgPrint (("Filemon: zero stats\n"));

            ??????????? ExAcquireFastMutex( &LogMutex );

            ??????????? while( CurrentLog->Next ) {

            ??????????????? //
            ??????????????? // Free all but the first output buffer
            ??????????????? //
            ??????????????? oldLog = CurrentLog->Next;
            ??????????????? CurrentLog->Next = oldLog->Next;

            ??????????????? ExFreePool( oldLog );
            ??????????????? NumLog--;
            ??????????? }

            ??????????? //
            ??????????? // Set the output pointer to the start of the output buffer
            ??????????? //
            ??????????? CurrentLog->Len = 0;
            ??????????? Sequence = 0;

            ??????????? ExReleaseFastMutex( &LogMutex );
            ??????????? break;

            ??????? case IOCTL_FILEMON_GETSTATS:

            ??????????? //
            ??????????? // Copy the oldest output buffer to the caller
            ??????????? //
            ??????????? DbgPrint (("Filemon: get stats\n"));

            ??? //
            ??????????? // If the output buffer is too large to fit into the caller's buffer
            ??????????? //
            ??????????? if( LOGBUFSIZE > OutputBufferLength ) {

            ??????????????? IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
            ??????????????? return FALSE;
            ??????????? }

            ??????????? //
            ??????????? // Probe the output buffer
            ??????????? //
            ??????????? try {????????????????

            ??????????????? ProbeForWrite( OutputBuffer,
            ?????????????????????????????? OutputBufferLength,
            ?????????????????????????????? sizeof( UCHAR ));

            ??????????? } except( EXCEPTION_EXECUTE_HANDLER ) {

            ??????????????? IoStatus->Status = STATUS_INVALID_PARAMETER;
            ??????????????? return FALSE;
            ??????????? }???????????

            ??????????? //
            ??????????? // We're okay, lock the buffer pool
            ??????????? //
            ??????????? ExAcquireFastMutex( &LogMutex );
            ??????????? if( CurrentLog->Len || CurrentLog->Next ) {

            ??????????????? //
            ??????????????? // Start output to a new output buffer
            ??????????????? //
            ??????????????? FilemonAllocateLog();

            ??????????????? //
            ??????????????? // Fetch the oldest to give to user
            ??????????????? //
            ??????????????? oldLog = FilemonGetOldestLog();

            ??????????????? if( oldLog != CurrentLog ) {

            ??????????????????? logMutexReleased = TRUE;
            ??????????????????? ExReleaseFastMutex( &LogMutex );

            ??????????????? } else {

            ??????????????????? logMutexReleased = FALSE;
            ??????????????? }

            ??????????????? //
            ??????????????? // Copy it to the caller's buffer
            ??????????????? //
            ??????????????? memcpy( OutputBuffer, oldLog->Data, oldLog->Len );

            ??????????????? //
            ??????????????? // Return length of copied info
            ??????????????? //
            ??????????????? IoStatus->Information = oldLog->Len;

            ??????????????? //
            ??????????????? // Deallocate buffer - unless its the last one
            ??????????????? //
            ??????????????? if( logMutexReleased ) {
            ???????????????????
            ??????????????????? ExFreePool( oldLog );

            ??????????????? } else {

            ??????????????????? CurrentLog->Len = 0;
            ??????????????????? ExReleaseFastMutex( &LogMutex );???????????????????
            ??????????????? }

            ??????????? } else {

            ??????????????? //
            ??????????????? // There is no unread data
            ??????????????? //
            ??????????????? ExReleaseFastMutex( &LogMutex );
            ???? IoStatus->Information = 0;
            ??????????? }
            ??????????? break;

            ??????? default:

            ??????????? //
            ??????????? // Unknown control
            ??????????? //
            ??????????? DbgPrint (("Filemon: unknown IRP_MJ_DEVICE_CONTROL\n"));
            ??????????? IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
            ??????????? break;
            ??????? }

            ??????? retval = TRUE;

            ??? } else {

            ??????? //
            ??????? // Its a call for a file system, so pass it through
            ??????? //
            ??????? if( FASTIOPRESENT( hookExt, FastIoDeviceControl ) ) {
            ???????
            ??????????? FilemonGetFullPath( FALSE, FileObject, hookExt, fullPathName );
            ??????????? TIMESTAMPSTART();

            ??????????? retval = hookExt->FileSystem->DriverObject->FastIoDispatch->FastIoDeviceControl(
            ??????????????? FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer,
            ??????????????? OutputBufferLength, IoControlCode, IoStatus, hookExt->FileSystem );

            ??????????? if(hookExt->Hooked) {

            ??????????????? TIMESTAMPSTOP();
            ??????????????? LogRecord( TRUE, NULL, &dateTime, &timeResult,
            ?????????????????????????? "%s\tFASTIO_DEVICE_CONTROL\t%s\tIOCTL: 0x%X\t%s",
            ?????????????????????????? FilemonGetProcess( name ), fullPathName,
            ?????????????????????????? IoControlCode,
            ?????????????????????????? retval ? ErrorString( IoStatus->Status, errorBuf ) : "FAILURE" );
            ??????????? }
            ??????? }
            ??? }

            ??? return retval;
            }

            久久亚洲精品成人av无码网站| 久久精品国产半推半就| 99久久精品免费看国产一区二区三区 | 婷婷久久综合九色综合绿巨人| 一级做a爱片久久毛片| 久久99久久99小草精品免视看| 2022年国产精品久久久久| 人妻精品久久久久中文字幕69| 久久精品九九亚洲精品| 色欲av伊人久久大香线蕉影院| 一本色道久久88—综合亚洲精品| 久久婷婷国产剧情内射白浆| 欧美国产精品久久高清| 亚洲一区精品伊人久久伊人| 精品久久久久久无码不卡| 久久久久高潮综合影院| 久久人爽人人爽人人片AV| 粉嫩小泬无遮挡久久久久久| 91精品国产91久久| 久久无码精品一区二区三区| 亚洲性久久久影院| 欧美精品久久久久久久自慰| 久久国产精品99精品国产987| 狠狠色伊人久久精品综合网| 婷婷久久综合| 国产一区二区三区久久精品| 久久精品国产清自在天天线| 影音先锋女人AV鲁色资源网久久| 77777亚洲午夜久久多喷| 久久久精品国产亚洲成人满18免费网站| 亚洲国产婷婷香蕉久久久久久| 性欧美丰满熟妇XXXX性久久久 | 国产69精品久久久久99| 一级女性全黄久久生活片免费 | 7777久久亚洲中文字幕| 久久强奷乱码老熟女| 久久99国产精品尤物| 久久久久亚洲av毛片大| 久久99精品久久久久久久不卡| 亚洲精品97久久中文字幕无码| 国产A三级久久精品|