驱动编程学习五 阻止特定进程创建

添加新建项   阻止特定进程创建.c   添加代码

VS设置:“项目-属性-链接器-命令行”位置添加 /INTEGRITYCHECK 即可,不然注册回调的时候会失败
#pragma once
#include <ntifs.h>

#define  计算器  L"\\??\\C:\\Windows\\system32\\calc.exe"      //要阻止创建的进程名
 //https://www.freesion.com/article/3275906661/
//VS设置:“项目-属性-链接器-命令行”位置添加 /INTEGRITYCHECK 即可,不然注册回调的时候会失败
//参考::https://xiaodaozhi.com/kernel/18.html

static VOID CallBack_NotifyProcessEx(PEPROCESS Process,//指向表示进程的 EPROCESS 结构的指针
    HANDLE ProcessId,//进程的进程 ID
    PPS_CREATE_NOTIFY_INFO CreateInfo)//指向包含有关新进程的信息的 PS_CREATE_NOTIFY_INFO 结构的指针
{
    if (CreateInfo)//退出时一般为NULL 
    {
        DbgPrint("jw:进程ID- %lld,父进程ID-%lld",
            CreateInfo->CreatingThreadId.UniqueProcess,
            CreateInfo->ParentProcessId);

        DbgPrint("jw:ImageFilelame =%wZ----", CreateInfo->ImageFileName);
        DbgPrint("jw:ComsandLine = %wZ", CreateInfo->CommandLine);

        WCHAR szfileName[255] = { 'A',};
        DbgPrint("jw:ImageFileName->Buffer = %ws Length =%d ---AAA",
            CreateInfo->ImageFileName->Buffer,
            CreateInfo->ImageFileName->Length);
        UINT32 Len = CreateInfo->ImageFileName->Length;
        memcpy_s(szfileName, 255, CreateInfo->ImageFileName->Buffer, Len);

        WCHAR *pwStr = wcsstr(szfileName, L"calc.exe");//计算器  wcsstr 字串写信 比较
        DbgPrint("jw:szfileName =%ws  sub = %ws  pwStr = %p", szfileName, L"calc.exe", pwStr);

        if (pwStr)
        {
            DbgPrint("jw:阻止运行 %wZ ", CreateInfo->ImageFileName);
            //STATUS_UNSUCCESSFUL  连接到系统上的设备没有发挥作用
            CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;//返回给用户层的状态
        }
    }
};


VOID CreateProcessNotifyEx(PEPROCESS  Process,HANDLE  ProcessId,PPS_CREATE_NOTIFY_INFO  CreateInfo)
{//https://www.cnblogs.com/iBinary/p/8399312.html
    KdPrint(("jw: 进入:CreateProcessNotifyEx\r\n"));
    UNICODE_STRING ustrCalc;//定义内核函数字符串
    RtlInitUnicodeString(&ustrCalc, L"\\??\\C:\\Windows\\system32\\calc.exe");//初始化计算器名字. 注意,这个要带上符号连接.  
    if (CreateInfo != NULL)//参数有可能为NULL
    {
        KdPrint(("jw: Create Porcess pid=%d ImageFileName=%wZ\r\n",
            ProcessId,
            CreateInfo->ImageFileName));

        if (RtlCompareUnicodeString(CreateInfo->ImageFileName, &ustrCalc, TRUE) == 0) //比较字符串.如果成功
        {//阻止创建
            CreateInfo->CreationStatus = STATUS_UNSUCCESSFUL; //标志给失败,则计算器不能运行.
        }
    }
    else
        KdPrint(("jw: Exit Porcess pid=%d\r\n", ProcessId));
}


void 安装监控进程的回调EX()
{
    NTSTATUS st = PsSetCreateProcessNotifyRoutineEx(CallBack_NotifyProcessEx, FALSE);
    if (st == STATUS_SUCCESS)
    {
        DbgPrint("jw:安装回调成功");
    }
    else { DbgPrint("jw:安装回调失败 st = %llX", st); }
}

void 移出监控进程的回调Ex()
{
    NTSTATUS st = PsSetCreateProcessNotifyRoutineEx(CallBack_NotifyProcessEx, TRUE);
}

在 监控进程.h  头文件中添加 声明

#pragma once
//#include <ntifs.h>

void 安装进程监控();  //通过DriverEntry  或者 DeviceIoControl  来安装
void 卸载进程监控();  //通过DriverUnload

const char*  通过进程ID获取进程名(HANDLE pid);

void 安装监控进程的回调EX();
void 移出监控进程的回调Ex();

在 驱动入口函数中调用 

//驱动入口点函数
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING szReg)
{
    KdPrint(("jw:我的第一个驱动,最简单的驱动+++++++++"));
    KdPrint(("jw:注册路径 = %wZ", szReg));//szReg注册表的路径
    driver->DriverUnload = Unload;//注册卸载例程
    //irp处理
    driver->MajorFunction[IRP_MJ_CREATE] = IRP_PROC;
    driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IRP_PROC;
    driver->MajorFunction[IRP_MJ_CLOSE] = IRP_PROC;

    //调用创建驱动设备函数 CreateDevice
    CreateDevice(driver);//创建驱动设备
    //安装进程监控();//调用
    安装监控进程的回调EX();
    return STATUS_SUCCESS;
};//最小的驱动  只有一行代码。

在 驱动卸载函数  中移除

//卸载驱动
void Unload(PDRIVER_OBJECT driver)
{//因为参数driver没有使用,会出现警告。
    KdPrint(("jw:进入卸载例程"));
    //卸载进程监控();
     移出监控进程的回调Ex();//一定要在删除设备前 先删除符号链接
    UNICODE_STRING uzMyLinsName;    //符号链接名字
    RtlInitUnicodeString(&uzMyLinsName, 符号链接名字);//初始化字符串
    IoDeleteSymbolicLink(&uzMyLinsName);
    
    IoDeleteDevice(driver->DeviceObject);//删除设备对象
    KdPrint(("jw:2进入卸载例程"));
}

 

posted on 2022-11-22 11:09  悠心不已  阅读(103)  评论(0)    收藏  举报

导航