阅读:8203回复:55
终于搞定了文件隐藏, 忙活了一个星期~哇哈哈
测试win2KSP4基本正常,参考了FileMon的代码,其实驱动开发主要就是资料少,其它方面没有难度,无非就是按照MS设定好的套路写代码,写那个FASTIO的时候尤其是体力活啊,google才是最好的老师,论坛我问的问题没有任何人提醒我,也许是不屑于回答吧,但是对于一个新手来说,一个简单的问题也可以耗费好大量时间,需源码的新手Email我,我也才学一个多星期而已;-)
【环境搭设】 驱动开发一定要有一个调试环境,我是使用VMWare+共享文件夹+SoftICE+DebugView,在主机里面编译,然后切换到VM执行测试,再也不怕BSOD:-) 【变量声明】驱动程序在函数中声明变量,必须将所有的变量声明放函数开始的地方 【分配和释放字符串缓冲区】 RtlInitAnsiString函数初始化ANSI_STRING字符串。 RtlInitUnicodeString函数初始化UNICODE_STRING字符串。 RtlAnsiStringToUnicodeString函数把ANSI_STRING转化成UNICODE_STRING。 RtlFreeUnicodeString函数释放给字符串动态分配的内存。 RtlInitAnsiString和RtlInitUnicodeString初始化时不分配内存。不能使用RtlFreeUnicodeString函数。ANSI_STRING和UNICODE_STRING中的Buffer指向一个字符串常量,当调用RtlFreeUnicodeString时字符串常量占用的地址被释放。所以产生错误。 RtlAnsiStringToUnicodeString该函数被调用时,将为目标变量分配内存。所以在不使用该变量时要用该函数释放内存,以免内存泄漏。 例: UNICODE_STRING string_unicode; ANSI_STRING string_ansi; RtlInitUnicodeString(&string_unicode,L”Hello World!”);//不用释放内存 RtlInitAnsiString(&string_ansi,”Hello World!”); RtlAnsiStringToUnicodeString(&string_unicode,&string_ansi,TRUE);//需要释放内存。 RtlFreeUnicodeString(&string_unicode);//释放动态分配的内存。 【DbgPrint 字符输出格式】 For DbgPrint (or macro KdPrint) - which is like printf - the following formats should be used (expected type of argument): 1. %s (PCHAR) 2. %ws (PWCHAR) 3. %Z (PSTRING, PANSI_STRING, POEM_STRING) 4. %wZ (PUNICODE_STRING) In fact %Z and %wZ are not documented in the official documentation, but you can find them in CRT source file for _output(). 【fastIO】 注意:一定要填写好FastIO函数,否则容易出问题 【DriverUnload】 注意:要首先使用IoDetachDevice卸载附在Device设备上的过滤设备,否则会导致BSOD 代码如下: #include <ntddk.h> #include "fastIO.h" #include "test.h" /* * 驱动主入口函数 */ NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { int i; NTSTATUS status; UNICODE_STRING nameString; PDEVICE_OBJECT FilterDevice; //首先创建一个CDO RtlInitUnicodeString(&nameString, L"\\FileSystem\\SFilter"); status = IoCreateDevice( DriverObject, 0, &nameString, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, FALSE, &g_CDO ); if (!NT_SUCCESS(status)) { KdPrint(("DriverEntry:Error Create cdo, status = %08x\n", status)); return status; } //安装分发函数 for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction = SfPassThrough; } DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FsDirectoryControl; DriverObject->DriverUnload = DriverUnload; //Fast IO InitFastIo(DriverObject); //准备绑定C:\的设备 RtlInitUnicodeString(&nameString, L"\\DosDevices\\C:\\"); if (!AttachToDiskDevice(&nameString, &FilterDevice)) { KdPrint(("DrierEntry Failed..\n")); IoDeleteDevice(FilterDevice); return STATUS_DEVICE_CONFIGURATION_ERROR; } return status;//STATUS_DEVICE_CONFIGURATION_ERROR; } /* *驱动卸载 */ VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { //卸载资源 PDEVICE_OBJECT DO = DriverObject->DeviceObject; PDEVICE_OBJECT NextDO = NULL; PDEVICE_EXTENSION DevEx = NULL; if (DriverObject) { while(DO) { KdPrint (("Unload Device...\n")); NextDO = DO->NextDevice; DevEx = DO->DeviceExtension; if (DevEx) { if (DevEx->AttachedToDevice) { IoDetachDevice(DevEx->AttachedToDevice); } } IoDeleteDevice(DO); DO = NextDO; } } //释放FastIo DestoryFastIo(DriverObject); } /* * 驱动的目录处理函数 */ NTSTATUS FsDirectoryControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); //当前Irp(IO_STACK_LOCATION)的参数 PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; PFILE_BOTH_DIR_INFORMATION dirInfo = NULL; KEVENT waitEvent; //UNICODE_STRING path; ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject)); if (IRP_MN_QUERY_DIRECTORY != irpSp->MinorFunction) { goto SkipHandle; } if (Irp->RequestorMode == KernelMode) { goto SkipHandle; } if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)->FileInformationClass) { goto SkipHandle; } //设置完成回调函数 KeInitializeEvent(&waitEvent, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); //IoSetCompletionRoutine(Irp,CompletionRoutine,context,InvokeOnSuccess,InvokeOnError,InvokeOnCancel); IoSetCompletionRoutine( Irp, DirControlCompletion, //CompletionRoutine &waitEvent, //context parameter TRUE, TRUE, TRUE ); status = IoCallDriver(devExt->AttachedToDevice, Irp); if (STATUS_PENDING == status) { //等待完成 status = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT(STATUS_SUCCESS == status); } if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length)) { IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } //KdPrint(("Hook Directory.\n")); HandleDirectory(Irp->UserBuffer, &((PQUERY_DIRECTORY)&irpSp->Parameters)->Length); IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; SkipHandle: IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDevice, Irp); } BOOLEAN HandleDirectory(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth) { //处理目录操作 PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo; ULONG offset = 0; ULONG position = 0; ULONG newLenth = *lpBufLenth; WCHAR fileName[] = L"HideTest.txt"; do { offset = currentDirInfo->NextEntryOffset; if (!(FILE_ATTRIBUTE_DIRECTORY & currentDirInfo->FileAttributes) && (0 == wcsncmp(currentDirInfo->FileName, fileName, currentDirInfo->FileNameLength>>1))) { //Now We Will Test The FileName //KdPrint(("%08x Hided File:%ws[%d]\n", currentDirInfo->FileAttributes, currentDirInfo->FileName, currentDirInfo->FileNameLength)); RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset); newLenth -= offset; position += offset; } else { //KdPrint(("%08x Directory:%ws\n", currentDirInfo->FileAttributes, currentDirInfo->FileName)); //Move Next position += offset; currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset); } } while (0 != offset); *lpBufLenth = newLenth; return TRUE; } BOOLEAN CmpWString(const WCHAR *s1, const WCHAR *s2, ULONG size) { return TRUE; } NTSTATUS DirControlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { //if (Irp->PendingReturned) IoMarkIrpPending(Irp); KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; //注:必须返回这个值 } BOOLEAN IS_MY_DEVICE_OBJECT(PDEVICE_OBJECT DeviceObject) { return DeviceObject->DriverObject == g_CDO->DriverObject; } /* * 挂载到指定的磁盘设备 */ BOOLEAN AttachToDiskDevice(IN PUNICODE_STRING pDiskName, OUT PDEVICE_OBJECT *pOurDevice) { NTSTATUS status; PDEVICE_EXTENSION DevEx; PDEVICE_OBJECT DiskDeviceObject; PDEVICE_OBJECT NewDeviceObject; IO_STATUS_BLOCK ioStatus; OBJECT_ATTRIBUTES objectAttributes; PFILE_OBJECT fileObject = NULL; HANDLE ntFileHandle; // We have to figure out what device to hook - first open the volume's // root directory // InitializeObjectAttributes(&objectAttributes, pDiskName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = 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(status)) { DbgPrint(("Filemon: Could not open drive\n")); return FALSE; } KdPrint(("Open Device is OK\n")); // // Got the file handle, so now look-up the file-object it refers to // status = ObReferenceObjectByHandle(ntFileHandle, FILE_READ_DATA, NULL, KernelMode, &fileObject, NULL); if(!NT_SUCCESS(status)) { DbgPrint(("Filemon: Could not get fileobject from handle\n")); ZwClose(ntFileHandle); return FALSE; } DiskDeviceObject = IoGetRelatedDeviceObject(fileObject); if(!DiskDeviceObject) { DbgPrint(("Filemon: Could not get related device object\n")); goto ErrHand; } //创建挂载设备 status = IoCreateDevice( g_CDO->DriverObject, sizeof(DEVICE_EXTENSION), NULL, DiskDeviceObject->DeviceType, FILE_DEVICE_SECURE_OPEN, FALSE, &NewDeviceObject ); if (!NT_SUCCESS(status)) { goto ErrHand; } NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; *pOurDevice = NewDeviceObject; DevEx = NewDeviceObject->DeviceExtension; DevEx->AttachedToDevice = DiskDeviceObject; DevEx->DeviceName.Length = 0; DevEx->DeviceName.MaximumLength = sizeof(DevEx->DeviceNameBuffer); DevEx->DeviceName.Buffer = DevEx->DeviceNameBuffer; //RtlFillMemory(DevEx->DeviceName.Buffer, sizeof(DevEx->DeviceNameBuffer), 0); SfGetObjectName(g_CDO, &(DevEx->DeviceName)); //执行挂载 DevEx->AttachedToDevice = IoAttachDeviceToDeviceStack(NewDeviceObject, DiskDeviceObject); if (!DevEx->AttachedToDevice) { goto ErrHand; } KdPrint(("Attath Device is OK\n")); ObDereferenceObject(fileObject); ZwClose(ntFileHandle); return TRUE; ErrHand: KdPrint(("AttachDevice Failed status %08x\n", status)); ObDereferenceObject(fileObject); ZwClose(ntFileHandle); return FALSE; } /* * 不处理的Irp */ NTSTATUS SfPassThrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { //不处理 ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject)); IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDevice, Irp); } /* * 得到一个对象的名称 */ VOID SfGetObjectName( IN PVOID Object, IN OUT PUNICODE_STRING Name ) { NTSTATUS status; CHAR nibuf[512]; //buffer that receives NAME information and name POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)nibuf; ULONG retLength; status = ObQueryNameString(Object, nameInfo, sizeof(nibuf), &retLength); Name->Length = 0; if (NT_SUCCESS( status )) { RtlCopyUnicodeString(Name, &nameInfo->Name); //KdPrint(("Object %wZ,Len = %d.[%d]\n", Name, retLength, Name->Length)); } } |
|
沙发#
发布于:2007-08-27 17:02
怎么代码帖出来就是斜的了??极度不喜欢中。。。
|
|
板凳#
发布于:2007-08-27 22:27
祝贺楼主!学习。能发给代码吗?谢谢! jskcxqhk@yahoo.com.hk
|
|
地板#
发布于:2007-08-28 08:44
希望也给我发一份共同学习,谢谢!
Email:gzwuyh@gmail.com |
|
地下室#
发布于:2007-08-28 10:11
谢谢共享 :)
|
|
5楼#
发布于:2007-08-28 10:24
虽然我也实现了,但还是佩服LZ的精神,顶你一个.
|
|
|
6楼#
发布于:2007-08-28 10:25
你的代码我没看,我也实现禁止访问,但对冰刀无效,LZ的呢
|
|
|
7楼#
发布于:2007-08-28 10:26
谢谢共享,顶!
|
|
8楼#
发布于:2007-08-28 10:28
楼主厉害呀!我也正在学习这块内容,能给我一份代码吗?
wwg266543@sina.com |
|
9楼#
发布于:2007-08-28 10:56
好人 楼主 我也要代码 xiaoyaozhiyu123@163.com
谢谢 |
|
10楼#
发布于:2007-08-28 11:29
To abc13271552
冰刀那个家伙是自己发IRP直接到NTFS的,绕过了我们的过滤驱动了,所以不行啊 我现在还不会,要是有好办法,希望通知一下 我的Email:Boywhp@126.com |
|
11楼#
发布于:2007-08-28 13:50
发份代码学习一下,zhangheyang2008@126.com
另请问我做的文件保护,为什么在文件被装入内存后就不会再受IRP_MJ_READ控制呢?大家是怎么清Cache的呢?我的代码很简单,就是在IRP_MJ_READ里禁止非我的进程访问某个特殊的文件夹。是不是要在FastIO中作什么?如何做呢? |
|
12楼#
发布于:2007-08-28 14:51
这种方式的隐藏,360safe一个检查就把你的设备给detach了。想想当年自己也写过这个,真怀念阿。
另请问我做的文件保护,为什么在文件被装入内存后就不会再受IRP_MJ_READ控制呢?大家是怎么清Cache的呢?我的代码很简单,就是在IRP_MJ_READ里禁止非我的进程访问某个特殊的文件夹。是不是要在FastIO中作什么?如何做呢? 你在irp_mj_create 里处理一下应该比较好 |
|
13楼#
发布于:2007-08-28 15:04
应该在rp_mj_create就让其得到失败的消息
也没有什么好的方法呢?可以隐藏比较好;-( xx_qiang提示一下,目前刚学驱动,太复杂的不会了 |
|
14楼#
发布于:2007-08-28 17:45
你在irp_mj_create 里处理一下应该比较好,中也处理了。
是cache的问题,当文档存在于内存中。像WORD这类软件就可以从Cache中打开了。 |
|
15楼#
发布于:2007-08-28 17:53
赞扬楼主的奉献精神!
|
|
|
16楼#
发布于:2007-08-28 18:22
楼主,mail一个给我吧moshior_li@yahoo.com.cn
|
|
17楼#
发布于:2007-08-28 18:38
想学习一下楼主的代码 谢谢 pandaemail@163.com
|
|
18楼#
发布于:2007-08-28 21:37
|
|
19楼#
发布于:2007-08-29 15:09
楼主给我一份研究一下,chinabjhyn2008@sina.com
|
|
|
上一页
下一页