文件监控(教学版)
2016-06-28 21:52
148 查看
参考FileSpy写的文件监控程序,但比它的抽象多了。可能瑞星的文件驱动也是这样写的,否则它为什么老阻止我安装驱动呢。测试程序是一个命令行小程序,负责打开设备,开启监控和关闭监控,运行时开启和关闭两次。
在DebugView中查看输出信息,我只是想看看能不能达到目的,所以信息量很少。
在驱动程序中开启和关闭监控的代码:
VOID AttachedToDeviceByName (__in PWSTR DeviceName, __in BOOLEAN attach)
{
UCHAR tmp_buf1[50];
UNICODE_STRING volumeName;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK openStatus;
HANDLE fileHandle;
PDEVICE_OBJECT volume_obj, fs_obj, spy_obj;
PFILESPY_DEVICE_EXTENSION devExt;
ULONG i;
LARGE_INTEGER interval;
PDEVICE_OBJECT current_obj, next_obj;
PAGED_CODE();
//应用程序传过来的盘符
RtlInitEmptyUnicodeString(&volumeName, (PWSTR)tmp_buf1, sizeof(tmp_buf1));
RtlAppendUnicodeToString(&volumeName, L"\\DosDevices\\");
status = RtlAppendUnicodeToString(&volumeName, DeviceName);
InitializeObjectAttributes( &objectAttributes,
&volumeName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
status = ZwCreateFile( &fileHandle,
SYNCHRONIZE|FILE_READ_DATA,
&objectAttributes,
&openStatus,
NULL,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
status = ObReferenceObjectByHandle( fileHandle,
FILE_READ_DATA,
*IoFileObjectType,
KernelMode,
&volume_obj,
NULL );
fs_obj = IoGetBaseFileSystemDeviceObject( volume_obj );
ObReferenceObject( fs_obj );
if(attach)
{
ObDereferenceObject( volume_obj );
ZwClose( fileHandle );
status = IoCreateDevice( gFileSpyDriverObject,
sizeof( FILESPY_DEVICE_EXTENSION ),
NULL,
fs_obj->DeviceType,
0,
FALSE,
&spy_obj );
devExt = spy_obj->DeviceExtension;
devExt->AttachedToDeviceObject = NULL;
ASSERT( IS_FILESPY_DEVICE_OBJECT( spy_obj ) );
SetFlag( spy_obj->Flags, FlagOn( fs_obj->Flags, (DO_BUFFERED_IO | DO_DIRECT_IO | DO_SUPPORTS_TRANSACTIONS)));
SetFlag( spy_obj->Characteristics, FlagOn( fs_obj->Characteristics, (FILE_DEVICE_SECURE_OPEN) ));
for (i=0; i < 8; i++)
{
status = IoAttachDeviceToDeviceStackSafe( spy_obj, fs_obj, &devExt->AttachedToDeviceObject );
if (NT_SUCCESS(status) )
{
break;
}
interval.QuadPart = (500 * DELAY_ONE_MILLISECOND);
KeDelayExecutionThread( KernelMode, FALSE, &interval );
}
ClearFlag(spy_obj->Flags, DO_DEVICE_INITIALIZING);
ObDereferenceObject( fs_obj );
}
else
{
current_obj = IoGetAttachedDeviceReference( fs_obj );
while (NULL != current_obj)
{
if (IS_FILESPY_DEVICE_OBJECT( current_obj ))
{
spy_obj = current_obj;
break;
}
next_obj = IoGetLowerDeviceObject( current_obj );
ObDereferenceObject( current_obj );
current_obj = next_obj;
}
ObDereferenceObject( volume_obj );
ZwClose( fileHandle );
devExt = spy_obj->DeviceExtension;
IoDetachDevice( devExt->AttachedToDeviceObject );
IoDeleteDevice( spy_obj );
ObDereferenceObject( spy_obj );
ObDereferenceObject( spy_obj );
ObDereferenceObject( spy_obj );
interval.QuadPart = (5 * DELAY_ONE_SECOND); //等5秒
KeDelayExecutionThread( KernelMode, FALSE, &interval );
ObDereferenceObject( fs_obj );
}
}
写的时候遇到一个有趣的问题是,驱动安装卸载一次,然后再安装,应用程序就不能访问它了,GetError()提示说系统找不到指定的文件。原来是卸载的时候没有卸干净,所以第二次不能用,程序中有相连的三句话“ObDereferenceObject( spy_obj);”正是我担心spy_obj不释放才出此下策。
http://www.cnblogs.com/lzjsky/archive/2010/11/19/1881971.html
在DebugView中查看输出信息,我只是想看看能不能达到目的,所以信息量很少。
在驱动程序中开启和关闭监控的代码:
VOID AttachedToDeviceByName (__in PWSTR DeviceName, __in BOOLEAN attach)
{
UCHAR tmp_buf1[50];
UNICODE_STRING volumeName;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK openStatus;
HANDLE fileHandle;
PDEVICE_OBJECT volume_obj, fs_obj, spy_obj;
PFILESPY_DEVICE_EXTENSION devExt;
ULONG i;
LARGE_INTEGER interval;
PDEVICE_OBJECT current_obj, next_obj;
PAGED_CODE();
//应用程序传过来的盘符
RtlInitEmptyUnicodeString(&volumeName, (PWSTR)tmp_buf1, sizeof(tmp_buf1));
RtlAppendUnicodeToString(&volumeName, L"\\DosDevices\\");
status = RtlAppendUnicodeToString(&volumeName, DeviceName);
InitializeObjectAttributes( &objectAttributes,
&volumeName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL );
status = ZwCreateFile( &fileHandle,
SYNCHRONIZE|FILE_READ_DATA,
&objectAttributes,
&openStatus,
NULL,
0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
status = ObReferenceObjectByHandle( fileHandle,
FILE_READ_DATA,
*IoFileObjectType,
KernelMode,
&volume_obj,
NULL );
fs_obj = IoGetBaseFileSystemDeviceObject( volume_obj );
ObReferenceObject( fs_obj );
if(attach)
{
ObDereferenceObject( volume_obj );
ZwClose( fileHandle );
status = IoCreateDevice( gFileSpyDriverObject,
sizeof( FILESPY_DEVICE_EXTENSION ),
NULL,
fs_obj->DeviceType,
0,
FALSE,
&spy_obj );
devExt = spy_obj->DeviceExtension;
devExt->AttachedToDeviceObject = NULL;
ASSERT( IS_FILESPY_DEVICE_OBJECT( spy_obj ) );
SetFlag( spy_obj->Flags, FlagOn( fs_obj->Flags, (DO_BUFFERED_IO | DO_DIRECT_IO | DO_SUPPORTS_TRANSACTIONS)));
SetFlag( spy_obj->Characteristics, FlagOn( fs_obj->Characteristics, (FILE_DEVICE_SECURE_OPEN) ));
for (i=0; i < 8; i++)
{
status = IoAttachDeviceToDeviceStackSafe( spy_obj, fs_obj, &devExt->AttachedToDeviceObject );
if (NT_SUCCESS(status) )
{
break;
}
interval.QuadPart = (500 * DELAY_ONE_MILLISECOND);
KeDelayExecutionThread( KernelMode, FALSE, &interval );
}
ClearFlag(spy_obj->Flags, DO_DEVICE_INITIALIZING);
ObDereferenceObject( fs_obj );
}
else
{
current_obj = IoGetAttachedDeviceReference( fs_obj );
while (NULL != current_obj)
{
if (IS_FILESPY_DEVICE_OBJECT( current_obj ))
{
spy_obj = current_obj;
break;
}
next_obj = IoGetLowerDeviceObject( current_obj );
ObDereferenceObject( current_obj );
current_obj = next_obj;
}
ObDereferenceObject( volume_obj );
ZwClose( fileHandle );
devExt = spy_obj->DeviceExtension;
IoDetachDevice( devExt->AttachedToDeviceObject );
IoDeleteDevice( spy_obj );
ObDereferenceObject( spy_obj );
ObDereferenceObject( spy_obj );
ObDereferenceObject( spy_obj );
interval.QuadPart = (5 * DELAY_ONE_SECOND); //等5秒
KeDelayExecutionThread( KernelMode, FALSE, &interval );
ObDereferenceObject( fs_obj );
}
}
写的时候遇到一个有趣的问题是,驱动安装卸载一次,然后再安装,应用程序就不能访问它了,GetError()提示说系统找不到指定的文件。原来是卸载的时候没有卸干净,所以第二次不能用,程序中有相连的三句话“ObDereferenceObject( spy_obj);”正是我担心spy_obj不释放才出此下策。
http://www.cnblogs.com/lzjsky/archive/2010/11/19/1881971.html
相关文章推荐
- Ubuntu16.04安装:JDK8+eclipse+tomcat9
- 第7章 Linux文件与目录管理
- hadoop入门
- Linux第一周
- Tomcat中的线程池StandardThreadExecutor
- Topcoder SRM 661 Div1 Easy: MissingLCM
- Servlet学习笔记(Tomcat目录结构)
- Linux 装显卡驱动
- Android之adb shell dumpsys activity获取task里面的所有actitiy
- sed的工作原理及使用
- CentOS 6.5 安装Clang 3.5.0
- Shell 循环语句:if,case esac,for,while
- centos6.5安装openssh7.2p2方法
- 如何在程序中动态设置墙纸(使用IActiveDesktop接口)
- Eclipse集成Tomcat 报错Tomcat 7.x JDK name
- Linux mint 18编译CUDA 7.5 Sample
- CF 632E Thief in a Shop
- Android 4.4 图形架构
- 如何在C语言中调用shell命令
- Tomcat的webapps目录下的classes文件夹下缺失编译好的.class文件原因及其解决方法