阅读:8549回复: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)); } } |
|
沙发#
发布于:2008-06-14 20:53
怎么实现文件重定向,比如访问 d:\aa\33.dll 变成 e:\bb\44.dll,有源码学习吗,goyanjie@21cn.com
|
|
板凳#
发布于:2008-06-14 20:48
我想知道怎么文件重定向,比如访问d:\aa\33.dll 变成e:\bb\44.dll,有源码学习最好,goyanjie@21cn.com
|
|
地板#
发布于:2008-04-30 13:30
目前还没碰到这个问题
不过楼主的共享精神 超赞! |
|
地下室#
发布于:2008-04-21 11:02
楼主可以给我发一份源码么,最近刚刚开始学这个,感觉一塌糊涂,china.jiangdong@163.com
|
|
5楼#
发布于:2007-12-25 10:26
楼主 能给我一份你的代码 本人正在学习中 谢谢
zhou_huawen@hotmail.com |
|
6楼#
发布于:2007-12-18 16:13
fancylf ,我也是用了虚的隐藏,不过会有问题的
|
|
7楼#
发布于:2007-12-17 15:48
BOOLEAN Attach2C_Volume()
{ UNICODE_STRING nameString; PDEVICE_OBJECT VolumeDeviceObject; PFILE_OBJECT fileObject; NTSTATUS ntStatus; PSFILTER_DEVICE_EXTENSION sfExtention; PDEVICE_OBJECT fileSysDevice; IO_STATUS_BLOCK ioStatus; HANDLE ntFileHandle; OBJECT_ATTRIBUTES objectAttributes; PAGED_CODE(); RtlInitUnicodeString( &nameString, L"\\DosDevices\\C:\\" ); InitializeObjectAttributes( &objectAttributes, &nameString, 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: \n", 'C'+0)); return FALSE; } DbgPrint(("Filemon: opened the root directory!!! handle: %x\n", ntFileHandle)); ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA, NULL, KernelMode, &fileObject, NULL ); if( !NT_SUCCESS( ntStatus )) { ZwClose( ntFileHandle ); return FALSE; } fileSysDevice = IoGetRelatedDeviceObject( fileObject ); if( ! fileSysDevice ) { ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return FALSE; } ntStatus = IoCreateDevice( gSFilterDriverObject, sizeof(SFILTER_DEVICE_EXTENSION), NULL, fileSysDevice->DeviceType, 0, FALSE, &VolumeDeviceObject ); if( !NT_SUCCESS(ntStatus) ) { ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return FALSE; } VolumeDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; sfExtention = VolumeDeviceObject->DeviceExtension; sfExtention->AttachedToDeviceObject = fileSysDevice; RtlInitUnicodeString(&sfExtention->DeviceName, sfExtention->DeviceNameBuffer); RtlCopyUnicodeString(&sfExtention->DeviceName, &nameString); ntStatus = IoAttachDeviceByPointer( VolumeDeviceObject, fileSysDevice ); if( !NT_SUCCESS(ntStatus) ) { ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return FALSE; } ObDereferenceObject( fileObject ); ZwClose( ntFileHandle ); return TRUE; } |
|
|
8楼#
发布于:2007-12-17 15:44
//准备绑定C:\的设备
RtlInitUnicodeString(&nameString, L"\\DosDevices\\C:\\"); if (!AttachToDiskDevice(&nameString, &FilterDevice)) 这一段实现跟我发布的函数Attach2C_Volume很像。 |
|
|
9楼#
发布于:2007-12-17 15:36
好啊。学习一下。
|
|
|
10楼#
发布于:2007-11-05 08:32
|
|
11楼#
发布于:2007-10-05 16:28
代码已经放出来了,我没想到还有这么多跟我一样的新人,呵呵!
http://bbs.driverdevelop.com/htm_data/39/0709/105273.html |
|
12楼#
发布于:2007-10-05 08:59
楼主,给我一份hoposky@163.com
谢谢了 |
|
|
13楼#
发布于:2007-09-20 10:18
楼主认真,我最偷懒
直接在FileSpy上改了改 |
|
14楼#
发布于:2007-09-19 11:31
楼主,给我一份hyzimbtb@163.com
|
|
15楼#
发布于:2007-09-19 10:17
呵呵,看得眼晕中
下回整个正着的哦 支持一下 |
|
16楼#
发布于:2007-09-18 23:00
谢谢楼主。能给我发一份代码学习一下么?tianzhengmail@163.com
|
|
|
17楼#
发布于:2007-09-18 10:54
学习谢谢分享
|
|
|
18楼#
发布于:2007-09-16 19:11
给一份研究下 谢谢
niklen@163.com |
|
19楼#
发布于:2007-09-16 14:45
有些驱动,里面的逻辑和复杂度,变态到你难以想像。。。
|
|
|
上一页
下一页