• <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:10 S.l.e!ep.¢% 閱讀(1846) 評論(0)  編輯 收藏 引用 所屬分類: Windows WDM
            FileMon源碼學習筆記(一)
            2008-11-24 09:37

            //----------------------------------------------------------------------
            //
            // HookDrive
            //
            // Hook the drive specified by determining which device object to
            // attach to. The algorithm used here is similar to the one used
            // internally by NT to determine which device object a file system request
            // is directed at.
            //
            //----------------------------------------------------------------------
            BOOLEAN
            HookDrive(
            ??? IN ULONG Drive,
            ??? IN PDRIVER_OBJECT DriverObject
            ??? )
            {
            ??? IO_STATUS_BLOCK???? ioStatus;
            ??? HANDLE????????????? ntFileHandle;??
            ??? OBJECT_ATTRIBUTES?? objectAttributes;
            ??? PDEVICE_OBJECT????? fileSysDevice;
            ??? PDEVICE_OBJECT????? hookDevice;
            ??? UNICODE_STRING????? fileNameUnicodeString;
            ??? PFILE_FS_ATTRIBUTE_INFORMATION fileFsAttributes;
            ??? ULONG?????????????? fileFsAttributesSize;
            ??? WCHAR?????????????? filename[] = L"
            \\DosDevices\\A:\\ ";
            ??? NTSTATUS??????????? ntStatus;
            ??? ULONG?????????????? i;
            ??? PFILE_OBJECT??????? fileObject;
            ??? PHOOK_EXTENSION???? hookExtension;
            ???
            ??? //
            ??? // Is it a legal drive letter?
            ??? //
            ??? if( Drive >= 26 ) {

            ??????? return FALSE;
            ??? }

            ??? //
            ??? // Has this drive already been hooked?
            ??? //
            ??? if( DriveHookDevices[Drive] == NULL ) {

            ??????? //
            ??????? // Frob the name to make it refer to the drive specified in the input
            ??????? // parameter.
            ??????? //
            ??????? filename[12] = (CHAR) ('A'+Drive);

            ??????? //
            ??????? // We have to figure out what device to hook - first open the volume's
            ??????? // root directory
            ??????? //
            ??????? RtlInitUnicodeString( &fileNameUnicodeString, filename );
            ??????? InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString,
            ??????????????????????????????????? OBJ_CASE_INSENSITIVE, NULL, NULL );
            ??????? ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,
            ???????????????????????????????? &objectAttributes, &ioStatus, NULL, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
            ???????????????????????????????? FILE_OPEN,
            ???????????????????????????????? FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
            ???????????????????????????????? NULL, 0 );
            ??????? if( !NT_SUCCESS( ntStatus ) ) {

            ??????????? DbgPrint(("Filemon: Could not open drive %c: %x\n", 'A'+Drive, ntStatus ));
            ??????????? return FALSE;
            ??????? }

            ??????? DbgPrint(("Filemon: opened the root directory!!! handle: %x\n", ntFileHandle));??

            ??????? //
            ??????? // Got the file handle, so now look-up the file-object it refers to
            ??????? //
            ??????? ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA,
            ????????????????????????????????????????????? NULL, KernelMode, &fileObject, NULL );
            ??????? if( !NT_SUCCESS( ntStatus )) {

            ??????????? DbgPrint(("Filemon: Could not get fileobject from handle: %c\n", 'A'+Drive ));
            ??????????? ZwClose( ntFileHandle );
            ??????????? return FALSE;
            ??????? }

            ??????? //
            ??????? // Next, find out what device is associated with the file object by getting its related
            ??????? // device object
            ??????? //
            ??????? fileSysDevice = IoGetRelatedDeviceObject( fileObject );

            ??????? if( ! fileSysDevice ) {

            ??????????? DbgPrint(("Filemon: Could not get related device object: %c\n", 'A'+Drive ));
            ??????????? ObDereferenceObject( fileObject );
            ??????????? ZwClose( ntFileHandle );
            ??????????? return FALSE;
            ??????? }

            ??????? //
            ??????? // Check the device list to see if we've already attached to this particular device.
            ??????? // This can happen when more than one drive letter is being handled by the same network
            ??????? // redirecter
            ??????? //
            ??????? for( i = 0; i < 26; i++ ) {

            ??????????? if( DriveHookDevices[i] == fileSysDevice ) {

            ??????????????? //
            ??????????????? // If we're already watching it, associate this drive letter
            ??????????????? // with the others that are handled by the same network driver. This
            ??????????????? // enables us to intelligently update the hooking menus when the user
            ??????????????? // specifies that one of the group should not be watched -we mark all
            ??????????????? // of the related drives as unwatched as well
            ??????????????? //
            ??????????????? ObDereferenceObject( fileObject );
            ??????????????? ZwClose( ntFileHandle );
            ??????????????? DriveHookDevices[ Drive ] = fileSysDevice;
            ??????????????? return TRUE;
            ??????????? }
            ??????? }

            ??????? //
            ??????? // The file system's device hasn't been hooked already, so make a hooking device
            ??????? // object that will be attached to it.
            ??????? //
            ??????? ntStatus = IoCreateDevice( DriverObject,
            ?????????????????????????????????? sizeof(HOOK_EXTENSION),
            ?????????????????????????????????? NULL,
            ?????????????????????????????????? fileSysDevice->DeviceType,
            ?????????????????????????????????? 0,
            ?????????????????????????????????? FALSE,
            ?????????????????????????????????? &hookDevice );
            ??????? if( !NT_SUCCESS(ntStatus) ) {

            ??????????? DbgPrint(("Filemon: failed to create associated device: %c\n", 'A'+Drive ));??

            ??????????? ObDereferenceObject( fileObject );
            ??????????? ZwClose( ntFileHandle );

            ??????????? return FALSE;
            ??????? }

            ??????? //
            ??????? // Clear the device's init flag as per NT DDK KB article on creating device
            ??????? // objects from a dispatch routine
            ??????? //
            ??????? hookDevice->Flags &= ~DO_DEVICE_INITIALIZING;

            ??????? //
            ??????? // Setup the device extensions. The drive letter and file system object are stored
            ??????? // in the extension.
            ??????? //
            ??????? hookExtension = hookDevice->DeviceExtension;
            ??????? hookExtension->LogicalDrive = 'A'+Drive;
            ??????? hookExtension->FileSystem?? = fileSysDevice;
            ??????? hookExtension->Hooked?????? = TRUE;
            ??????? hookExtension->Type???????? = STANDARD;

            ??????? //
            ??????? // Finally, attach to the device. The second we're successfully attached, we may
            ??????? // start receiving IRPs targetted at the device we've hooked.
            ??????? //
            ??????? ntStatus = IoAttachDeviceByPointer( hookDevice, fileSysDevice );
            ??????? if( !NT_SUCCESS(ntStatus) ) {

            ??????????? //
            ??????????? // Couldn' attach for some reason
            ??????????? //
            ??????????? DbgPrint(("Filemon: Connect with Filesystem failed: %c (%x) =>%x\n",
            ????????????????????? 'A'+Drive, fileSysDevice, ntStatus ));

            ??????????? //
            ??????????? // Derefence the object and get out
            ??????????? //
            ??????????? ObDereferenceObject( fileObject );
            ??????????? ZwClose( ntFileHandle );

            ??????????? return FALSE;

            ??????? } else {

            ??????????? //
            ??????????? // Make a new drive group for the device,l if it does not have one
            ??????????? // already
            ??????????? //
            ??????????? DbgPrint(("Filemon: Successfully connected to Filesystem device %c\n", 'A'+Drive ));
            ??????? }

            ??????? //
            ??????? // Determine if this is a NTFS drive
            ??????? //
            ??????? fileFsAttributesSize = sizeof( FILE_FS_ATTRIBUTE_INFORMATION) + MAXPATHLEN;
            ??????? hookExtension->FsAttributes = (PFILE_FS_ATTRIBUTE_INFORMATION) ExAllocatePool( NonPagedPool,
            ?????????????????????????????????????????????????????????????????????????????????????? fileFsAttributesSize );
            ??????? if( hookExtension->FsAttributes &&
            ??????????? !NT_SUCCESS( IoQueryVolumeInformation( fileObject, FileFsAttributeInformation,
            ?????????????????????????????????????????????????? fileFsAttributesSize, hookExtension->FsAttributes,
            ?????????????????????????????????????????????????? &fileFsAttributesSize ))) {

            ??????????? //
            ??????????? // On failure, we just don't have attributes for this file system
            ??????????? //
            ??????????? ExFreePool( hookExtension->FsAttributes );
            ??????????? hookExtension->FsAttributes = NULL;
            ??????? }

            ??????? //
            ??????? // Close the file and update the hooked drive list by entering a
            ??????? // pointer to the hook device object in it.
            ??????? //
            ??????? ObDereferenceObject( fileObject );

            ??????? ZwClose( ntFileHandle );

            ??????? DriveHookDevices[Drive] = hookDevice;
            ???????
            ??? } else {

            ??????? hookExtension = DriveHookDevices[Drive]->DeviceExtension;
            ??????? hookExtension->Hooked = TRUE;
            ??? }
            ??? return TRUE;
            }

            以上摘自FileMon源碼,作者在獲得要hook的設備的DeviceObject的時候用了以下方式:

            ZwCreateFile——》ObReferenceObjectByHandle——》IoGetRelatedDeviceObject

            另外,這個設備對象也可以直接用一個函數獲得IoGetDeviceObjectPointer,該函數原型如下:

            NTSTATUS
            IoGetDeviceObjectPointer(
            ??? IN PUNICODE_STRING ObjectName ,
            ??? IN ACCESS_MASK DesiredAccess ,
            ??? OUT PFILE_OBJECT * FileObject ,
            ??? OUT PDEVICE_OBJECT * DeviceObject
            ??? );

            直接由名字獲得設備對象和文件對象,而該函數內部的實現方式combojiang大俠也給出過c的逆向代碼如下: 逆向為c的代碼:
            NTSTATUS
            IoGetDeviceObjectPointer(
            ???? IN PUNICODE_STRING ObjectName,
            ???? IN ACCESS_MASK DesiredAccess,
            ???? OUT PFILE_OBJECT *FileObject,
            ???? OUT PDEVICE_OBJECT *DeviceObject
            ???? )
            {
            ???? IO_STATUS_BLOCK ioStatus;
            ???? OBJECT_ATTRIBUTES objectAttributes;
            ????
            ???? //額外定義出來的棧變量。由于C與匯編的游戲規則不同。
            ???? PFILE_OBJECT fileObject;
            ???? HANDLE fileHandle;
            ???? NTSTATUS status;
            ????
            ???? InitializeObjectAttributes( &objectAttributes,
            ???????????????????????????????? ObjectName,
            ???????????????????????????????? OBJ_KERNEL_HANDLE,
            ???????????????????????????????? (HANDLE) NULL,
            ???????????????????????????????? (PSECURITY_DESCRIPTOR) NULL );
            ????????????????????????????????
            ??? status = ZwOpenFile( &fileHandle,
            ????????????????????????? DesiredAccess,
            ????????????????????????? &objectAttributes,
            ????????????????????????? &ioStatus,
            ????????????????????????? 0,
            ????????????????????????? 0x40 );

            ???? if (status >= 0)
            ???? {

            ????????? status = ObReferenceObjectByHandle( fileHandle,
            ???????????????????????????????????????????? 0,
            ???????????????????????????????????????????? IoFileObjectType,
            ???????????????????????????????????????????? 0,
            ???????????????????????????????????????????? (PVOID *) &fileObject,
            ???????????????????????????????????????????? 0 );
            ???????? if (status >= 0)
            ???????? {

            ???????????? *FileObject = fileObject;
            ???????????? *DeviceObject = IoGetRelatedDeviceObject( fileObject );
            ???????? }

            ???????? ZwClose( fileHandle );
            ???? }

            ???? return status;
            }
            與FileMon的源碼使用的方法類似,所以FileMon源碼里面應該可以用這個函數直接替代,但是原作者沒有直接調用這個函數,不知道原因是什么,難道是寫FileMon的時候還沒提供這個函數,所以要自己來實現嗎?

            久久久国产乱子伦精品作者| 中文成人久久久久影院免费观看| 一级做a爰片久久毛片免费陪| 亚洲国产精品婷婷久久| 久久99精品国产99久久| 久久久九九有精品国产| 日韩精品久久久久久| 国产精品内射久久久久欢欢| 国产农村妇女毛片精品久久| 久久激情五月丁香伊人| 亚洲欧美久久久久9999 | 2021国产精品久久精品| 日韩欧美亚洲综合久久| 中文字幕久久久久人妻| 久久久久亚洲av无码专区导航| 久久午夜伦鲁片免费无码| 国内精品久久久久| 久久久久人妻一区精品| 久久99久国产麻精品66| 国产精品青草久久久久婷婷| 久久久精品久久久久久| 亚洲国产美女精品久久久久∴| 久久精品国产半推半就| 久久亚洲国产精品123区| 久久青青草原精品国产| 嫩草影院久久国产精品| 久久久亚洲AV波多野结衣| 精品精品国产自在久久高清| 亚洲国产成人久久综合区| 九九精品99久久久香蕉| 亚洲精品NV久久久久久久久久 | 色老头网站久久网| 狠狠色丁香久久综合婷婷| 99久久这里只精品国产免费| 国产99久久久国产精品~~牛| 久久99这里只有精品国产| 国内精品久久久久久麻豆| 久久精品麻豆日日躁夜夜躁| 一本色道久久88综合日韩精品| 99麻豆久久久国产精品免费| 免费久久人人爽人人爽av|