开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 211|回复: 0
收起左侧

[技术专题] windows内核驱动文件保护原理和代码

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式   河北省石家庄市

在 Windows 操作系统中,要实现真正的文件保护,使其不被其他高权限程序(如管理员权限的程序或恶意软件)修改或删除,必须在内核态(Kernel Mode)进行。这是因为内核是操作系统的核心,拥有最高的权限,可以拦截和控制所有用户态(User Mode)的I/O操作。

Windows内核驱动文件保护的核心原理是利用**文件系统过滤驱动(File System Filter Driver)**技术。


Windows 内核文件保护原理

文件系统过滤驱动,顾名思义,就是位于文件系统和磁盘驱动器之间的一层软件。它的作用就像一个“守门员”,可以拦截所有对文件系统发起的I/O请求,并根据其自定义的规则来决定是放行、修改请求还是直接拒绝。

具体来说,一个文件保护驱动通常会执行以下步骤:

  1. 注册为过滤器:驱动程序通过 Windows 的 Filter Manager 框架,将自己注册为一个文件系统过滤驱动。
  2. 拦截 I/O 请求:一旦注册成功,操作系统会将所有经过文件系统的 I/O 请求包(IRP - I/O Request Packet)发送给该驱动。常见的请求类型包括:
    • IRP_MJ_CREATE:创建或打开文件。
    • IRP_MJ_WRITE:写入文件。
    • IRP_MJ_SET_INFORMATION:设置文件信息,如修改文件名、删除文件等。
    • IRP_MJ_CLEANUP:关闭文件句柄,如果文件被标记为删除,在此阶段会执行删除操作。
  3. 判断与决策:在拦截到请求后,驱动会根据其内部设定的保护策略进行判断。例如:
    • 判断文件路径:检查请求操作的文件路径是否在保护列表中。
    • 判断操作类型:检查请求是写入、删除还是修改。
    • 判断发起进程:检查发起此操作的进程ID,以区分哪些是受信任的进程(如杀毒软件自身),哪些是非法的。
  4. 执行操作:根据判断结果,驱动会采取相应的行动:
    • 放行:如果操作是合法的,驱动会将请求传递给下一个更底层的驱动。
    • 拒绝:如果操作是不合法的,驱动会直接返回一个错误状态(如 STATUS_ACCESS_DENIED),从而阻止该操作的发生。
    • 修改请求:驱动甚至可以修改I/O请求的内容,例如在文件写入时进行加密,或者在读取时进行解密。

通过这种机制,一个内核驱动能够从根本上阻止任何用户态程序对受保护文件的非法操作,即使是管理员权限也无法绕过,因为驱动本身运行在更高的权限级别。


示例代码:一个简单的文件保护过滤器驱动

下面的代码是一个简化的文件系统**迷你过滤驱动(Minifilter Driver)**示例。该驱动旨在保护一个特定的文件不被删除。

注意:

  • 这只是一个概念性代码,用于演示原理。一个完整的驱动程序需要处理更多的I/O请求、错误处理和内存管理。
  • 编写和运行内核驱动程序是高风险行为,任何错误都可能导致系统崩溃(蓝屏)。
  • 驱动需要进行数字签名才能在 Windows 系统上运行。

1. 驱动入口和卸载函数

DriverEntry 是驱动的入口点,负责注册过滤器和设置回调函数。DriverUnload 负责卸载和清理。

// 包含必要的头文件
#include <fltKernel.h>

// 全局变量
PFLT_FILTER g_FilterHandle = NULL;
UNICODE_STRING g_ProtectedFileName = RTL_CONSTANT_STRING(L"\\??\\C:\\protected_file.txt");

// 驱动卸载回调
VOID
FilterUnload(
    _In_ FLT_FILTER_UNLOAD_FLAGS Flags
    )
{
    UNREFERENCED_PARAMETER(Flags);
    FltUnregisterFilter(g_FilterHandle);
    DbgPrint("File protector driver unloaded.\n");
}

// 驱动入口函数
NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status;

    // 注册过滤器
    status = FltRegisterFilter(
        DriverObject,
        &g_Registration, // 这是下面定义的注册信息
        &g_FilterHandle
    );

    if (NT_SUCCESS(status))
    {
        // 开始过滤
        status = FltStartFiltering(g_FilterHandle);
        if (!NT_SUCCESS(status))
        {
            FltUnregisterFilter(g_FilterHandle);
        }
    }

    DbgPrint("File protector driver loaded.\n");
    return status;
}

2. 回调函数

这是核心逻辑所在,用于在I/O操作发生前后进行处理。

// Pre-Operation Callback:在I/O操作开始前调用
FLT_PREOP_CALLBACK_STATUS
PreOperationCallback(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
    )
{
    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);

    PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
    NTSTATUS status;

    // 检查是否是删除操作
    if (Data->Iopb->MajorFunction == IRP_MJ_CREATE)
    {
        // 检查请求是否包含删除意图
        if (FlagOn(Data->Iopb->Parameters.Create.Options, FILE_DELETE_ON_CLOSE))
        {
            // 获取文件名信息
            status = FltGetFileNameInformation(Data,
                                               FLT_FILE_NAME_NORMALIZED |
                                               FLT_FILE_NAME_QUERY_DEFAULT,
                                               &nameInfo);

            if (NT_SUCCESS(status) && nameInfo != NULL)
            {
                // 检查文件名是否匹配受保护文件
                if (RtlCompareUnicodeString(&nameInfo->Name, &g_ProtectedFileName, TRUE) == 0)
                {
                    DbgPrint("Blocking delete request for protected file.\n");

                    // 阻止删除操作,返回“拒绝访问”状态
                    Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                    Data->IoStatus.Information = 0;

                    FltReleaseFileNameInformation(nameInfo);
                    return FLT_PREOP_COMPLETE; // 终止此I/O请求
                }
                FltReleaseFileNameInformation(nameInfo);
            }
        }
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

3. 注册信息

DriverEntry 中,我们需要一个结构体来告诉 Filter Manager 如何调用我们的回调函数。

const FLT_OPERATION_REGISTRATION Callbacks[] =
{
    // 在创建/打开文件操作前,调用我们的回调
    { IRP_MJ_CREATE, 0, PreOperationCallback, NULL },
    // 这里可以添加更多回调,例如对写入或重命名进行拦截
    { IRP_MJ_OPERATION_END }
};

const FLT_REGISTRATION g_Registration =
{
    sizeof(FLT_REGISTRATION),
    FLT_REGISTRATION_VERSION,
    0,
    NULL,
    Callbacks,
    FilterUnload,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备2025452707号) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表