使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

使用驱动突破对线程优先级修改的限制

    在用户态设置线程优先级会受到所属进程优先级的限制,难以实现真正的高优先级,可以通过驱动突破该限制.

流程图如下:

用户态程序:
图片[1]-使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

驱动:

图片[2]-使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

先来看用户态代码,主要是向内核发送带有控制信息的结构体

1.程序入口和参数处理

int main(int argc, const char* argv[]) {
    // 检查参数数量
    if (argc < 3) {
        printf("Usage: Booster <threadid> <priority>\\\\n");
        return 0;
    }

    // 解析命令行参数
    ThreadData data;
    data.ThreadId = atoi(argv[1]); // 线程ID
    data.Priority = atoi(argv[2]); // 优先级
}
  • 接受两个命令行参数
  • 第一个参数:目标线程ID
  • 第二个参数:新的线程优先级

2.打开设备句柄

HANDLE hDevice = CreateFile(
    L"\\\\\\\\.\\\\PriorityBooster",  // 设备路径
    GENERIC_WRITE,              
    FILE_SHARE_WRITE,           
    nullptr,                   
    OPEN_EXISTING,              
    0,                          
    nullptr                     
);

关键步骤:

  • 打开自定义设备驱动
  • 建立用户态与内核态通信

3.发送设备控制请求

DWORD returned;
BOOL success = DeviceIoControl(
    hDevice,                                // 设备句柄
    IOCTL_PRIORITY_BOOSTER_SET_PRIORITY,    // 控制码
    &data, sizeof(data),                    
    nullptr, 0,                             
    &returned,                             
    nullptr                                 
);

通信流程:

  • 发送线程优先级修改请求
  • 传递线程ID和新优先级
  • 检查请求处理结果

IOCTL_PRIORITY_BOOSTER_SET_PRIORITY以及ThreadData的定义在头文件中,如下

#pragma once

#define PRIORITY_BOOSTER_DEVICE 0x8000
#define IOCTL_PRIORITY_BOOSTER_SET_PRIORITY CTL_CODE(PRIORITY_BOOSTER_DEVICE, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)

struct ThreadData {
	ULONG ThreadId;//线程id
	int Priority;//优先值
};

来看驱动代码,主要是PriorityBoosterDeviceControl中实现主要功能逻辑

  1. 驱动入口函数 DriverEntry
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
    // 注册驱动卸载函数
    DriverObject->DriverUnload = PriorityBoosterUnload;

    // 设置IRP处理函数
    DriverObject->MajorFunction[IRP_MJ_CREATE] = PriorityBoosterCreateClose;//空函数
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = PriorityBoosterCreateClose;//空函数
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PriorityBoosterDeviceControl;
}

关键步骤:

  • 设置不同IRP请求的处理函数,PriorityBoosterDeviceControl为核心函数

直接来看PriorityBoosterDeviceControl

NTSTATUS PriorityBoosterDeviceControl(PDEVICE_OBJECT, PIRP Irp) {
    auto stack = IoGetCurrentIrpStackLocation(Irp);
    auto status = STATUS_SUCCESS;

    case IOCTL_PRIORITY_BOOSTER_SET_PRIORITY: {
	auto len = stack->Parameters.DeviceIoControl.InputBufferLength;
	if (len < sizeof(ThreadData)) {
		status = STATUS_BUFFER_TOO_SMALL;//检查缓冲区大小
		break;
	}

	auto data = (ThreadData*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
	if (data == nullptr) {
		status = STATUS_INVALID_PARAMETER;//检查栈指针有效性
		break;
	}
	if (data->Priority < 1 || data->Priority > 31) {
		status = STATUS_INVALID_PARAMETER;//检查优先级参数合法性(0~31)
		break;
	}

	PETHREAD Thread;
	status = PsLookupThreadByThreadId(ULongToHandle(data->ThreadId), &Thread);//修改线程优先级
	if (!NT_SUCCESS(status))
		break;

	KeSetPriorityThread((PKTHREAD)Thread, data->Priority);
	ObDereferenceObject(Thread);
	KdPrint(("Thread Priority change for %d to %d succeeded!\\n", data->ThreadId, data->Priority));
	break;
}
default:
	status = STATUS_INVALID_DEVICE_REQUEST;
	break;
}
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

完整代码参考:https://blog.csdn.net/jiaodou2/article/details/126980272

使用示例:

# 修改线程ID为1234的线程优先级为15
Booster.exe 1234 15

效果展示:

注册开启驱动

图片[3]-使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

找一个目标线程,这里是7800,现在优先级为8

图片[4]-使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

成功修改,现在优先级为9

图片[5]-使用驱动突破对线程优先级修改的限制-C/C++编程社区论坛-技术社区-学技术网

 

 

 

 

请登录后发表评论