编写驱动拦截NT的API实现隐藏文件目录

2024-03-05 03:08

本文主要是介绍编写驱动拦截NT的API实现隐藏文件目录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原作者姓名 desert studio

介绍
这几天看了lornwolf兄写的拦截ZwQuerySystemInformation来隐藏进程的文章,还有sinister的“隐藏 任意进程 目录 文件 注册表 端口“这篇文章。发现sinister的根本编译不了,于是我梢加修改了一下,其他的如隐藏注册表键值,拦截删除注册表,拦截删除文件等等都可以类似实现!


读者评分 4 评分次数 2 

正文
目前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)上测试通过!
具体程序体请看lornwolf写的skykernel.c,这里不再列出!下载地址:
http://lornwolf.8u8.com/software/LornWolf.zip 
申明:
本代码不提高任何担保和技术支持,只供做简单驱动编写练习用!如有使用本代码造成任何后果一概与作者无关!
正文完

这篇关于编写驱动拦截NT的API实现隐藏文件目录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775144

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin