|
[求助]求有经验的文件重定向驱动开发者帮助
找到办法了 |
|
[求助]求有经验的文件重定向驱动开发者帮助
我已经确定需要合并目录了,过滤IRP_MJ_DIRECTORY_CONTROL.IRP_MN_QUERY_DIRECTORY 目前做法是这样的: 过滤原有查询,当原有查询返回 STATUS_NO_MORE_FILES 时,打开定向目录,并将返回结果改为 STATUS_SUCCESS。据调试如果返回 STATUS_SUCCESS 上层应该是会继续查询的,当继续查询被我们捕获到后,我们再查询定向的目录,一个细节是原目录和定向目录中都有一个文件时,将原目录中文件隐藏。 如原目录 C:\test 下有 a.txt b.txt 定向目录 D:\ 下有 b.txt c.txt,当查询到 a.txt b.txt 时将 b.txt 擦除,继续查询 D:\ 得到 b.txt c.txt 则总的结果是 a.txt b.txt c.txt 整个合并过程在XP上工作观察是稳定的,但在 win7 上将返回值改为 STATUS_SUCCESS 后上层并没有继续查,原因不明。 核心代码如下: static FLT_PREOP_CALLBACK_STATUS _SbPreDirectoryControl( IN PFLT_CALLBACK_DATA Data, IN PCFLT_RELATED_OBJECTS FltObjects, IN PVOID* CompletionContext ) { FLT_PREOP_CALLBACK_STATUS FltStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; UNICODE_STRING Volume = {0}; do { PSB_FILEOBJ_DESC FileobjDesc = NULL; if (IRP_MN_QUERY_DIRECTORY != Data->Iopb->MinorFunction) { break; } if (!SbIsSandboxProcess((ULONG)PsGetCurrentProcessId())) { break; } // 如果记录的有定向目录,则说明已经在合并中了,让后回调去完成查询 FileobjDesc = _SbGetFileobjDesc(Data->Iopb->TargetFileObject); if (FileobjDesc && FileobjDesc->DirectoryHandle) { KdPrint(("found merge query, send to post callback\n")); FltStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK; break; } if (!NT_SUCCESS(IoVolumeDeviceToDosName(Data->Iopb->TargetFileObject->DeviceObject, &Volume)) || Volume.Length < 4 || Volume.Buffer[1] != L':' ) { break; } // 沙箱中文件查询则 passthrough if (SbIsSandboxVolume(Volume.Buffer[0])) { break; } // 否则就让它走 Post Callback (好合并目录和隐藏原目录中文件) FltStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK; } while (FALSE); if (Volume.Buffer) { ExFreePool((VOID*)Volume.Buffer); } return FltStatus; } static NTSTATUS _SbPrepareMergeDirectory( IN OUT PFLT_CALLBACK_DATA Data, IN WCHAR SbVolume, IN PUNICODE_STRING OriginalDirectory ) { NTSTATUS Status = STATUS_UNSUCCESSFUL; PSB_FILEOBJ_DESC FileobjDesc = NULL; do { IO_STATUS_BLOCK IoStatus = {0}; OBJECT_ATTRIBUTES ObjAttrib = {0}; FileobjDesc = (PSB_FILEOBJ_DESC)ExAllocatePoolWithTag(NonPagedPool, sizeof(SB_FILEOBJ_DESC), SB_MEM_TAG); if (!FileobjDesc) { break; } RtlZeroMemory(FileobjDesc, sizeof(SB_FILEOBJ_DESC)); FileobjDesc->FileObject = Data->Iopb->TargetFileObject; RtlInitEmptyUnicodeString(&(FileobjDesc->OriginalPath), FileobjDesc->OriginalBuff, SB_MAX_NAME_LEN * sizeof(WCHAR)); RtlInitEmptyUnicodeString(&(FileobjDesc->RedirectPath), FileobjDesc->RedirectBuff, SB_MAX_NAME_LEN * sizeof(WCHAR)); RtlUnicodeStringCopy(&(FileobjDesc->OriginalPath), OriginalDirectory); _SbGetRedirectPath(OriginalDirectory, SbVolume, &(FileobjDesc->RedirectPath)); InitializeObjectAttributes(&ObjAttrib, &(FileobjDesc->RedirectPath), OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateFile( &(FileobjDesc->DirectoryHandle), GENERIC_READ, &ObjAttrib, &IoStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0 ); } while (FALSE); if (!NT_SUCCESS(Status)) { if (FileobjDesc) { ExFreePoolWithTag((PVOID)FileobjDesc, SB_MEM_TAG); } } else { _SbRecordFileObject(FileobjDesc); } return Status; } static FLT_POSTOP_CALLBACK_STATUS _SbPostDirectoryControl( IN OUT PFLT_CALLBACK_DATA Data, IN PCFLT_RELATED_OBJECTS FltObjects, IN PVOID CompletionContext, IN FLT_POST_OPERATION_FLAGS Flags ) { FLT_POSTOP_CALLBACK_STATUS FltStatus = FLT_POSTOP_FINISHED_PROCESSING; PFLT_FILE_NAME_INFORMATION NameInfo = NULL; PVOID SafeBuffer = NULL; do { PSB_FILEOBJ_DESC FileobjDesc = NULL; BOOLEAN IsDirectory = FALSE; WCHAR FirstSbVolume = SbFirstSandboxVolume(); if (!FirstSbVolume) { break; } if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass != FileBothDirectoryInformation && Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass != FileIdBothDirectoryInformation ) { break; } if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName && Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName->Length ) { USHORT Index = 0; BOOLEAN ContainsAsterisk = FALSE; for (Index = 0; Index < Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName->Length / 2; ++Index) { if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName->Buffer[Index] == L'*') { ContainsAsterisk = TRUE; break; } } // 没有 * 说明找的非常精确,如就找 C:\ 下的 a.txt ,精确查找时,直接放过 if (!ContainsAsterisk) { break; } } // 如果有映射目录句柄,则说明已经在合并目录,则直接查询定向目录即可 FileobjDesc = _SbGetFileobjDesc(Data->Iopb->TargetFileObject); if (FileobjDesc && FileobjDesc->DirectoryHandle) { KdPrint(("query redirect path\n")); Data->IoStatus.Status = ZwQueryDirectoryFile( FileobjDesc->DirectoryHandle, NULL, NULL, NULL, &Data->IoStatus, Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer, Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length, Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass, FALSE, Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName, FALSE ); break; } if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress != NULL) { SafeBuffer = MmGetSystemAddressForMdlSafe( Data->Iopb->Parameters.DirectoryControl.QueryDirectory.MdlAddress, NormalPagePriority ); } else { SafeBuffer = Data->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer; } if (!SafeBuffer) { break; } if (!NT_SUCCESS(FltGetFileNameInformation( Data, FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT, &NameInfo ))) { break; } KdPrint(("_SbPostDirectoryControl %wZ\n", &NameInfo->Name)); if (STATUS_NO_MORE_FILES == Data->IoStatus.Status) { // 原查询结束了,准备开始定向目录的合并工作 KdPrint(("Original Query finished\n")); if (NT_SUCCESS(_SbPrepareMergeDirectory(Data, FirstSbVolume, &NameInfo->Name))) { // 将状态置为 STATUS_SUCCESS 则系统会继续往下查 Data->IoStatus.Status = STATUS_SUCCESS; // 如果设置为成功,则本次的缓冲区仍会被上层使用,会导致查询结果叠加,应设置本次返回长度为0 // Data->IoStatus.Information = 0; // 经调试设置 Data->IoStatus.Information = 0; 还不行,将文件查询相关结构清零似乎可以 Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length = 0; if (FileBothDirectoryInformation == Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass) { RtlZeroMemory(SafeBuffer, sizeof(FILE_BOTH_DIR_INFORMATION)); } else { RtlZeroMemory(SafeBuffer, sizeof(FILE_ID_BOTH_DIR_INFORMATION)); } } break; } else if (!NT_SUCCESS(Data->IoStatus.Status)) { break; } // 从原来的查询结果中隐藏沙箱中已经有的部分 if (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass == FileBothDirectoryInformation) { _SbProcessFileBothDirectoryInformation( FirstSbVolume, &NameInfo->Name, (PFILE_BOTH_DIR_INFORMATION)SafeBuffer, Data ); } else { _SbProcessFileIdBothDirectoryInformation( FirstSbVolume, &NameInfo->Name, (PFILE_ID_BOTH_DIR_INFORMATION)SafeBuffer, Data ); } } while (FALSE); if (NameInfo) { FltReleaseFileNameInformation(NameInfo); } return FltStatus; } |
|
[原创]自动将一批地址写入静态路由表
求教意义 |
|
|
|
[求助]AFD HOOK的问题
afd部分的主要代码在下面: #include <ntddk.h> #define AFD_RECV 5 #define AFD_RECV_DATAGRAM 6 #define FSCTL_AFD_BASE FILE_DEVICE_NETWORK #define _AFD_CONTROL_CODE(Operation, Method) ((FSCTL_AFD_BASE) << 12 | (Operation << 2) | Method) #define IOCTL_AFD_RECV _AFD_CONTROL_CODE(AFD_RECV, METHOD_NEITHER) #define IOCTL_AFD_RECV_DATAGRAM _AFD_CONTROL_CODE(AFD_RECV_DATAGRAM, METHOD_NEITHER) #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function + 1)] struct AFD_WSABUF { ULONG Length; PCHAR Buff; }; struct AFD_TCP_RECV_INFO { struct AFD_WSABUF* BufferArray; ULONG BuffCount; ULONG AfdFlags; ULONG TdiFlags; }; struct AFD_UDP_RECV_INFO { struct AFD_WSABUF* BufferArray; ULONG BuffCount; ULONG AfdFlags; ULONG TdiFlags; PVOID Address; int* AddressLength; }; typedef NTSTATUS (*PZwDeviceIoControlFile)( IN HANDLE FileHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine, IN PVOID ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength ); typedef struct _ServiceDescriptorTable { PULONG ServiceTableBase; PULONG ServiceCounterTable; ULONG NumberOfServices; ULONG ParamTableBase; } ServiceDescriptorTable, *PServiceDescriptorTable; __declspec(dllimport) ServiceDescriptorTable KeServiceDescriptorTable; static PZwDeviceIoControlFile OldZwDeviceIoControlFile = 0; static ULONG gsOldCR0; static void _SetCR0() { _asm mov eax, cr0 _asm mov gsOldCR0, eax _asm and eax, 0xfffeffff _asm mov cr0, eax _asm cli } static void _ResetCR0() { _asm sti _asm mov eax, gsOldCR0 _asm mov cr0, eax } static NTSTATUS NewZwDeviceIoControlFile( IN HANDLE FileHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine, IN PVOID ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength ) { NTSTATUS Status = OldZwDeviceIoControlFile( FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength ); if (!NT_SUCCESS(Status)) { return Status; } if (IOCTL_AFD_RECV == IoControlCode) { KdPrint(("IOCTL_AFD_RECV Size:%d %d\n", IoStatusBlock->Information, OutputBufferLength )); } else if (IOCTL_AFD_RECV_DATAGRAM == IoControlCode) { KdPrint(("IOCTL_AFD_RECV_DATAGRAM Size:%d %d\n", IoStatusBlock->Information, OutputBufferLength)); } return Status; } NTSTATUS DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath ) { _SetCR0(); OldZwDeviceIoControlFile = (PZwDeviceIoControlFile)(SYSTEMSERVICE(ZwDeviceIoControlFile)); (PZwDeviceIoControlFile)(SYSTEMSERVICE(ZwDeviceIoControlFile)) = NewZwDeviceIoControlFile; _ResetCR0(); return STATUS_SUCCESS; } |
|
[求助]AFD HOOK的问题
udp的大部分是可行的,TCP的总是不行,有人做过吗 |
|
[原创]只能写个贪食蛇的垃圾实力
其实我准备发CSDN汇编区呢,结果一试,CSDN似乎最长支持10000字符,我分开两段,结果还是超过了10000,比较懒,就没往CSDN发了。 |
|
[原创]只能写个贪食蛇的垃圾实力
大哥们,不是我谦虚啊,看雪牛人多啊,我逆向啥的都不行,我就想要个邀请码…… |
|
|
|
[求助]用ollydbg修改软件的标题!高手帮帮忙~!
需要改吗?你自己写几句C代码足矣。 大致是这样: CreateProcess(你说的那个程序); sleep(合适的时间); // 给窗口显示时间 HANDLE hWnd = FindWindow(NULL, 那个窗口的标题); SetWindowText(hWnd, 新标题); 这样的话本进程在创建完目标进程并改它的窗口标题后退出。 你要非用OD改EXE的话,肯定能,拿UE都能改吧…… |
|
[分享]QQ抖动窗口原理,用C语言写的(有源码)
这多不厚道啊…… 我用Java写过许多GUI的代码,抖动,大约是这个样子: public static void shake(Component cp) { int x = cp.getLocation().x; int y = cp.getLocation().y; for (int i = 0; i < 6; i++) { try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } if (i % 2 == 0) { x += 5; y += 5; } else { x -= 5; y -= 5; } cp.setLocation(x, y); } } |
|
[下载]小心有的文件有病菌
太可爱了…… |
|
[分享] 转载 某个论坛管理员总结的几句话,拿出来跟大家分享下
凑贴没关系吧……关键是凑分…… |
|
[原创]发现36O漏洞,可以轻松绕过active启动检查
有这么随便吗? |
|
王爽《汇编语言》课件2版[下载]
这种随处可得的教程,是挣不到钱滴 |
|
[原创]通俗解析IRP和I/O设备栈在内核程序中的作用
厉害,这个完全不懂。 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值