使用GetUmsSystemThreadInformation枚举UMS调度线程异常求助
使用GetUmsSystemThreadInformation枚举UMS调度线程的问题修复
问题根源分析
- 结构体初始化错误:
UMS_SYSTEM_THREAD_INFORMATION的IsUmsSchedulerThread和IsUmsWorkerThread是输出参数,不应提前赋值,否则会覆盖系统返回的真实标识,导致无法正确识别UMS线程。 - 错误码检查逻辑错误:
GetUmsSystemThreadInformation返回TRUE时,GetLastError()的值未定义,仅当函数返回FALSE时才需要调用该API获取错误原因。 - 缺少UMS线程过滤逻辑:原代码未根据返回的UMS标识筛选线程,导致所有可打开的线程都被输出。
修正后的枚举线程代码
#include <windows.h> #include <tlhelp32.h> #include <iostream> #include "UMSEnum.h" void EnumerateThreads(DWORD tid) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { std::cerr << "[-] 创建快照失败: " << GetLastError() << std::endl; return; } THREADENTRY32 threadEntry; threadEntry.dwSize = sizeof(THREADENTRY32); if (Thread32First(hSnapshot, &threadEntry)) { do { if (threadEntry.th32ThreadID != tid && tid != 0) continue; HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadEntry.th32ThreadID); if (hThread != NULL) { UMS_SYSTEM_THREAD_INFORMATION tInfo = {0}; // 初始化所有成员为0 tInfo.UmsVersion = UMS_VERSION; // 仅设置版本号,其余由系统填充 BOOL result = GetUmsSystemThreadInformation(hThread, &tInfo); if (result) { // 仅输出UMS调度线程或工作线程 if (tInfo.IsUmsSchedulerThread || tInfo.IsUmsWorkerThread) { std::cout << "[.] " << threadEntry.th32OwnerProcessID << "[" << threadEntry.th32ThreadID << "]" << "[调度线程: " << (tInfo.IsUmsSchedulerThread ? "是" : "否") << "]" << "[工作线程: " << (tInfo.IsUmsWorkerThread ? "是" : "否") << "]" << "[UMS标志: " << tInfo.ThreadUmsFlags << "]" << std::endl; } } else { DWORD err = GetLastError(); // ERROR_NOT_SUPPORTED表示该线程不是UMS线程,无需报错 if (err != ERROR_NOT_SUPPORTED) { std::cerr << "[-] GetUmsSystemThreadInformation失败 - " << threadEntry.th32ThreadID << " - 错误码: " << err << std::endl; } } CloseHandle(hThread); } } while (Thread32Next(hSnapshot, &threadEntry)); } else { std::cerr << "[-] 获取线程信息失败: " << GetLastError() << std::endl; } CloseHandle(hSnapshot); } int main(int argc, char** argv) { EnumerateThreads(argc > 1 ? atol(argv[1]) : 0); return 0; }
关键修改点说明
- 结构体初始化:用
{0}清空结构体所有成员,仅手动设置UmsVersion,确保系统能正确填充UMS线程标识。 - 错误码处理:仅在函数返回
FALSE时获取错误码,且忽略ERROR_NOT_SUPPORTED(非UMS线程会返回此错误),避免无效报错。 - 线程过滤:添加判断逻辑,仅输出
IsUmsSchedulerThread或IsUmsWorkerThread为真的线程。 - 参数兼容:优化
main函数,支持无参数时枚举所有线程。
测试验证
运行你的UMS调度线程测试程序后,启动修正后的枚举程序,将仅输出对应的UMS调度线程信息。
内容的提问来源于stack exchange,提问作者bananabr
相关产品推荐
相关产品推荐

