编写驱动拦截NT的API实现隐藏文件目录(代码)
2013-08-08 14:14
573 查看
转载地址:http://www.cnblogs.com/qiuyi21/articles/1151923.html
pudn上的这个源代码可以使用:http://www.pudn.com/downloads79/sourcecode/windows/vxd/detail305108.html
驱动已经使用WDK编译好了,直接安装就可以,安装好后,用VS2010,或者VS2008编译Test项目,就可以隐藏文件了,不需要改动,代码也很规范,可以好好学习。
网上流传的一篇文章《编写驱动拦截NT的API实现隐藏文件目录》,当时我在网上搜索内核级Hook资料时搜索到的,因为自己对驱动程序还是初初接触,所有想按照这篇文章自己弄个简单的驱动出来,测试测试~~~但由于网上流传的这篇文章都丢失了原作者和原出处,有些代码似乎是错的,但自己又不熟悉,难免弄错。参考了其它使用驱动程序Hook的例子(都是Windows 2000 DDK的),最终编译了一个驱动出来,马上安装进自己的系统里(Windows XP Professional SP2),执行[net start "驱动名"],噢,系统立即蓝屏挂掉了!!经过一段时间的驱动程序编写研究,终于写成功拦截NT的API实现隐藏文件目录了,也知道了一点就是Windows
XP之后的操作系统的SSDT都已经写保护,Hook SSDT时不可以直接改写SSDT。我的代码如下,由于水平有限,难免会有错误,请多多指教。
C 语言代码,用WDK编译
pudn上的这个源代码可以使用:http://www.pudn.com/downloads79/sourcecode/windows/vxd/detail305108.html
驱动已经使用WDK编译好了,直接安装就可以,安装好后,用VS2010,或者VS2008编译Test项目,就可以隐藏文件了,不需要改动,代码也很规范,可以好好学习。
网上流传的一篇文章《编写驱动拦截NT的API实现隐藏文件目录》,当时我在网上搜索内核级Hook资料时搜索到的,因为自己对驱动程序还是初初接触,所有想按照这篇文章自己弄个简单的驱动出来,测试测试~~~但由于网上流传的这篇文章都丢失了原作者和原出处,有些代码似乎是错的,但自己又不熟悉,难免弄错。参考了其它使用驱动程序Hook的例子(都是Windows 2000 DDK的),最终编译了一个驱动出来,马上安装进自己的系统里(Windows XP Professional SP2),执行[net start "驱动名"],噢,系统立即蓝屏挂掉了!!经过一段时间的驱动程序编写研究,终于写成功拦截NT的API实现隐藏文件目录了,也知道了一点就是Windows
XP之后的操作系统的SSDT都已经写保护,Hook SSDT时不可以直接改写SSDT。我的代码如下,由于水平有限,难免会有错误,请多多指教。
C 语言代码,用WDK编译
#include <ntddk.h> #define FILE_DEVICE_NTHIDEFILES 0x8000 #define NTHIDEFILES_IOCTL_BASE 0x800 #define CTL_CODE_NTHIDEFILES(i) CTL_CODE(FILE_DEVICE_NTHIDEFILES, NTHIDEFILES_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NTHIDEFILES_HELLO CTL_CODE_NTHIDEFILES(0) #define NTHIDEFILES_DEVICE_NAME L"\\Device\\NtHideFiles" #define NTHIDEFILES_DOS_DEVICE_NAME L"\\DosDevices\\NtHideFiles" #define dprintf if (DBG) DbgPrint #define nprintf DbgPrint typedef struct _DEVICE_EXTENSION { ULONG StateVariable; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; typedef struct _FILE_BOTH_DIR_INFORMATION { ULONG NextEntryOffset; ULONG FileIndex; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; LARGE_INTEGER EndOfFile; LARGE_INTEGER AllocationSize; ULONG FileAttributes; ULONG FileNameLength; ULONG EaSize; CCHAR ShortNameLength; WCHAR ShortName[12]; WCHAR FileName[1]; } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; #pragma pack(1) typedef struct _SERVICE_DESCRIPTOR_ENTRY { unsigned int * ServiceTableBase; unsigned int * ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char * ParamTableBase; } SERVICE_DESCRIPTOR_ENTRY, *PSERVICE_DESCRIPTOR_ENTRY; #pragma pack() // ZwQueryDirectoryFile 的原型 typedef NTSTATUS (NTAPI *PFN_ZwQueryDirectoryFile)( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery); NTSYSAPI NTSTATUS NTAPI ZwQueryDirectoryFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery); NTSTATUS HookZwQueryDirectoryFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery); __declspec(dllimport) SERVICE_DESCRIPTOR_ENTRY KeServiceDescriptorTable; // 保存原 ZwQueryDirectoryFile 函数指针 PFN_ZwQueryDirectoryFile OriginalZwQueryDirectoryFile = NULL; PMDL g_pmdlSystemCall = NULL; PVOID *MappedSystemCallTable = NULL; BOOLEAN g_bHooked = FALSE; #define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function + 1) #define SYSTEMSERVICE(_Function) KeServiceDescriptorTable.ServiceTableBase[SYSCALL_INDEX(_Function)] #define HOOK_SYSCALL(_Function, _Hook, _Orig) _Orig = (PVOID)InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Hook) #define UNHOOK_SYSCALL(_Function, _Orig) InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Orig) NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID DriverUnload(IN PDRIVER_OBJECT DriverObject); PCWSTR GetProcessFullName(); #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, DispatchCreate) #pragma alloc_text(PAGE, DispatchClose) #pragma alloc_text(PAGE, DispatchDeviceControl) #pragma alloc_text(PAGE, DriverUnload) #endif // ALLOC_PRAGMA #define BASE_PROCESS_PEB_OFFSET 0x1B0 #define BASE_PEB_PROCESS_PARAMETER_OFFSET 0x010 #define BASE_PROCESS_PARAMETER_FULL_IMAGE_NAME 0x03C #define W2003_BASE_PROCESS_PEB_OFFSET 0x190 #define W2003_BASE_PROCESS_PEB_OFFSET_SP1 0x1A0 #define W2003_BASE_PROCESS_PEB_OFFSET_SP2 W2003_BASE_PROCESS_PEB_OFFSET_SP1 #define VISTA_BASE_PROCESS_PEB_OFFSET 0x188 PCWSTR GetProcessFullName() { NTSTATUS status = -1; ULONG dwAddress = 0; PCWSTR lpszTemp = NULL; RTL_OSVERSIONINFOEXW osVerInfo; dwAddress = (ULONG)PsGetCurrentProcess(); if (dwAddress == 0 || dwAddress == (ULONG)-1) return NULL; RtlZeroMemory(&osVerInfo, sizeof(RTL_OSVERSIONINFOEXW)); osVerInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); status = RtlGetVersion((PRTL_OSVERSIONINFOW)&osVerInfo); if (!NT_SUCCESS(status)) return NULL; // 目前只支持 Windows 2000/XP/2003/Vista if (osVerInfo.dwMajorVersion < 5 || osVerInfo.dwMinorVersion > 2) return NULL; // 取得PEB,不同平台的位置是不同的 if (osVerInfo.dwMajorVersion == 5) { if (osVerInfo.dwMinorVersion < 2) // 2000 0X0500 XP 0X0501 { dwAddress += BASE_PROCESS_PEB_OFFSET; } else if (osVerInfo.dwMinorVersion == 2) // 2003 0X0502 { if (osVerInfo.wServicePackMajor == 0) // No Service Pack dwAddress += W2003_BASE_PROCESS_PEB_OFFSET; else if (osVerInfo.wServicePackMajor < 3) // Service Pack 1 & 2 dwAddress += W2003_BASE_PROCESS_PEB_OFFSET_SP1; } } else // Vista 0X0600 { dwAddress += VISTA_BASE_PROCESS_PEB_OFFSET; } if ((dwAddress = *(PULONG)dwAddress) == 0) return NULL; // 通过PEB取得RTL_USER_PROCESS_PARAMETERS dwAddress += BASE_PEB_PROCESS_PARAMETER_OFFSET; if ((dwAddress = *(PULONG)dwAddress) == 0) return NULL; // 在RTL_USER_PROCESS_PARAMETERS->ImagePathName保存了路径,偏移为0x038 dwAddress += BASE_PROCESS_PARAMETER_FULL_IMAGE_NAME; if ((dwAddress = *(PULONG)dwAddress) == 0) return NULL; // [10/14/2006] lpszTemp = (PCWSTR)dwAddress; if (wcslen(lpszTemp) > 4) { if (lpszTemp[0] == L'\\' && (lpszTemp[1] == L'?' || lpszTemp[1] == L'\\') && lpszTemp[2] == L'?' && lpszTemp[3] == L'\\') { dwAddress += 4 * sizeof(WCHAR); } } return (PCWSTR)dwAddress; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ntDeviceName; UNICODE_STRING dosDeviceName; PDEVICE_OBJECT deviceObject = NULL; BOOLEAN fSymbolicLink = FALSE; dprintf("[NtHideFiles] DriverEntry: %wZ\n", RegistryPath); RtlInitUnicodeString(&ntDeviceName, NTHIDEFILES_DEVICE_NAME); status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), // DeviceExtensionSize &ntDeviceName, // DeviceName FILE_DEVICE_NTHIDEFILES, // DeviceType 0, // DeviceCharacteristics TRUE, // Exclusive &deviceObject // [OUT] ); if (!NT_SUCCESS(status)) goto __failed; RtlInitUnicodeString(&dosDeviceName, NTHIDEFILES_DOS_DEVICE_NAME); status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName); if (!NT_SUCCESS(status)) goto __failed; fSymbolicLink = TRUE; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; DriverObject->DriverUnload = DriverUnload; // Map the memory into our domain to change the permissions on the MDL g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices * 4, FALSE, FALSE, NULL); if (g_pmdlSystemCall == NULL) { status = STATUS_UNSUCCESSFUL; goto __failed; } MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // Change the flags of the MDL g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); // HOOK ZwQueryDirectoryFile 并保存原 ZwQueryDirectoryFile 函数地址 HOOK_SYSCALL(ZwQueryDirectoryFile, HookZwQueryDirectoryFile, OriginalZwQueryDirectoryFile); g_bHooked = TRUE; if (NT_SUCCESS(status)) return status; __failed: if (fSymbolicLink) IoDeleteSymbolicLink(&dosDeviceName); if (deviceObject) IoDeleteDevice(deviceObject); return status; } NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION irpStack; PVOID ioBuf; ULONG inBufLength, outBufLength; ULONG ioControlCode; irpStack = IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Information = 0; // // Get the pointer to the input/output buffer and it's length // ioBuf = Irp->AssociatedIrp.SystemBuffer; inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; switch (ioControlCode) { case IOCTL_NTHIDEFILES_HELLO: break; default: status = STATUS_INVALID_PARAMETER; break; } // // DON'T get cute and try to use the status field of // the irp in the return status. That IRP IS GONE as // soon as you call IoCompleteRequest. // Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // // We never have pending operation so always return the status code. // return status; } VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING dosDeviceName; // UnHook ZwQueryDirectoryFile if (g_bHooked && OriginalZwQueryDirectoryFile != NULL) UNHOOK_SYSCALL(ZwQueryDirectoryFile, OriginalZwQueryDirectoryFile); if (g_pmdlSystemCall != NULL) { MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall); IoFreeMdl(g_pmdlSystemCall); } // // Delete the symbolic link // RtlInitUnicodeString(&dosDeviceName, NTHIDEFILES_DOS_DEVICE_NAME); IoDeleteSymbolicLink(&dosDeviceName); // // Delete the device object // IoDeleteDevice(DriverObject->DeviceObject); dprintf("[NtHideFiles] unloaded\n"); } NTSTATUS HookZwQueryDirectoryFile( IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass, IN BOOLEAN bReturnOnlyOneEntry, IN PUNICODE_STRING PathMask OPTIONAL, IN BOOLEAN bRestartQuery) { NTSTATUS rc = STATUS_SUCCESS; ANSI_STRING ansiFileName, ansiDirName, HideDirFile; UNICODE_STRING uniFileName; PCWSTR pProcPath = NULL; // 初始化要过虑的文件名,大写形式 RtlInitAnsiString(&HideDirFile, "WAR3.EXE"); pProcPath = GetProcessFullName(); DbgPrint("[NtHideFiles] GetProcessFullName: %ws\n", pProcPath == NULL ? L"<null>" : pProcPath); // 执行真正的 ZwQueryDirectoryFile 函数 rc = OriginalZwQueryDirectoryFile( hFile, hEvent, IoApcRoutine, IoApcContext, pIoStatusBlock, FileInformationBuffer, FileInformationBufferLength, FileInfoClass, bReturnOnlyOneEntry, PathMask, bRestartQuery); // 如果执行成功,而且 FILE_INFORMATION_CLASS 的值为 FileBothDirectoryInformation,我们就进行处理,过滤 if (NT_SUCCESS(rc) && FileInfoClass == FileBothDirectoryInformation) { // 把执行结果赋给 pFileInfo PFILE_BOTH_DIR_INFORMATION pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer; PFILE_BOTH_DIR_INFORMATION pLastFileInfo = NULL; BOOLEAN bLastOne = FALSE; // 循环检查 do { bLastOne = !pFileInfo->NextEntryOffset; RtlInitUnicodeString(&uniFileName, pFileInfo->FileName); RtlUnicodeStringToAnsiString(&ansiFileName, &uniFileName, TRUE); RtlUnicodeStringToAnsiString(&ansiDirName, &uniFileName, TRUE); RtlUpperString(&ansiFileName, &ansiDirName); // 打印结果,用 debugview 可以查看打印结果 //dprintf("ansiFileName :%s\n", ansiFileName.Buffer); //dprintf("HideDirFile :%s\n", HideDirFile.Buffer); // 开始进行比较,如果找到了就隐藏这个文件或者目录 if (RtlCompareMemory(ansiFileName.Buffer, HideDirFile.Buffer, HideDirFile.Length) == HideDirFile.Length) { dprintf("This is HideDirFile!\n"); if (bLastOne) { if (pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer) rc = STATUS_NO_MORE_FILES; // 隐藏文件或者目录; else pLastFileInfo->NextEntryOffset = 0; break; } else // 指针往后移动 { int iPos = (ULONG)pFileInfo - (ULONG)FileInformationBuffer; int iLeft = (ULONG)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset; RtlCopyMemory((PVOID)pFileInfo, (PVOID)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset), (ULONG)iLeft); continue; } } pLastFileInfo = pFileInfo; pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset); } while (!bLastOne); RtlFreeAnsiString(&ansiDirName); RtlFreeAnsiString(&ansiFileName); } return rc; }
相关文章推荐
- 编写驱动拦截NT的API实现隐藏文件目录
- 【】编写驱动拦截NT的API实现隐藏文件目录
- 编写驱动拦截NT的API实现隐藏文件目录
- 编写驱动拦截NT的API实现隐藏文件目录
- 编写驱动拦截NT的API实现隐藏文件目录
- 驱动拦截NT的API实现隐藏木马客户端
- 驱动拦截NT的API实现隐藏木马客户端
- 自定义实现InputFormat、OutputFormat、输出到多个文件目录中去、hadoop1.x api写单词计数的例子、运行时接收命令行参数,代码例子
- 2003年的代码-隐藏任意文件/目录-禁止访问任意文件/目录-隐藏任意注册表子键-禁止访问任意注册表子键-隐藏任意进程[NT系列]-自启动任意进程[95系列]-自定义可信赖进程(可以访问被保护的文件/目录,和/或者子键),并采用CRC32校验
- 市面上所有号称"虚拟机","防火墙"的实时监控杀毒软件无一不是使用的IFSHOOK技术.但是同时也有一些朋友不断写MAIL给我打听如何实现读写的监控.下面给出用VTOOLSD写的代码.也就是所有实时杀毒软件的奥秘.同时,很多拦截文件操作的软件,例如对目录加
- 认证鉴权与API权限控制在微服务架构中的设计与实现 参考文件目录
- 使用WDM驱动实现在NT下读取物理端口,特殊寄存器,物理内存的代码(C++驱动加载代码)
- php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
- 代码实现拷贝Ecplise Plugin源码工程的文件(目录)到运行时目录
- 文件过滤驱动实现目录重定向(二)
- php 删除目录下N分钟前创建的所有文件的实现代码
- 使用WDM驱动实现在NT下读取物理端口,特殊寄存器,物理内存的代码(C++驱动加载代码) .
- php实现文件上传-从php配置到代码编写
- 用JSP实现类似资源管理器式的文件与目录的折叠(代码示例)
- 文件过滤驱动实现目录重定向(三)