驱动编程学习五 阻止特定进程创建
添加新建项 阻止特定进程创建.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进入卸载例程")); }
浙公网安备 33010602011771号