在用户态设置线程优先级会受到所属进程优先级的限制,难以实现真正的高优先级,可以通过驱动突破该限制.
流程图如下:
用户态程序:
驱动:
先来看用户态代码,主要是向内核发送带有控制信息的结构体
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
中实现主要功能逻辑
- 驱动入口函数
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
效果展示:
注册开启驱动
找一个目标线程,这里是7800,现在优先级为8
成功修改,现在优先级为9