驱动编程学习四 通过进程ID获取进程名 将进程监控添加到 数据分发 函数中
在 监控进程 类 中添加 代码
监控进程.h 头文件中
#pragma once //#include <ntifs.h> void 安装进程监控(); //通过DriverEntry 或者 DeviceIoControl 来安装 void 卸载进程监控(); //通过DriverUnload const char* 通过进程ID获取进程名(HANDLE pid);
监控进程.cpp 实现文件中
#pragma once #include <ntifs.h> #include "监控进程.h" //https://www.cnblogs.com/iBinary/p/8399312.html //PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine); //PsSetCreateProcessNotifyRoutineEx(); NTSTATUS PsSetCreateProcessNotifyRoutine( PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,//这是一个回调函数指针 BOOLEAN );//安装为假,卸载时为真。 //PCREATE_PROCESS_NOTIFY_ROUTINE PcreateProcessNotifyRoutine; VOID NotifyRoutine( HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create)//回调函数 { char* p1 = 通过进程ID获取进程名(ParentId); char* p2 = 通过进程ID获取进程名(ProcessId); if (Create) { KdPrint(("jw:(%s)ParentId = %d (%s)ProcessId = %d 进程创建 \r\n",p1, ParentId, p2,ProcessId)); } else { KdPrint(("jw:(%s)ParentId = %d (%s)ProcessId = %d 进程退出 \r\n",p1, ParentId,p2, ProcessId)); } } void 安装进程监控() { PsSetCreateProcessNotifyRoutine(NotifyRoutine, FALSE); } void 卸载进程监控() { PsSetCreateProcessNotifyRoutine(NotifyRoutine, TRUE); } NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process); const char * 通过进程ID获取进程名(HANDLE pid) { PEPROCESS Process = NULL; //例程接受进程的进程 ID,并返回指向进程的 EPROCESS 结构的引用指针 NTSTATUS status = PsLookupProcessByProcessId(pid,//指定进程的进程 ID。 &Process);//返回指向 由 ProcessId 指定的进程的 EPROCESS 结构的引用指针 return PsGetProcessImageFileName(Process); }
在 驱动入口 函数 页中 修改 分发 函数 代码 驱动入口函数中删除 安装进程监控 的调用 在卸载驱动中 移除 卸载进程监控 的调用
将 进程监控 添加到 分发代码 中
//#include <ntddk.h>//这2个只要一个就可以了。 #include <ntifs.h> #include "监控进程.h" #define 符号链接名字 L"\\??\\mylinkName" //这个是用户层访问的CreateFile #define 驱动设备名字 L"\\DEVICE\uzDriverName001" //这是内核访问的NtCreateFile //创建驱动设备对象 NTSTATUS CreateDevice(PDRIVER_OBJECT driver) { NTSTATUS status; UNICODE_STRING uzDriverName;//char*wchar* PDEVICE_OBJECT device = NULL; //这是一个指针 RtlInitUnicodeString(&uzDriverName, 驱动设备名字);//strcpy//ucscpy,初始化字符串对象 KdPrint(("jw:未创建设备前:driver->DeviceObject=%p, device=%p \r\n", driver->DeviceObject, device)); status = IoCreateDevice(driver, 4,//sizeof(DEVICE_EXTENSION),自己定义的结构的大小 &uzDriverName, // 设备名字 FILE_DEVICE_UNKNOWN,//设备的类型 FILE_DEVICE_SECURE_OPEN,////独占的话设置为TRUE,非独占设置为FALSE FALSE, &device);//device 返回设备对象 if (status == STATUS_SUCCESS) { KdPrint(("jw:驱动设备对象创建成功,ok \n")); //创建设备对象之后就可以为驱动对象绑定符号链接,就是为设备创建一个别名 UNICODE_STRING uzMyLinsName; //符号链接名字 RtlInitUnicodeString(&uzMyLinsName, 符号链接名字);//初始化字符串 status = IoCreateSymbolicLink(&uzMyLinsName, &uzDriverName); if (status == STATUS_SUCCESS) { KdPrint(("jw:创建符号链接 符号链接名= %wZ 成功\r\n", &uzMyLinsName)); }else{ IoDeleteSymbolicLink(&uzMyLinsName);//删除符号链接 KdPrint(("jw:创建符号链接失败 错误代码=%X \r\n", status));//错误就是状态码 } } else { KdPrint(("jw:驱动设备对象创建失败,删除设备 \n")); IoDeleteDevice(device); } KdPrint(("jw:创建设备之后:driver->DeviceObject=%p, device=%p \r\n", driver->DeviceObject, device)); return status; } //访问驱动设备及IRP事件处理 //https://learn.microsoft.com/zh-cn/windows-hardware/drivers/kernel/irp-major-function-codes #define IO_STRING CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803,METHOD_BUFFERED,FILE_ANY_ACCESS) //控制码测试 #define IO_进程监控安装 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806,METHOD_BUFFERED,FILE_ANY_ACCESS) //控制码测试 #define IO_进程监控卸载 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807,METHOD_BUFFERED,FILE_ANY_ACCESS) //控制码测试 NTSTATUS IRP_PROC(PDEVICE_OBJECT device, PIRP pirp)//irp回调函数 {//常用的三个处理 KdPrint(("jw:进入派遣函数")); PIO_STACK_LOCATION irpStack; ULONG CtlCode; ULONG InputBuffLength; irpStack = IoGetCurrentIrpStackLocation(pirp);//获取应用层传来的消息 switch (irpStack->MajorFunction) {//分发消息 case IRP_MJ_DEVICE_CONTROL: //DeviceIoControl { ULONG IoCode = irpStack->Parameters.DeviceIoControl.IoControlCode; switch (IoCode) {//利用控制码分发 case IO_进程监控安装: { 安装进程监控(); KdPrint(("jw:SYS IO_进程监控安装 =%X \r\n", IoCode)); break; }; case IO_进程监控卸载: { 卸载进程监控(); KdPrint(("jw:SYS IO_进程监控卸载 =%X \r\n", IoCode)); break; }; case IO_STRING: { //这里取出用户层传递过来的缓冲区的数据 char *pInbuf = (char *)pirp->AssociatedIrp.SystemBuffer; //取出缓冲区大小 KdPrint(("jw:pInbuf = %s \r\n", pInbuf)); KdPrint(("jw:用户层调用了 DeviceIoControl")); //返回数据给缓冲区 strcpy(pInbuf, "这个数据是驱动返回给用户层的。\r\n"); } default: break; } //case irpStack->Parameters.DeviceIoControl.IoControlCode: // pirp->IoStatus.Status = STATUS_SUCCESS; pirp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength; //返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned IoCompleteRequest(pirp, IO_NO_INCREMENT); //调用方已完成所有I/O请求处理操作 并且不增加优先级 break; } case IRP_MJ_CREATE: //CreateFile { KdPrint(("jw:用户层调用了 CreateFile ")); break; } case IRP_MJ_CLOSE: //CloseHandle { KdPrint(("jw:用户层调用了 CloseHandle")); } } KdPrint(("jw:离开派遣函数 \r\n")); return STATUS_SUCCESS; }; //卸载驱动 void Unload(PDRIVER_OBJECT driver) {//因为参数driver没有使用,会出现警告。 //卸载进程监控(); //一定要在删除设备前 先删除符号链接 UNICODE_STRING uzMyLinsName; //符号链接名字 RtlInitUnicodeString(&uzMyLinsName, 符号链接名字);//初始化字符串 IoDeleteSymbolicLink(&uzMyLinsName); //删除设备对象 IoDeleteDevice(driver->DeviceObject); KdPrint(("jw:进入卸载例程")); } //驱动入口点函数 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);//创建驱动设备 //安装进程监控();//调用 return STATUS_SUCCESS; };//最小的驱动 只有一行代码。
在 驱动用户层访问 中修改代码 添加2个按钮 安装进程监控 和 移除进程监控

#define IO_进程监控安装 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806,METHOD_BUFFERED,FILE_ANY_ACCESS) //控制码测试 #define IO_进程监控卸载 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807,METHOD_BUFFERED,FILE_ANY_ACCESS) //控制码测试 //安装进程监控 void C驱动用户层访问Dlg::OnBnClickedBtnInstapromon() { //打开设备,获取设备句柄 g_sysHandle = CreateFileW(符号链接名字, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); DWORD dwRetSize = 0; BOOL br = DeviceIoControl(g_sysHandle,//CreateFileW 打开驱动设备 返回的句柄 IO_进程监控安装,//控制码 CTL_CODE NULL, //输入缓冲区指针 驱动中在irp中的 IRP_MJ_DEVICE_CONTROL中处理放入缓冲区的数据 NULL, //输入缓冲区大小,直接写100也可以 NULL,//返回缓冲区的地址 256, //返回缓冲区的大小 &dwRetSize, //返回字节数 NULL); //返回值 TRACE("jw:IO_进程监控安装 = %X \r\n", IO_进程监控安装);// //另一种方式打印数据 char buf[1024] = { 0 }; sprintf_s(buf, "jw:IO_进程监控安装 =%X \r\n", IO_进程监控安装); OutputDebugStringA(buf);//用调试输出 } //移除进程监控 void C驱动用户层访问Dlg::OnBnClickedBtnUnloadpromon2() { //打开设备,获取设备句柄 g_sysHandle = CreateFileW(符号链接名字, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //传递字符串到设备。 DWORD dwRetSize = 0; BOOL br = DeviceIoControl(g_sysHandle,//CreateFileW 打开驱动设备 返回的句柄 IO_进程监控卸载,//控制码 CTL_CODE NULL, //输入缓冲区指针 驱动中在irp中的 IRP_MJ_DEVICE_CONTROL中处理放入缓冲区的数据 NULL, //输入缓冲区大小,直接写100也可以 NULL,//返回缓冲区的地址 256, //返回缓冲区的大小 &dwRetSize, //返回字节数 NULL); //返回值 TRACE("jw:IO_进程监控卸载 = %X \r\n", IO_进程监控卸载);// //另一种方式打印数据 char buf[1024] = { 0 }; sprintf_s(buf, "jw:IO_进程监控卸载 =%X ", IO_进程监控卸载); OutputDebugStringA(buf);//用调试输出 }
浙公网安备 33010602011771号